@bastani/atomic 0.8.20-0 → 0.8.21-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/builtin/intercom/package.json +1 -1
  3. package/dist/builtin/mcp/CHANGELOG.md +5 -0
  4. package/dist/builtin/mcp/package.json +1 -1
  5. package/dist/builtin/subagents/CHANGELOG.md +5 -0
  6. package/dist/builtin/subagents/agents/code-simplifier.md +78 -22
  7. package/dist/builtin/subagents/agents/debugger.md +4 -3
  8. package/dist/builtin/subagents/package.json +1 -1
  9. package/dist/builtin/web-access/CHANGELOG.md +5 -0
  10. package/dist/builtin/web-access/package.json +1 -1
  11. package/dist/builtin/workflows/CHANGELOG.md +25 -0
  12. package/dist/builtin/workflows/package.json +1 -1
  13. package/dist/builtin/workflows/skills/create-spec/SKILL.md +169 -125
  14. package/dist/builtin/workflows/skills/impeccable/SKILL.md +89 -80
  15. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_asset_producer.toml +92 -0
  16. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_manual_edit_applier.toml +95 -0
  17. package/dist/builtin/workflows/skills/impeccable/agents/openai.yaml +4 -0
  18. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +122 -1
  19. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +38 -12
  20. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +5 -5
  21. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +7 -7
  22. package/dist/builtin/workflows/skills/impeccable/reference/brand.md +4 -14
  23. package/dist/builtin/workflows/skills/impeccable/reference/clarify.md +115 -1
  24. package/dist/builtin/workflows/skills/impeccable/reference/codex.md +3 -3
  25. package/dist/builtin/workflows/skills/impeccable/reference/colorize.md +109 -6
  26. package/dist/builtin/workflows/skills/impeccable/reference/craft.md +7 -7
  27. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +623 -94
  28. package/dist/builtin/workflows/skills/impeccable/reference/delight.md +2 -2
  29. package/dist/builtin/workflows/skills/impeccable/reference/distill.md +2 -2
  30. package/dist/builtin/workflows/skills/impeccable/reference/document.md +16 -14
  31. package/dist/builtin/workflows/skills/impeccable/reference/extract.md +1 -1
  32. package/dist/builtin/workflows/skills/impeccable/reference/harden.md +1 -1
  33. package/dist/builtin/workflows/skills/impeccable/reference/init.md +172 -0
  34. package/dist/builtin/workflows/skills/impeccable/reference/interaction-design.md +0 -6
  35. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +33 -13
  36. package/dist/builtin/workflows/skills/impeccable/reference/live.md +96 -19
  37. package/dist/builtin/workflows/skills/impeccable/reference/onboard.md +1 -1
  38. package/dist/builtin/workflows/skills/impeccable/reference/optimize.md +1 -1
  39. package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +1 -1
  40. package/dist/builtin/workflows/skills/impeccable/reference/polish.md +3 -4
  41. package/dist/builtin/workflows/skills/impeccable/reference/product.md +1 -3
  42. package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +2 -2
  43. package/dist/builtin/workflows/skills/impeccable/reference/shape.md +5 -5
  44. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +158 -3
  45. package/dist/builtin/workflows/skills/impeccable/scripts/cleanup-deprecated.mjs +1 -1
  46. package/dist/builtin/workflows/skills/impeccable/scripts/command-metadata.json +2 -2
  47. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +225 -0
  48. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +266 -0
  49. package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +17 -1
  50. package/dist/builtin/workflows/skills/impeccable/scripts/design-parser.mjs +16 -1
  51. package/dist/builtin/workflows/skills/impeccable/scripts/detect.mjs +21 -0
  52. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1725 -0
  53. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +244 -0
  54. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +4543 -0
  55. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns.mjs +43 -0
  56. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +252 -0
  57. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +535 -0
  58. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +986 -0
  59. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +208 -0
  60. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +189 -0
  61. package/dist/builtin/workflows/skills/impeccable/scripts/detector/findings.mjs +12 -0
  62. package/dist/builtin/workflows/skills/impeccable/scripts/detector/node/file-system.mjs +198 -0
  63. package/dist/builtin/workflows/skills/impeccable/scripts/detector/profile/profiler.mjs +166 -0
  64. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +419 -0
  65. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +2316 -0
  66. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/color.mjs +124 -0
  67. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/constants.mjs +101 -0
  68. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +7 -0
  69. package/dist/builtin/workflows/skills/impeccable/scripts/impeccable-paths.mjs +17 -1
  70. package/dist/builtin/workflows/skills/impeccable/scripts/is-generated.mjs +2 -2
  71. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +139 -96
  72. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +4491 -526
  73. package/dist/builtin/workflows/skills/impeccable/scripts/live-commit-manual-edits.mjs +1241 -0
  74. package/dist/builtin/workflows/skills/impeccable/scripts/live-copy-edit-agent.mjs +683 -0
  75. package/dist/builtin/workflows/skills/impeccable/scripts/live-discard-manual-edits.mjs +51 -0
  76. package/dist/builtin/workflows/skills/impeccable/scripts/live-event-validation.mjs +136 -0
  77. package/dist/builtin/workflows/skills/impeccable/scripts/live-inject.mjs +22 -9
  78. package/dist/builtin/workflows/skills/impeccable/scripts/live-insert-ui.mjs +458 -0
  79. package/dist/builtin/workflows/skills/impeccable/scripts/live-insert.mjs +232 -0
  80. package/dist/builtin/workflows/skills/impeccable/scripts/live-manual-edit-evidence.mjs +363 -0
  81. package/dist/builtin/workflows/skills/impeccable/scripts/live-manual-edits-buffer.mjs +152 -0
  82. package/dist/builtin/workflows/skills/impeccable/scripts/live-poll.mjs +288 -110
  83. package/dist/builtin/workflows/skills/impeccable/scripts/live-resume.mjs +47 -1
  84. package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +1443 -100
  85. package/dist/builtin/workflows/skills/impeccable/scripts/live-session-store.mjs +17 -0
  86. package/dist/builtin/workflows/skills/impeccable/scripts/live-status.mjs +17 -3
  87. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +216 -6
  88. package/dist/builtin/workflows/skills/impeccable/scripts/live.mjs +2 -3
  89. package/dist/builtin/workflows/skills/impeccable/scripts/palette.mjs +633 -0
  90. package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +1 -1
  91. package/dist/builtin/workflows/src/extension/index.ts +67 -3
  92. package/dist/builtin/workflows/src/extension/render-result.ts +26 -1
  93. package/dist/builtin/workflows/src/runs/foreground/executor.ts +227 -3
  94. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +94 -7
  95. package/dist/builtin/workflows/src/shared/stage-prompt.ts +326 -0
  96. package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +62 -7
  97. package/dist/builtin/workflows/src/shared/store-types.ts +43 -0
  98. package/dist/builtin/workflows/src/shared/store.ts +37 -0
  99. package/dist/builtin/workflows/src/tui/chat-surface-message.ts +22 -4
  100. package/dist/builtin/workflows/src/tui/graph-view.ts +47 -0
  101. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +43 -1
  102. package/dist/builtin/workflows/src/tui/run-detail.ts +10 -4
  103. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +117 -15
  104. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +9 -0
  105. package/dist/core/skills.d.ts.map +1 -1
  106. package/dist/core/skills.js +2 -5
  107. package/dist/core/skills.js.map +1 -1
  108. package/dist/core/system-prompt.d.ts.map +1 -1
  109. package/dist/core/system-prompt.js +11 -29
  110. package/dist/core/system-prompt.js.map +1 -1
  111. package/dist/index.d.ts +1 -0
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +3 -0
  114. package/dist/index.js.map +1 -1
  115. package/docs/quickstart.md +1 -2
  116. package/package.json +4 -4
  117. package/dist/builtin/workflows/skills/impeccable/reference/cognitive-load.md +0 -106
  118. package/dist/builtin/workflows/skills/impeccable/reference/color-and-contrast.md +0 -105
  119. package/dist/builtin/workflows/skills/impeccable/reference/heuristics-scoring.md +0 -234
  120. package/dist/builtin/workflows/skills/impeccable/reference/motion-design.md +0 -109
  121. package/dist/builtin/workflows/skills/impeccable/reference/personas.md +0 -179
  122. package/dist/builtin/workflows/skills/impeccable/reference/responsive-design.md +0 -114
  123. package/dist/builtin/workflows/skills/impeccable/reference/spatial-design.md +0 -100
  124. package/dist/builtin/workflows/skills/impeccable/reference/teach.md +0 -156
  125. package/dist/builtin/workflows/skills/impeccable/reference/typography.md +0 -159
  126. package/dist/builtin/workflows/skills/impeccable/reference/ux-writing.md +0 -107
  127. package/dist/builtin/workflows/skills/impeccable/scripts/load-context.mjs +0 -141
