← pstackCONTENT HISTORY

Update to pstack

Snapshot Sep 30, 2026 · 23:14 UTC · version 0.2.0

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Design types, interfaces, module boundaries, data flow, and ownership before implementation. Use for 'architect this', 'design this', API or domain modeling, refactors, new subsystems, or non-trivial changes where choosing the wrong shape would make the implementation harder.",
  "included_files": [],
  "name": "architect",
  "skill_md_contents": "---\nname: architect\ndescription: \"Design types, interfaces, module boundaries, data flow, and ownership before implementation. Use for 'architect this', 'design this', API or domain modeling, refactors, new subsystems, or non-trivial changes where choosing the wrong shape would make the implementation harder.\"\n---\n\n# Architect\n\nDesign the shape before writing the implementation.\n\nWork out the types, ownership, interfaces, module boundaries, and data flow first. The design should make the implementation more obvious, not move complexity into vague abstractions.\n\nUse this skill for:\n\n* new subsystems\n* non-trivial features\n* API design\n* domain modeling\n* refactors that change ownership\n* service boundaries\n* persistence boundaries\n* event-driven flows\n* changes where several reasonable designs exist\n* code that keeps fighting its current architecture\n\nFor a small mechanical change with an obvious shape, skip this skill.\n\n## Understand the existing system first\n\nDo not design around a codebase you have not understood.\n\nUse the `how` skill on the parts the change touches.\n\nWork out:\n\n* what owns the current behavior\n* where state lives\n* what the runtime flow is\n* which boundaries already exist\n* what callers depend on\n* which invariants the current code enforces\n\nIf the new design changes an existing boundary, ownership rule, or strange-looking constraint, use `why` before removing it.\n\nThe current design may be accidental. It may also encode a constraint that is invisible in the code.\n\nTreat verified history as a design input.\n\nFor greenfield work, skip the existing-system investigation and start from the requirements.\n\n## Start with usage\n\nDesign from the caller inward.\n\nWrite the important usage before defining the internals.\n\nFor example:\n\n```text\nsession = parking.open_session(entry)\n\npayment = session.pay(method)\n\ndecision = session.request_exit(exit_event)\n```\n\nThe exact syntax does not matter yet.\n\nThe point is to see what the caller needs to know.\n\nIf normal usage requires the caller to understand several internal steps, internal state transitions, or storage details, the design is probably exposing too much.\n\nAsk:\n\n* What should the caller provide?\n* What should the caller receive?\n* What should stay hidden?\n* Which invalid operations should be impossible or difficult to express?\n\nUse the answers to shape the API.\n\n## Model the domain\n\nName the real concepts in the problem.\n\nDo not create types just because the existing code has classes with those names.\n\nLook for:\n\n* entities with identity\n* values with rules\n* state transitions\n* commands\n* events\n* policies\n* external systems\n* ownership boundaries\n\nGive each rule one clear owner.\n\nIf two modules both decide whether the same operation is valid, ownership is unclear.\n\nPrefer types that prevent invalid states instead of objects full of optional fields plus comments explaining which combinations are legal.\n\nUse the `principle-model-the-domain` and `principle-type-system-discipline` skills when they apply.\n\n## Decide where the boundaries are\n\nA useful module owns something.\n\nIt may own:\n\n* a business rule\n* a state transition\n* persistence\n* communication with an external system\n* a protocol\n* a set of invariants\n\nA module that only forwards arguments to another module probably does not justify the extra layer.\n\nKeep framework, transport, and persistence details at their boundaries when possible.\n\nThe domain should not need to know that a request arrived through HTTP or that an entity happens to be stored in SQLite unless those facts are part of the domain.\n\nUse `principle-boundary-discipline` when deciding where parsing, validation, and external representations stop.\n\n## Sketch the design\n\nFor a small change, sketch:\n\n* the important types\n* their fields\n* function or method signatures\n* ownership\n* the main data flow\n\nFor a larger change, also sketch:\n\n* module boundaries\n* dependencies between modules\n* persistence ownership\n* external integrations\n* events or messages\n* failure paths\n\nUse pseudocode or incomplete declarations.\n\nDo not fill in implementation details yet.\n\nA sketch should expose the decisions without burying them under working code.\n\n## Design more than one shape when the decision matters\n\nFor a meaningful architectural choice, produce at least two structurally different designs before choosing one.\n\nChanging a method name does not count as another design.\n\nThe alternatives should disagree about something real, such as:\n\n* which component owns state\n* synchronous calls versus events\n* one service versus separate responsibilities\n* where validation occurs\n* whether a concept is stored or derived\n* whether callers coordinate several operations or call one higher-level operation\n\nDo not create alternatives just to reach a quota. Use this when there is a real design choice.\n\nApply `principle-exhaust-the-design-space`.\n\n## Compare the designs\n\nJudge each design by what the caller must understand and what the system can enforce.\n\nPrefer the design that:\n\n* gives each rule one owner\n* hides implementation details\n* keeps dependencies pointed toward the domain\n* makes invalid states harder to represent\n* keeps common operations short\n* isolates external systems\n* makes important behavior testable\n* handles concurrency without casual shared mutation\n* has fewer special cases\n\nDo not choose the design with the most layers.\n\nDo not choose the most abstract design.\n\nA good abstraction removes knowledge from its callers.\n\nIf an abstraction adds concepts without hiding anything, remove it.\n\nApply `principle-subtract-before-you-add`.\n\n## Check the design against real scenarios\n\nWalk real cases through the proposed API.\n\nUse the common path first.\n\nThen test the cases that are likely to expose a bad shape.\n\nExamples include:\n\n* duplicate requests\n* retries\n* partial failure\n* stale state\n* concurrent operations\n* missing data\n* an operation arriving in the wrong order\n* an external dependency being unavailable\n* a new domain variant\n\nDo not solve every hypothetical edge case.\n\nUse cases that come from the requirements, current code, bugs, or realistic behavior of the system.\n\nIf an ordinary scenario needs a workaround, the design needs another pass.\n\n## Check the dependency direction\n\nFor each module, ask what it knows about.\n\nDomain code should usually know domain concepts.\n\nAdapters may know the domain and an external system.\n\nThe domain should not depend on an adapter merely because the adapter currently provides the data.\n\nLook for dependencies that force business logic to know about:\n\n* HTTP\n* database rows\n* JSON payloads\n* UI components\n* vendor SDKs\n* queue-specific message formats\n\nMove those translations to the boundary when possible.\n\n## Write the decision down\n\nFor the chosen design, show:\n\n### Usage\n\nHow the main caller uses it.\n\n### Types\n\nThe important domain types and states.\n\n### Interfaces\n\nThe functions or methods that form the contract.\n\n### Ownership\n\nWhich component owns each important rule or state transition.\n\n### Module map\n\nWhere the pieces live and which direction dependencies point.\n\n### Flow\n\nWhat happens through the system for the main case.\n\n### Alternatives\n\nThe meaningful designs considered and why they lost.\n\n### Risks\n\nThe assumptions most likely to prove the design wrong.\n\nKeep this proportional to the task. A three-function refactor does not need an architecture document.\n\n## Separate design from implementation\n\nIf the user asked only for architecture, stop at the design.\n\nIf they also asked for implementation, treat the chosen sketch as the starting contract.\n\nDo not silently change the architecture halfway through coding because a local implementation choice is easier.\n\nWhen implementation needs something the sketch did not anticipate, treat that as evidence.\n\nAsk what changed:\n\n* Was a requirement missed?\n* Was the domain model wrong?\n* Is ownership in the wrong place?\n* Is the implementation leaking a detail that should stay hidden?\n\nSmall corrections are normal.\n\nRepeated corrections of the same kind are not.\n\n## Know when to throw the design away\n\nDo not keep patching a bad design because work has already gone into it.\n\nWarning signs include:\n\n* the same workaround appearing in several places\n* unrelated edge cases all needing special branches\n* types needing repeated casts or escape hatches\n* optional fields that are actually required in certain hidden states\n* callers needing to know internal sequencing rules\n* several modules enforcing the same invariant\n* locks appearing because ownership was never made clear\n* repeated changes to the contract during implementation\n\nOne awkward case does not prove the architecture is wrong.\n\nLook for a pattern.\n\nIf the pattern is real, go back to the requirements and the lessons from implementation. Redesign as if those facts had been known from the start.\n\nApply `principle-redesign-from-first-principles` and `principle-fix-root-causes`.\n\nDo not preserve the old shape merely because it already exists.\n\n## Evidence\n\nWhen designing against an existing project, tie claims about the current system to source you inspected.\n\nDo not claim a constraint exists because the code looks like it might.\n\nUse `how` for current behavior.\n\nUse `why` for historical intent.\n\nKeep requirements, verified constraints, and your own design judgment distinct.\n\n## Writing\n\nApply `unslop` to the answer.\n\nUse concrete domain names.\n\nDo not hide a weak design behind architecture vocabulary.\n\nShow the caller's usage early. Then show the types and ownership that make that usage possible.\n\nThe reply should contain the design itself, not a description of the design process.\n"
}

SHA-256 of public snapshot: 26aefce4f3c20658fb1f29fefc80ff5304c93b556615620463d99993da0c15da