@@ -1,20 +1,61 @@
1
1
  ---
2
2
  name: create-spec
3
- description: Create a detailed execution plan/spec/prd for implementing features or refactors in a codebase by leveraging existing research in the codebase.
3
+ description: "Create a detailed execution plan/spec/PRD for implementing features or refactors in a codebase, designed around the program's entrypoints, the doors that carry domain intent, by leveraging existing research in the codebase."
4
4
  ---
5
5
 
6
6
  You are tasked with creating a spec for implementing a new feature or system change in the codebase by leveraging existing research in the **$ARGUMENTS** path. If no research path is specified, use the entire `research/` directory. IMPORTANT: Research documents are located in the `research/` directory — do NOT look in the `specs/` directory for research. Follow the template below to produce a comprehensive specification as output in the `specs/` folder using the findings from RELEVANT research documents found in `research/`. The spec file MUST be named using the format `YYYY-MM-DD-topic.md` (e.g., `specs/2026-03-26-my-feature.md`), where the date is the current date and the topic is a kebab-case summary. Tip: It's good practice to use the `codebase-research-locator` and `codebase-research-analyzer` agents to help you find and analyze the research documents in the `research/` directory. It is also HIGHLY recommended to cite relevant research throughout the spec for additional context.
7
7
 
8
+ ## Design philosophy: a spec is a theory of its doors
9
+
10
+ The entrypoints of a program, read together, are the program's **theory of its own purpose**. Everything inside the boundary is mechanism — the *how*. Only at the boundary does the code speak in terms of meaning — the *what* and the *why*. So the single most important thing this spec defines is not the mechanism inside the system, but the **set of doors** the system keeps: the functions, routes, and RPC methods through which untrusted input arrives and irreversible effects happen.
11
+
12
+ Two acts hide inside that claim, and a good spec performs both. One is *finding* the doors — discovering where the domain is already jointed, using the research in `research/` to learn what actually matters in the world the software serves. The other is *crafting* them — naming and shaping each door so it tells the truth about what lies behind it. Treat entrypoint design as the spine of the spec: a reviewer should be able to read the door set alone and reconstruct what the system is *for* before reading a single implementation detail.
13
+
14
+ Apply the five principles below to every entrypoint the spec introduces or changes, and run the rubric on each.
15
+
16
+ ### The five principles
17
+
18
+ 1. **Name a joint, not a tool.** A domain has seams — places reality is already divided into meaningful units (*authenticate a user, settle a payment, revoke access, publish a draft*). These exist before your code does. Name each door after such a joint, never after the mechanism behind it (`run the query`, `call the service`, `update the row`). A door named for a tool lets a reader learn *how it works* without ever learning *what it is for* — an ontological mismatch no clean mechanism repairs. Listen to the domain (and to the research), not to the code.
19
+
20
+ 2. **Compress honestly, or not at all.** A door's value is roughly the ratio of mechanism hidden to surface exposed — *but only when the name promises exactly what the body delivers.* No less (so it hides no danger or incompleteness), no more (so it implies no guarantee it does not keep). A `save()` that sometimes silently doesn't, a `delete()` that soft-deletes, a `validate()` that mutates, a `getUser()` that creates one — each is a lie at the boundary, and lies at the boundary compound across every caller who reasons from the name. Encode cost and risk in the vocabulary (cheap-borrow vs allocate vs consume; `read` vs `read_exact`; panic-risk in the name).
21
+
22
+ 3. **Intent lives in what the door refuses.** A boundary communicates as much by what it forbids as by what it allows. The *shape* of the door set — what it makes easy, what it makes impossible — is a direct statement of what the designers held sacred. Prefer making the illegal **unrepresentable** (in types and structure) over merely *checked* at runtime: a door that checks a rule trusts the caller; a door that makes the rule structurally necessary need trust no one. Use newtypes (`AccountId`, `OrderId`) over primitives, sum types over independent booleans, and capability-carrying types (an `AdminSession`, an `AuthorizedCharge`) that can only be produced by the door that earns them.
23
+
24
+ 4. **Write for the stranger across time.** You craft the door not for the machine but for a competent stranger who arrives years from now, never meets you, and must understand the system's purpose before they dare change it. The governing test: **could they reconstruct the purpose of the system from the entrypoints alone, without reading a single body?** If they would have to read implementations to learn what the system *means*, intent has leaked out of the doors into the mechanism.
25
+
26
+ 5. **Keep the dangerous doors few and honest.** The maturity of a system is visible in how few doors guard its irreversible effects — and how truthfully those doors are named. Every place money moves, access is granted, data is destroyed, a key is minted, a message is broadcast: funnel each effect through **one honestly-named chokepoint**, so the promise that guards it has exactly one home. Scatter danger across many small unnamed paths (every handler that can `chargeCard`, broad DB grants reaching `DROP TABLE`, ad-hoc `os.system(...)`, default-public storage) and no one — not even the authors — can say where the weight is carried.
27
+
28
+ ### The rubric you run on every entrypoint in the spec
29
+
30
+ For each non-trivial entrypoint the spec introduces or changes, walk these in order. Stop at the first one you cannot answer cleanly — that is a finding, and it belongs in the spec (often in §5 as a constraint, or in §9 as an open question). Run it **forward** to audit a door you've drafted, and **backward** — asking what door each obligation deserves — to find the doors the system is still missing.
31
+
32
+ 1. **Joint, not tool.** Is the name a unit of domain intent a non-engineer would recognize — not a description of the mechanism? If you can only name it in implementation terms, it's a step, not a door.
33
+ 2. **The sentence holds.** Can you state its guarantee in one declarative sentence with no *and*? If not, it's fused (split it) or undefined (the most dangerous case — stop and find out what it actually promises).
34
+ 3. **The name is honest.** Does it promise exactly what the body will deliver — hiding no danger, implying no guarantee it won't keep? List the ways the name could be read as a lie.
35
+ 4. **Obligations are discharged.** Read the pre / invariant / post / *never* off the sentence. Does each obligation map to a real step in the design, and each step to an obligation?
36
+ 5. **Every exit keeps the promise.** Walk the error return, the retry, the timeout, the partial write, the concurrent caller, the second entry. The guarantee must survive all of them, not just the happy path.
37
+ 6. **The refusals are real.** What does this door make impossible? Are the illegal states unrepresentable, or merely checked and trusted?
38
+ 7. **The trust transition is explicit and singular.** If untrusted becomes trusted or authority increases, does it happen here — and only here?
39
+ 8. **Irreversible effects pass one chokepoint.** Is this the single dominating door for the effect it guards? If the effect can be reached another way, that other way is the bug.
40
+ 9. **The airlock is at the boundary.** Validation, authorization, conversion, and the error boundary live at the door, leaving the inside free to trust its own invariants. Defensive code deep within means the boundary is misplaced.
41
+ 10. **A stranger could reconstruct intent.** Could someone read this door alone — name and signature, not the body — and know what it is for and what it owes?
42
+
43
+ ### The joint is the same at every boundary
44
+
45
+ `settle_payment` in process, `POST /v1/payment_intents/{id}/capture` over REST, and `Billing.SettlePayment` over gRPC are **one door, three transports, one name**. When the function, the route, and the RPC method disagree about what the joints are, at least one of them is naming a tool — flag it. On the wire, the HTTP verb is honesty the protocol gives you for free (`GET` is *safe*, `PUT`/`DELETE` are *idempotent*, `POST` is neither — which is exactly why money doors carry an `Idempotency-Key`), and the status code is the door's honest exit (`201` created, `204` done, `202` accepted; `409`/`412` are real refusals). The cardinal lie is `200 OK` wrapping `{"error": ...}`. Authentication is one gate at the edge so every handler behind it may trust it speaks to a known caller.
46
+
8
47
  <EXTREMELY_IMPORTANT>
9
48
 
10
- - Please use your AskUserQuestion tool to provide a rich interface to ask the user for their input on a question.
49
+ - Please use your ask_user_question tool to provide a rich interface to ask the user for their input on a question.
11
50
  - Please DO NOT implement anything in this stage, just create the comprehensive spec as described below.
12
51
  - When writing the spec, DO NOT include information about concrete dates/timelines (e.g. # minutes, hours, days, weeks, etc.) and favor explicit phases (e.g. Phase 1, Phase 2, etc.).
52
+ - The spec MUST treat its entrypoint set as a first-class artifact. Section 5 is built around the **doors** (typed signatures, named failures, refusals expressed in types) and must pass the rubric above. Do not let intent leak into mechanism: a reviewer should reconstruct the system's purpose from §4.4 and §5.1 alone.
13
53
  - Once the spec is generated ask questions one at a time OR in logical groups:
14
54
  - Refer to section "## 9. Open Questions / Unresolved Issues", go through each question one by one, and use **contrastive clarification** (presenting 2-3 specific options with concrete tradeoffs) rather than open-ended questions. This means presenting interpretations like "(A) Option X — tradeoff Y" and "(B) Option Z — tradeoff W" instead of asking "what do you think about X?". Update the spec with the user's answers as you walk through the questions.
15
- - Interview the user relentlessly about every aspect of this plan/spec until you reach a shared understanding with them. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer (i.e., **contrastive clarification**).
55
+ - Interview the user relentlessly about every aspect of this plan/spec until you reach a shared understanding with them. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer (i.e., **contrastive clarification**). Pay special attention to the **doors**: every disagreement about what a joint is, what a door promises, what it refuses, or where a dangerous effect is funneled is a question worth resolving with the user.
16
56
  - If a question can be answered by exploring the codebase, explore the codebase instead and confirm with the user that this is their inferred intent.
17
57
  - Finally, once the spec is generated and after open questions are answered, provide an executive summary of the spec to the user including the path to the generated spec document in the `specs/` directory.
58
+ - In the summary, list the door set by name alone (the stranger-across-time view) and call out which doors guard irreversible effects.
18
59
  - Encourage the user to review the spec for best results and provide feedback or ask any follow-up questions they may have.
19
60
 
20
61
  </EXTREMELY_IMPORTANT>
@@ -30,20 +71,21 @@ You are tasked with creating a spec for implementing a new feature or system cha
30
71
 
31
72
  ## 1. Executive Summary
32
73
 
33
- _Instruction: A "TL;DR" of the document. Assume the reader is a VP or an engineer from another team who has 2 minutes. Summarize the Context (Problem), the Solution (Proposal), and the Impact (Value). Keep it under 200 words._
74
+ _Instruction: A "TL;DR" of the document. Assume the reader is a VP or an engineer from another team who has 2 minutes. Summarize the Context (Problem), the Solution (Proposal), and the Impact (Value). Name the one or two **doors** at the heart of the change. Keep it under 200 words._
34
75
 
35
- > **Example:** This RFC proposes replacing our current nightly batch billing system with an event-driven architecture using Kafka and AWS Lambda. Currently, billing delays cause a 5% increase in customer support tickets. The proposed solution will enable real-time invoicing, reducing billing latency from 24 hours to <5 minutes.
76
+ > **Example:** This RFC proposes replacing our current nightly batch billing system with an event-driven architecture. Currently, billing delays cause a 5% increase in customer support tickets. The proposed solution introduces two money doors — `authorize_charge` (reversible hold) and `settle_payment` (irreversible capture) — as the single chokepoint for outbound money, reducing billing latency from 24 hours to <5 minutes while making double-charges structurally impossible.
36
77
 
37
78
  ## 2. Context and Motivation
38
79
 
39
- _Instruction: Why are we doing this? Why now? Link to the Product Requirement Document (PRD)._
80
+ _Instruction: Why are we doing this? Why now? Link to the Product Requirement Document (PRD) and cite the relevant `research/` documents._
40
81
 
41
82
  ### 2.1 Current State
42
83
 
43
- _Instruction: Describe the existing architecture. Use a "Context Diagram" if possible. Be honest about the flaws._
84
+ _Instruction: Describe the existing architecture. Use a "Context Diagram" if possible. Be honest about the flaws — including which existing doors **leak** (named for tools, dishonest compression, scattered danger)._
44
85
 
45
86
  - **Architecture:** Currently, Service A communicates with Service B via a shared SQL database.
46
87
  - **Limitations:** This creates a tight coupling; when Service A locks the table, Service B times out.
88
+ - **Leaking doors (today):** e.g. `chargeCard(token, cents)` is reachable from checkout, the retry job, *and* the admin panel — no one owns "charge exactly once." `processPayment(...) -> bool` collapses a declined card, a network failure, and a duplicate submission into the same `false`.
47
89
 
48
90
  ### 2.2 The Problem
49
91
 
@@ -51,11 +93,11 @@ _Instruction: What is the specific pain point?_
51
93
 
52
94
  - **User Impact:** Customers cannot download receipts during the nightly batch window.
53
95
  - **Business Impact:** We are losing $X/month in churn due to billing errors.
54
- - **Technical Debt:** The current codebase is untestable and has 0% unit test coverage.
96
+ - **Technical Debt:** Danger is scattered; the boundary is misplaced, with defensive code deep inside the core instead of at the door.
55
97
 
56
98
  ## 3. Goals and Non-Goals
57
99
 
58
- _Instruction: This is the contract Definition of Success. Be precise._
100
+ _Instruction: This is the contract / Definition of Success. Be precise._
59
101
 
60
102
  ### 3.1 Functional Goals
61
103
 
@@ -64,11 +106,11 @@ _Instruction: This is the contract Definition of Success. Be precise._
64
106
 
65
107
  ### 3.2 Non-Goals (Out of Scope)
66
108
 
67
- _Instruction: Explicitly state what you are NOT doing. This prevents scope creep._
109
+ _Instruction: Explicitly state what you are NOT doing. Remember: **intent lives in what the door refuses** — the doors you deliberately do not build are as much a statement of purpose as the ones you do. This prevents scope creep._
68
110
 
69
111
  - [ ] We will NOT support PDF export in this version (CSV only).
70
112
  - [ ] We will NOT migrate data older than 3 years.
71
- - [ ] We will NOT build a custom UI (API only).
113
+ - [ ] We will NOT expose a second path to move money; `settle_payment` remains the only chokepoint.
72
114
 
73
115
  ## 4. Proposed Solution (High-Level Design)
74
116
 
@@ -76,71 +118,38 @@ _Instruction: The "Big Picture." Diagrams are mandatory here._
76
118
 
77
119
  ### 4.1 System Architecture Diagram
78
120
 
79
- _Instruction: Insert a C4 System Context or Container diagram. Show the "Black Boxes."_
80
-
81
- - (Place Diagram Here - e.g., Mermaid diagram)
82
-
83
- For example,
121
+ _Instruction: Insert a C4 System Context or Container diagram. Show the "Black Boxes" and mark where the **airlock** sits (the single edge where untrusted network becomes a trusted request)._
84
122
 
85
123
  ```mermaid
86
- %%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#f8f9fa','primaryTextColor':'#2c3e50','primaryBorderColor':'#4a5568','lineColor':'#4a90e2','secondaryColor':'#ffffff','tertiaryColor':'#e9ecef','background':'#f5f7fa','mainBkg':'#f8f9fa','nodeBorder':'#4a5568','clusterBkg':'#ffffff','clusterBorder':'#cbd5e0','edgeLabelBackground':'#ffffff'}}}%%
87
-
124
+ %%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#f8f9fa','primaryTextColor':'#2c3e50','primaryBorderColor':'#4a5568','lineColor':'#4a90e2','secondaryColor':'#ffffff','tertiaryColor':'#e9ecef','clusterBkg':'#ffffff','clusterBorder':'#cbd5e0'}}}%%
88
125
  flowchart TB
89
- %% ---------------------------------------------------------
90
- %% CLEAN ENTERPRISE DESIGN
91
- %% Professional • Trustworthy • Corporate Standards
92
- %% ---------------------------------------------------------
93
-
94
- %% STYLE DEFINITIONS
95
- classDef person fill:#5a67d8,stroke:#4c51bf,stroke-width:3px,color:#ffffff,font-weight:600,font-size:14px
96
-
97
- classDef systemCore fill:#4a90e2,stroke:#357abd,stroke-width:2.5px,color:#ffffff,font-weight:600,font-size:14px
98
-
99
- classDef systemSupport fill:#667eea,stroke:#5a67d8,stroke-width:2.5px,color:#ffffff,font-weight:600,font-size:13px
100
-
101
- classDef database fill:#48bb78,stroke:#38a169,stroke-width:2.5px,color:#ffffff,font-weight:600,font-size:13px
102
-
103
- classDef external fill:#718096,stroke:#4a5568,stroke-width:2.5px,color:#ffffff,font-weight:600,font-size:13px,stroke-dasharray:6 3
104
-
105
- %% NODES - CLEAN ENTERPRISE HIERARCHY
106
-
107
- User(("◉<br><b>User</b><br>")):::person
108
-
109
- subgraph SystemBoundary["◆ Primary System Boundary"]
126
+ classDef person fill:#5a67d8,stroke:#4c51bf,stroke-width:3px,color:#fff,font-weight:600
127
+ classDef core fill:#4a90e2,stroke:#357abd,stroke-width:2.5px,color:#fff,font-weight:600
128
+ classDef support fill:#667eea,stroke:#5a67d8,stroke-width:2.5px,color:#fff,font-weight:600
129
+ classDef db fill:#48bb78,stroke:#38a169,stroke-width:2.5px,color:#fff,font-weight:600
130
+ classDef external fill:#718096,stroke:#4a5568,stroke-width:2.5px,color:#fff,font-weight:600,stroke-dasharray:6 3
131
+
132
+ User(("◉<br><b>User</b>")):::person
133
+ subgraph Boundary["◆ System Boundary — Airlock at the edge"]
110
134
  direction TB
111
-
112
- LoadBalancer{{"<b>Load Balancer</b><br>NGINX<br><i>Layer 7 Proxy</i>"}}:::systemCore
113
-
114
- API["<b>API Application</b><br>Go • Gin Framework<br><i>REST Endpoints</i>"]:::systemCore
115
-
116
- Worker(["<b>Background Worker</b><br>Go Runtime<br><i>Async Processing</i>"]):::systemSupport
117
-
118
- Cache[("◆<br><b>Cache Layer</b><br>Redis<br><i>In-Memory</i>")]:::database
119
-
120
- PrimaryDB[("●<br><b>Primary Database</b><br>PostgreSQL<br><i>Persistent Storage</i>")]:::database
135
+ Gateway{{"<b>API Gateway</b><br><i>auth · validate · authorize</i><br>the one trust transition"}}:::core
136
+ API["<b>Core Service</b><br><i>trusts its own invariants</i>"]:::core
137
+ Worker(["<b>Worker</b><br><i>async</i>"]):::support
138
+ DB[("●<br><b>Primary DB</b>")]:::db
121
139
  end
122
-
123
- ExternalAPI{{"<b>External API</b><br>Third Party<br><i>HTTP/REST</i>"}}:::external
124
-
125
- %% RELATIONSHIPS - CLEAN FLOW
126
-
127
- User -->|"1. HTTPS Request<br>TLS 1.3"| LoadBalancer
128
- LoadBalancer -->|"2. Proxy Pass<br>Round Robin"| API
129
-
130
- API <-->|"3. Cache<br>Read/Write"| Cache
131
- API -->|"4. Persist Data<br>Transactional"| PrimaryDB
132
- API -.->|"5. Enqueue Event<br>Async"| Worker
133
-
134
- Worker -->|"6. Process Job<br>Execution"| PrimaryDB
135
- Worker -.->|"7. HTTP Call<br>Webhooks"| ExternalAPI
136
-
137
- %% STYLE BOUNDARY
138
- style SystemBoundary fill:#ffffff,stroke:#cbd5e0,stroke-width:2px,color:#2d3748,stroke-dasharray:8 4,font-weight:600,font-size:12px
140
+ Ext{{"<b>Payment Provider</b>"}}:::external
141
+
142
+ User -->|"1. HTTPS (untrusted)"| Gateway
143
+ Gateway -->|"2. trusted request"| API
144
+ API -->|"3. persist (txn)"| DB
145
+ API -.->|"4. enqueue"| Worker
146
+ Worker -.->|"5. settle (irreversible)"| Ext
147
+ style Boundary fill:#fff,stroke:#cbd5e0,stroke-width:2px,stroke-dasharray:8 4
139
148
  ```
140
149
 
141
150
  ### 4.2 Architectural Pattern
142
151
 
143
- _Instruction: Name the pattern (e.g., "Event Sourcing", "BFF - Backend for Frontend")._
152
+ _Instruction: Name the pattern (e.g., "Event Sourcing", "BFF Backend for Frontend", "Publisher-Subscriber")._
144
153
 
145
154
  - We are adopting a Publisher-Subscriber pattern where the Order Service publishes `OrderCreated` events, and the Billing Service consumes them asynchronously.
146
155
 
@@ -152,96 +161,131 @@ _Instruction: Name the pattern (e.g., "Event Sourcing", "BFF - Backend for Front
152
161
  | Event Bus | Decouples services | Kafka | Durable log, replay capability. |
153
162
  | Projections DB | Read-optimized views | MongoDB | Flexible schema for diverse receipt formats. |
154
163
 
155
- ## 5. Detailed Design
164
+ ### 4.4 The Door Set at a Glance (Stranger-Across-Time View)
165
+
166
+ _Instruction: List the entrypoint **names alone** — no signatures, no bodies. A competent stranger should reconstruct the system's purpose from this list. If they cannot, intent has leaked into the mechanism; return to §5 and rename until they can. Mark every door that guards an irreversible effect with ⚠._
156
167
 
157
- _Instruction: The "Meat" of the document. Sufficient detail for an engineer to start coding._
168
+ > **Example:** `register_account`, `authenticate`, `authorize_charge`, `settle_payment` ⚠, `grant_access` ⚠, `revoke_access`, `publish_draft`. Reading these alone tells you who the system lets in, that money moves in exactly two steps and only those two, who may hand out access, and what it means for work to go live.
158
169
 
159
- ### 5.1 API Interfaces
170
+ ## 5. Detailed Design
160
171
 
161
- _Instruction: Define the contract. Use OpenAPI/Swagger snippets or Protocol Buffer definitions._
172
+ _Instruction: The "Meat" of the document. Sufficient detail for an engineer to start coding. Lead with the **doors** — they are the load-bearing part of the spec — then describe the mechanism behind them._
162
173
 
163
- **Endpoint:** `POST /api/v1/invoices`
174
+ ### 5.1 The Doors (Entrypoint Contracts)
164
175
 
165
- - **Auth:** Bearer Token (Scope: `invoice:write`)
166
- - **Idempotency:** Required header `X-Idempotency-Key`
167
- - **Request Body:**
176
+ _Instruction: For each non-trivial entrypoint, give a typed signature (typed pseudocode is fine — read the types, not the syntax), the one-sentence guarantee (no "and"), the named failure set, and the refusals it enforces in the type system. Then record the rubric result. Make illegal states **unrepresentable**, not merely checked. Cite the `research/` doc that establishes each joint._
168
177
 
169
- ```json
170
- { "user_id": "uuid", "amount": 100.0, "currency": "USD" }
178
+ ```
179
+ // Money. Two doors, and there is no third way to move a cent. —
180
+
181
+ authorize_charge(
182
+ account: AccountId, // newtype: cannot be confused with any other id
183
+ amount: Money, // currency-typed: USD and JPY will not add
184
+ idempotency_key: IdempotencyKey,
185
+ ): Result<AuthorizedCharge, ChargeError>
186
+ // Guarantee: places a reversible hold and returns proof an authorization exists.
187
+ // ChargeError = InsufficientFunds | CardDeclined | NetworkError | DuplicateKey
188
+
189
+ settle_payment(
190
+ authorized: AuthorizedCharge, // ← can ONLY be produced by authorize_charge
191
+ idempotency_key: IdempotencyKey,
192
+ ): Result<Settlement, SettlementError>
193
+ // Guarantee: captures the held funds. IRREVERSIBLE. The single chokepoint for outbound money.
194
+ // You cannot settle a charge you did not authorize — not because a check forbids it,
195
+ // but because there is no way to CONSTRUCT an AuthorizedCharge except by calling
196
+ // authorize_charge. The illegal state is unrepresentable. The idempotency key makes
197
+ // the retry, the double-click, and the at-least-once queue converge on ONE settlement.
171
198
  ```
172
199
 
173
- ### 5.2 Data Model / Schema
174
-
175
- _Instruction: Provide ERDs (Entity Relationship Diagrams) or JSON schemas. Discuss normalization vs. denormalization._
200
+ **Per-door audit (run the rubric):**
176
201
 
177
- **Table:** `invoices` (PostgreSQL)
202
+ | Door | (1) Joint | (2) One sentence, no "and" | (3) Honest name | (5) Every exit | (6) Refusals real | (7) Trust transition | (8) One chokepoint |
203
+ | ------------------ | --------------- | ---------------------------- | ------------------------------- | ------------------------------------------------ | ----------------------------------------- | -------------------- | ------------------------------ |
204
+ | `authorize_charge` | ✅ business verb | ✅ "places a reversible hold" | ✅ | retry → `DuplicateKey`; timeout → `NetworkError` | currency mismatch unrepresentable | n/a | reversible, not the chokepoint |
205
+ | `settle_payment` ⚠ | ✅ business verb | ✅ "captures held funds" | ✅ irreversibility in doc + type | replay converges via key | cannot settle un-authorized charge (type) | n/a | ✅ the sole outbound-money door |
178
206
 
179
- | Column | Type | Constraints | Description |
180
- | --------- | ---- | ----------------- | --------------------- |
181
- | `id` | UUID | PK | |
182
- | `user_id` | UUID | FK -> Users | Partition Key |
183
- | `status` | ENUM | 'PENDING', 'PAID' | Indexed for filtering |
207
+ ### 5.2 API Interfaces The Same Doors on the Wire
184
208
 
185
- ### 5.3 Algorithms and State Management
209
+ _Instruction: A web service's real boundary is its transport surface. The URL names the joint, the HTTP verb declares its safety class, the status code is the door's honest exit. Never `200 OK` wrapping an error. The wire door MUST carry the same name as its in-process twin (§5.1)._
186
210
 
187
- _Instruction: Describe complex logic, state machines, or consistency models._
211
+ ```
212
+ # Identity — the one trust transition, at the edge
213
+ POST /v1/sessions 201 Created # = authenticate; 401 on bad credentials
214
+ DELETE /v1/sessions/current 204 No Content # = log out
215
+
216
+ # Money — two doors, one chokepoint, idempotent under retry
217
+ POST /v1/payment_intents 201 Idempotency-Key: <key> # = authorize_charge (reversible)
218
+ POST /v1/payment_intents/{id}/capture 200 Idempotency-Key: <key> # = settle_payment (IRREVERSIBLE)
219
+ # 409 Conflict if the key is replayed with a different body
220
+ # 422 Unprocessable if the intent was never authorized
221
+
222
+ # Access — authority demanded by the route, destructive door made idempotent
223
+ POST /v1/accounts/{id}/grants 201 (admin scope required) # = grant_access
224
+ DELETE /v1/grants/{id} 204 (204 even if already revoked) # = revoke_access
225
+
226
+ # Publishing — the domain's own verb, refusing to clobber a concurrent edit
227
+ POST /v1/drafts/{id}/publish 200 If-Match: <etag> # = publish_draft
228
+ # 412 Precondition Failed if the draft moved under you — the wire's --force-with-lease
229
+ ```
188
230
 
189
- - **State Machine:** An invoice moves from `DRAFT` -> `LOCKED` -> `PROCESSING` -> `PAID`.
190
- - **Concurrency:** We use Optimistic Locking on the `version` column to prevent double-payments.
231
+ _If using gRPC, define the same joints in the `.proto`; the typed request message is the airlock by construction. Use honest status codes (`INVALID_ARGUMENT`, `PERMISSION_DENIED`, `NOT_FOUND`, `ALREADY_EXISTS`, `FAILED_PRECONDITION`, retryable `ABORTED`/`UNAVAILABLE`) never a lone `OK` carrying an error field._
191
232
 
192
- ## 6. Alternatives Considered
233
+ ### 5.3 Data Model / Schema
193
234
 
194
- _Instruction: Prove you thought about trade-offs. Why is your solution better than the others?_
235
+ _Instruction: Provide ERDs or JSON schemas. Discuss normalization vs. denormalization. Prefer schemas that make illegal states unrepresentable (sum-type status columns over independent boolean flags)._
195
236
 
196
- | Option | Pros | Cons | Reason for Rejection |
197
- | -------------------------------- | ---------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------- |
198
- | Option A: Synchronous HTTP Calls | Simple to implement, Easy to debug | Tight coupling, cascading failures | Latency requirements (200ms) make blocking calls risky. |
199
- | Option B: RabbitMQ | Lightweight, Built-in routing | Less durable than Kafka, harder to replay | We need message replay for auditing (Compliance requirement). |
200
- | Option C: Kafka (Selected) | High throughput, Replayability | Operational complexity | **Selected:** The need for auditability/replay outweighs the complexity cost. |
237
+ **Table:** `invoices` (PostgreSQL)
201
238
 
202
- ## 7. Cross-Cutting Concerns
239
+ | Column | Type | Constraints | Description |
240
+ | --------- | ---- | ------------------------------------ | ------------------------------ |
241
+ | `id` | UUID | PK | |
242
+ | `user_id` | UUID | FK -> Users | Partition Key |
243
+ | `status` | ENUM | 'DRAFT','LOCKED','PROCESSING','PAID' | A sum type, not three booleans |
203
244
 
204
- ### 7.1 Security and Privacy
245
+ ### 5.4 Algorithms and State Management
205
246
 
206
- - **Authentication:** Services authenticate via mTLS.
207
- - **Authorization:** Policy enforcement point at the API Gateway (OPA - Open Policy Agent).
208
- - **Data Protection:** PII (Names, Emails) is encrypted at rest using AES-256.
209
- - **Threat Model:** Primary threat is compromised API Key; remediation is rapid rotation and rate limiting.
247
+ _Instruction: Describe complex logic, state machines, or consistency models. Tie each state transition to the door that performs it._
210
248
 
211
- ### 7.2 Observability Strategy
249
+ - **State Machine:** An invoice moves `DRAFT` → `LOCKED` → `PROCESSING` → `PAID`; the `PROCESSING → PAID` transition happens only through `settle_payment`.
250
+ - **Concurrency:** Optimistic locking on the `version` column; on the wire this surfaces as `If-Match`/`412`.
212
251
 
213
- - **Metrics:** We will track `invoice_creation_latency` (Histogram) and `payment_failure_count` (Counter).
214
- - **Tracing:** All services propagate `X-Trace-ID` headers (OpenTelemetry).
215
- - **Alerting:** PagerDuty triggers if `5xx` error rate > 1% for 5 minutes.
252
+ ## 6. Alternatives Considered
216
253
 
217
- ### 7.3 Scalability and Capacity Planning
254
+ _Instruction: Prove you thought about trade-offs — including alternative **door sets** (e.g., one god endpoint vs. distinct joints). Why is your boundary better than the others?_
218
255
 
219
- - **Traffic Estimates:** 1M transactions/day = ~12 TPS avg / 100 TPS peak.
220
- - **Storage Growth:** 1KB per record \* 1M = 1GB/day.
221
- - **Bottleneck:** The PostgreSQL Write node is the bottleneck. We will implement Read Replicas to offload traffic.
256
+ | Option | Pros | Cons | Reason for Rejection |
257
+ | ------------------------------------------- | ------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------ |
258
+ | Option A: Single `POST /execute {action}` | One route, flexible | God door; intent hidden in payload; danger un-funneled | Fails "joint, not tool" and "few dangerous doors." |
259
+ | Option B: One-step `chargeCard()` | Fewest calls | No reversible hold; retries double-charge | Cannot make double-charge unrepresentable. |
260
+ | Option C: `authorize` + `settle` (Selected) | Reversible hold; one chokepoint; idempotent | Two calls instead of one | **Selected:** the two real joints, with the irreversible effect funneled once. |
222
261
 
223
- ## 8. Migration, Rollout, and Testing
262
+ ## 7. Cross-Cutting Concerns
224
263
 
225
- ### 8.1 Deployment Strategy
264
+ ### 7.1 Security and Privacy
226
265
 
227
- - [ ] Phase 1: Deploy services in "Shadow Mode" (process traffic but do not email users).
228
- - [ ] Phase 2: Enable Feature Flag `new-billing-engine` for 1% of internal users.
229
- - [ ] Phase 3: Ramp to 100%.
266
+ _Instruction: This is where "keep the dangerous doors few and honest" and "the airlock at the boundary" become concrete._
230
267
 
231
- ### 8.2 Data Migration Plan
268
+ - **The trust transition is singular:** untrusted callers become trusted only at `POST /v1/sessions` / the gateway. No other door promotes an anonymous caller. (Rubric #7.)
269
+ - **Authority carried by type:** destructive/privileged doors demand a capability (`AdminSession`) that only `authenticate` can mint — the permission check cannot be forgotten at a call site because there is no call site where it is absent. (Rubric #6.)
270
+ - **Irreversible effects pass one chokepoint:** money via `settle_payment`, deletion via the single guarded door; the catastrophic version must be asked for explicitly. (Rubric #8.)
271
+ - **Data Protection:** PII (names, emails) encrypted at rest (AES-256); `Password` is a newtype that cannot be logged, printed, or compared by accident.
272
+ - **Threat Model:** Primary threat is a compromised API key; remediation is rapid rotation and rate limiting.
232
273
 
233
- - **Backfill:** We will run a script to migrate the last 90 days of invoices from the legacy SQL server.
234
- - **Verification:** A "Reconciliation Job" will run nightly to compare Legacy vs. New totals.
274
+ ## 8. Test Plan
235
275
 
236
- ### 8.3 Test Plan
276
+ _Instruction: Test the doors at their promises and their refusals — not just the happy path. Every exit in rubric #5 deserves a test. The interactive verification is what lets a human or another agent confirm the feature is correct without reading the bodies — the stranger-across-time test, made executable._
237
277
 
238
- - **Unit Tests:**
239
- - **Integration Tests:**
240
- - **End-to-End Tests:**
278
+ - **Unit Tests:** each door's named failure variants; the *refusals* (e.g., a type/construction test proving `settle_payment` cannot accept anything but an `AuthorizedCharge`).
279
+ - **End-to-End Tests:** full domain flows named by joint (register → authenticate → authorize → settle), driven through the real wire doors of §5.2.
280
+ - **Integration Tests:** idempotency under replay (same key → one settlement); concurrent-edit `412`; trust transition (no door promotes an anonymous caller except `authenticate`).
281
+ - **Fuzz / Property Tests:** throw malformed and adversarial input at the doors (the airlock); the boundary must reject everything the types forbid and never crash the core. Assert invariants over random inputs (e.g., `settle_payment` converges on one settlement under any interleaving of retries; no input sequence reaches a money move except through the chokepoint).
282
+ - **Interactive Verification:** a runnable checklist or script a human OR another agent can execute to confirm the feature was implemented correctly — each step names a door, supplies an input, and states the expected honest exit (status code / named error / resulting state), so correctness is observable from the boundary alone. Include the exact commands or requests to run and the pass/fail condition for each.
241
283
 
242
284
  ## 9. Open Questions / Unresolved Issues
243
285
 
244
- _Instruction: List known unknowns. These must be resolved before the doc is marked "Approved"._
286
+ _Instruction: List known unknowns. These must be resolved before the doc is marked "Approved." Include any door whose rubric could not be answered cleanly — especially undefined guarantees (rubric #2, the most dangerous case) and any irreversible effect not yet funneled to a single chokepoint (rubric #8). Resolve these with the user via contrastive clarification._
245
287
 
246
- - [ ] Will the Legal team approve the 3rd party library for PDF generation?
288
+ - [ ] Is `publish_draft` the only door that moves a draft to live, or can the admin panel also publish? (If the latter, the effect is not yet funneled — rubric #8.)
289
+ - [ ] What exactly does `authorize_charge` promise on a partial provider outage — is the guarantee defined? (rubric #2.)
290
+ - [ ] Will the Legal team approve the 3rd-party library for PDF generation?
247
291
  - [ ] Does the current VPC peering allow connection to the legacy mainframe?