shapeup-sdlc 1.6.2

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 (135) hide show
  1. package/.claude/settings.local.example.json +20 -0
  2. package/.claude-plugin/marketplace.json +16 -0
  3. package/.claude-plugin/plugin.json +18 -0
  4. package/.env.shapeup.example +14 -0
  5. package/AGENTS.md +133 -0
  6. package/LICENSE +21 -0
  7. package/README.md +362 -0
  8. package/SECURITY.md +72 -0
  9. package/bin/init.mjs +329 -0
  10. package/commands/build.md +14 -0
  11. package/commands/eval.md +15 -0
  12. package/commands/hammer.md +12 -0
  13. package/commands/orient.md +11 -0
  14. package/commands/qa.md +12 -0
  15. package/commands/retro.md +13 -0
  16. package/commands/scopes.md +14 -0
  17. package/commands/shape.md +12 -0
  18. package/commands/ship.md +53 -0
  19. package/commands/wire.md +11 -0
  20. package/hooks/anti-rationalization.mjs +244 -0
  21. package/hooks/compact-snapshot.mjs +47 -0
  22. package/hooks/gate-deadline.mjs +151 -0
  23. package/hooks/gate-intake.mjs +110 -0
  24. package/hooks/gate-l2.mjs +161 -0
  25. package/hooks/gate-zerowork.mjs +264 -0
  26. package/hooks/hooks.json +118 -0
  27. package/hooks/lib/decision.mjs +183 -0
  28. package/hooks/safety-spine.mjs +296 -0
  29. package/hooks/sandbox-guard.mjs +172 -0
  30. package/hooks/session-rehydrate.mjs +109 -0
  31. package/hooks/slop-cleaner.mjs +176 -0
  32. package/oracles/_shared.mjs +46 -0
  33. package/oracles/http-oracle.mjs +155 -0
  34. package/oracles/index.mjs +36 -0
  35. package/oracles/process-oracle.mjs +146 -0
  36. package/oracles/snapshot-oracle.mjs +119 -0
  37. package/oracles/test-oracle.mjs +138 -0
  38. package/package.json +49 -0
  39. package/skills/advisor-protocol/SKILL.md +171 -0
  40. package/skills/ba-pitch-analyzer/SKILL.md +175 -0
  41. package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +84 -0
  42. package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +65 -0
  43. package/skills/ba-pitch-analyzer/assets/templates/assess-report.tmpl.md +127 -0
  44. package/skills/ba-pitch-analyzer/assets/templates/contracts/be-service.contract.tmpl.md +62 -0
  45. package/skills/ba-pitch-analyzer/assets/templates/contracts/offline-storage.contract.tmpl.md +92 -0
  46. package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +66 -0
  47. package/skills/ba-pitch-analyzer/assets/templates/cross-context/context-map.tmpl.md +64 -0
  48. package/skills/ba-pitch-analyzer/assets/templates/cross-context/event-choreography.tmpl.md +77 -0
  49. package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +104 -0
  50. package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +79 -0
  51. package/skills/ba-pitch-analyzer/assets/templates/domain-model.tmpl.md +79 -0
  52. package/skills/ba-pitch-analyzer/assets/templates/feedback.tmpl.md +87 -0
  53. package/skills/ba-pitch-analyzer/assets/templates/integration.tmpl.md +64 -0
  54. package/skills/ba-pitch-analyzer/assets/templates/run-state.tmpl.md +77 -0
  55. package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +105 -0
  56. package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +215 -0
  57. package/skills/ba-pitch-analyzer/assets/templates/task-board.tmpl.md +35 -0
  58. package/skills/ba-pitch-analyzer/assets/templates/task-spike.tmpl.md +86 -0
  59. package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +84 -0
  60. package/skills/ba-pitch-analyzer/assets/templates/usecase.tmpl.md +105 -0
  61. package/skills/ba-pitch-analyzer/assets/templates/ux-behavior.tmpl.md +65 -0
  62. package/skills/ba-pitch-analyzer/references/contract-patterns.md +152 -0
  63. package/skills/ba-pitch-analyzer/references/ddd-patterns.md +173 -0
  64. package/skills/ba-pitch-analyzer/references/doc-schemas.md +275 -0
  65. package/skills/ba-pitch-analyzer/references/integration-analysis.md +152 -0
  66. package/skills/ba-pitch-analyzer/references/task-generation.md +623 -0
  67. package/skills/ba-pitch-analyzer/references/test-surface.md +102 -0
  68. package/skills/ba-pitch-analyzer/references/ux-behavior-patterns.md +269 -0
  69. package/skills/ba-pitch-analyzer/scripts/board-derive.mjs +241 -0
  70. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +239 -0
  71. package/skills/coach/SKILL.md +202 -0
  72. package/skills/orient/SKILL.md +262 -0
  73. package/skills/qa-edge-hunter/SKILL.md +369 -0
  74. package/skills/scope-architect/SKILL.md +111 -0
  75. package/skills/scope-hammer/SKILL.md +186 -0
  76. package/skills/shapeup/SKILL.md +403 -0
  77. package/skills/shapeup/resources/breadboard-reflection.md +88 -0
  78. package/skills/shapeup/resources/breadboarding.md +334 -0
  79. package/skills/shapeup/resources/context-compaction.md +240 -0
  80. package/skills/shapeup/resources/framing-doc.md +92 -0
  81. package/skills/shapeup/resources/kickoff-doc.md +95 -0
  82. package/skills/shapeup/resources/shaping.md +194 -0
  83. package/skills/shapeup/resources/spike.md +86 -0
  84. package/skills/solution-architect/SKILL.md +129 -0
  85. package/skills/spec-evaluator/README.md +93 -0
  86. package/skills/spec-evaluator/SKILL.md +213 -0
  87. package/skills/spec-evaluator/references/anti-leniency.md +50 -0
  88. package/skills/spec-evaluator/references/dimension-contract.md +126 -0
  89. package/skills/spec-evaluator/references/dimensions/_registry.md +40 -0
  90. package/skills/spec-evaluator/references/dimensions/completeness.md +102 -0
  91. package/skills/spec-evaluator/references/dimensions/integration.md +129 -0
  92. package/skills/spec-evaluator/references/dimensions/performance.md +48 -0
  93. package/skills/spec-evaluator/references/dimensions/security.md +60 -0
  94. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +134 -0
  95. package/skills/spec-evaluator/references/dimensions/tdd-surface.md +110 -0
  96. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +100 -0
  97. package/skills/spec-evaluator/references/probing.md +177 -0
  98. package/skills/spec-evaluator/references/report-schema.md +101 -0
  99. package/skills/spec-evaluator/references/verdict-ledger.md +92 -0
  100. package/skills/spec-evaluator/scripts/verdict-ledger.mjs +166 -0
  101. package/skills/task-executor/SKILL.md +194 -0
  102. package/skills/tech-lead/README.md +71 -0
  103. package/skills/tech-lead/SKILL.md +459 -0
  104. package/skills/tech-lead/references/delegation.md +254 -0
  105. package/skills/tech-lead/references/gates.md +379 -0
  106. package/skills/tech-lead/references/invocation.md +45 -0
  107. package/skills/tech-lead/references/ledger-schema.md +214 -0
  108. package/skills/tech-lead/references/round-protocol.md +184 -0
  109. package/skills/tech-lead/references/state-model.md +66 -0
  110. package/skills/tech-lead/references/tiny-lane.md +52 -0
  111. package/skills/tech-lead/schemas/domain.schema.json +2294 -0
  112. package/skills/tech-lead/schemas/gate-answers.schema.json +92 -0
  113. package/skills/tech-lead/schemas/work-order.schema.json +21 -0
  114. package/skills/tech-lead/schemas/work-result.schema.json +40 -0
  115. package/skills/tech-lead/scripts/aegis-digest.mjs +124 -0
  116. package/skills/tech-lead/scripts/budget-check.mjs +156 -0
  117. package/skills/tech-lead/scripts/compile-order.mjs +518 -0
  118. package/skills/tech-lead/scripts/fit-check.mjs +196 -0
  119. package/skills/tech-lead/scripts/gate-answers.mjs +338 -0
  120. package/skills/tech-lead/scripts/ingest-result.mjs +270 -0
  121. package/skills/tech-lead/scripts/init-run.mjs +326 -0
  122. package/skills/tech-lead/scripts/lib/argv.mjs +224 -0
  123. package/skills/tech-lead/scripts/lib/contract-md.mjs +481 -0
  124. package/skills/tech-lead/scripts/lib/is-main.mjs +82 -0
  125. package/skills/tech-lead/scripts/lib/paths.mjs +278 -0
  126. package/skills/tech-lead/scripts/lib/ratchet-tree.mjs +112 -0
  127. package/skills/tech-lead/scripts/run-snapshot.mjs +269 -0
  128. package/skills/tech-lead/scripts/ship-report.mjs +275 -0
  129. package/skills/tech-lead/scripts/stats.mjs +423 -0
  130. package/skills/tech-lead/scripts/t0-verify.mjs +470 -0
  131. package/skills/tech-lead/scripts/trace-lint.mjs +367 -0
  132. package/skills/tech-lead/scripts/validate-envelope.mjs +283 -0
  133. package/skills/translator/README.md +66 -0
  134. package/skills/translator/SKILL.md +258 -0
  135. package/skills/translator/references/preservation-rules.md +102 -0
@@ -0,0 +1,152 @@
1
+ # Contract Patterns — Repository Boundary Contracts
2
+
3
+ Reference for Phase 2b. Read before writing any `.contract.md` file.
4
+
5
+ ---
6
+
7
+ ## Why Contracts Exist
8
+
9
+ Repository interfaces in `domain-model.md` define *what* a repository does.
10
+ Contract files define *exactly what shape* goes in and comes out.
11
+
12
+ A developer must be able to read a contract and answer:
13
+ - What exact fields do I send?
14
+ - What fields come back, and what are their types and invariants?
15
+ - What errors can occur, and how do I handle each one?
16
+
17
+ If any of those questions require opening another document, the contract is incomplete.
18
+
19
+ ---
20
+
21
+ ## Determining Source Type
22
+
23
+ Read the pitch and domain model. For each repository interface, ask:
24
+
25
+ ```
26
+ Is the data store internal to the monorepo?
27
+ ├── YES and it's a database/file/local cache → offline-storage
28
+ └── YES and it's another service in the system → be-service
29
+
30
+ Is the data store an external vendor?
31
+ └── YES → third-party-api
32
+ ```
33
+
34
+ Use the corresponding template from `assets/templates/contracts/`.
35
+
36
+ ---
37
+
38
+ ## Source Type: `be-service`
39
+
40
+ Use when: repository calls an internal HTTP service (same org, different service/package).
41
+
42
+ **Key contract fields:**
43
+ - HTTP method + path (exact, including path params)
44
+ - Auth header type — never leave this implicit
45
+ - Request body table with `Source` column tracing each field to a UC input or env var
46
+ - Response table per HTTP status code (200, 201, etc.)
47
+ - Error table with HTTP status, error code, UX action
48
+
49
+ **Contract is `status: confirmed` immediately** — Dev can verify from service code.
50
+
51
+ **Source column values:**
52
+ ```
53
+ UC-[Name].input.[fieldName] ← from a use case input interface
54
+ env.[ENV_VAR_NAME] ← from environment config
55
+ session.[claim] ← from JWT/auth context (e.g. session.userId)
56
+ domain.[Aggregate].[field] ← derived from domain model state
57
+ computed:[formula] ← calculated by application layer before calling repo
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Source Type: `third-party-api`
63
+
64
+ Use when: repository calls an external vendor API or SDK (Framer, Stripe, Twilio, etc.).
65
+
66
+ **Key contract fields:**
67
+ - Same as be-service PLUS:
68
+ - `feasibility_ref: API-NN` — links to api-feasibility.md investigation block
69
+ - `spike_task` — links to the SPIKE task that will confirm this contract
70
+ - `status: speculative` — MUST remain speculative until SPIKE is done
71
+ - `⚠️ SPECULATIVE CONTRACT` header — visible warning to all readers
72
+
73
+ **⏳ TBD annotation format:**
74
+ ```markdown
75
+ | pageId | string | ⏳ TBD — field name unverified | publishPage() |
76
+ ```
77
+ Every `⏳ TBD` field must reference what needs to be confirmed.
78
+
79
+ **Transition to confirmed:**
80
+ When SPIKE task is complete, Dev:
81
+ 1. Replaces all `⏳ TBD` entries with confirmed values + source URL
82
+ 2. Changes `status: speculative` → `status: confirmed`
83
+ 3. Removes `⚠️ SPECULATIVE CONTRACT` header
84
+ 4. Fills `Post-SPIKE Update Log` table
85
+ 5. Implementation tasks blocking annotation can now be removed
86
+
87
+ ---
88
+
89
+ ## Source Type: `offline-storage`
90
+
91
+ Use when: repository reads/writes to local device storage (SQLite, AsyncStorage, MMKV,
92
+ file system, or in-memory cache).
93
+
94
+ **Key contract fields:**
95
+ - Engine name (SQLite via Drizzle, AsyncStorage, MMKV, etc.)
96
+ - Table/key schema with column types, constraints, and migration version
97
+ - Migration version must match `domain-model.md` schema version — they stay in sync
98
+ - Conflict strategy — what happens on concurrent writes
99
+ - Null behavior for read methods — must be explicit (null vs empty array vs throw)
100
+
101
+ **Contract is `status: confirmed` immediately** — schema is defined in the spec.
102
+
103
+ **Null behavior rule:**
104
+ ```
105
+ findById → returns null (never throws) when not found
106
+ findAll → returns [] (never null) when empty
107
+ write → throws StorageError (never returns null) on failure
108
+ ```
109
+ These invariants must appear in the contract Error Cases table.
110
+
111
+ ---
112
+
113
+ ## Contract Registry (`contracts/_index.md`)
114
+
115
+ Every contracts folder must have an `_index.md` registry:
116
+
117
+ ```markdown
118
+ # Contract Registry — [feature-slug]
119
+
120
+ | Repository | Source Type | Service / Engine | Status | SPIKE Task |
121
+ |-----------|------------|-----------------|--------|------------|
122
+ | [[FramerPageRepository]] | third-party-api | Framer REST API | ⚠️ speculative | [[TASK-001]] |
123
+ | [[PageCacheRepository]] | offline-storage | SQLite/Drizzle | ✅ confirmed | — |
124
+ | [[UserSessionRepository]] | be-service | apps/api /auth | ✅ confirmed | — |
125
+ ```
126
+
127
+ This registry is the entry point for the spec-lint structure checks.
128
+
129
+ ---
130
+
131
+ ## Contract → Task Traceability
132
+
133
+ Every implementation task that uses a repository MUST:
134
+
135
+ 1. Reference the contract in the Context section:
136
+ ```markdown
137
+ ## Context
138
+ Implement FramerPageRepository per [[contracts/framer-page.contract.md]].
139
+ ```
140
+
141
+ 2. Include these three AC lines under Baseline:
142
+ ```markdown
143
+ - [ ] Request shape matches [[contracts/framer-page.contract.md#Request]] table
144
+ - [ ] Response mapping matches [[contracts/framer-page.contract.md#Response]] table
145
+ - [ ] All error codes in contract Error Cases table are handled
146
+ ```
147
+
148
+ 3. If contract is still `speculative` at task-generation time:
149
+ ```markdown
150
+ > ⏳ BLOCKED by [[TASK-001-spike-framer-feasibility]]
151
+ > Unblock condition: [[contracts/framer-page.contract.md]] has no remaining ⏳ TBD fields
152
+ ```
@@ -0,0 +1,173 @@
1
+ # DDD Patterns — Domain Modeling Guide
2
+
3
+ Reference for Phase 2 of the BA Pitch Analyzer. Read this before writing `domain-model.md`.
4
+
5
+ ---
6
+
7
+ ## Bounded Context Decision
8
+
9
+ Ask these questions from the pitch:
10
+
11
+ 1. **Who owns the data lifecycle?** The context that creates AND deletes an entity owns it.
12
+ 2. **What crosses a context boundary?** Cross-context = domain event or anti-corruption layer, never direct DB join.
13
+ 3. **Does this pitch create a new context or extend existing?** Extending = add to existing `domain-model.md`. New = create new bounded context folder.
14
+
15
+ ### Common Bounded Contexts (reference for monorepo)
16
+
17
+ | Context | Owns | Does NOT own |
18
+ |---------|------|-------------|
19
+ | `ordering` | Order, LineItem, Cart | Product catalog, Stock levels |
20
+ | `inventory` | StockItem, Warehouse | Order details |
21
+ | `identity` | User, Session, Role | Profile preferences |
22
+ | `payment` | Payment, PaymentAttempt | Order totals |
23
+ | `notification` | Message, Channel, Template | Business triggers |
24
+
25
+ ---
26
+
27
+ ## Aggregate Design Rules
28
+
29
+ ### Identifying Aggregate Roots
30
+
31
+ An entity is an Aggregate Root if:
32
+ - Other entities can't exist without it (LineItem can't exist without Order)
33
+ - It enforces invariants across child entities
34
+ - It's the entry point for all external writes
35
+
36
+ ### Invariant Checklist
37
+
38
+ For every aggregate, document at least one invariant:
39
+ - `Order.totalAmount` must equal sum of `LineItem.subtotals`
40
+ - `Order` can only transition: `draft → placed → paid | failed`
41
+ - `PaymentAttempt` count must not exceed 3 per `Payment`
42
+
43
+ ### Aggregate Size Heuristic
44
+
45
+ - **Too large:** aggregate has more than 3-4 entity types → split
46
+ - **Too small:** every operation needs to load 3 aggregates → merge
47
+ - **Right size:** one transaction boundary, one invariant set
48
+
49
+ ---
50
+
51
+ ## Value Object Patterns
52
+
53
+ Value Objects have no identity — equality is by value, not ID.
54
+
55
+ ```typescript
56
+ // ✅ Value Object — no ID field
57
+ class Money {
58
+ constructor(
59
+ readonly amount: number, // integer cents/VND — no float
60
+ readonly currency: 'VND' | 'USD'
61
+ ) {
62
+ if (amount < 0) throw new DomainError('Money cannot be negative')
63
+ }
64
+ equals(other: Money): boolean {
65
+ return this.amount === other.amount && this.currency === other.currency
66
+ }
67
+ }
68
+
69
+ // ✅ Value Object — wraps primitive with validation
70
+ class OrderId {
71
+ constructor(readonly value: string) {
72
+ if (!isUUID(value)) throw new DomainError('Invalid OrderId')
73
+ }
74
+ }
75
+ ```
76
+
77
+ When to use VO vs Entity:
78
+ - Has identity that persists across mutations → Entity
79
+ - Replaced entirely when changed → Value Object
80
+ - Examples of VOs: Money, Address, Email, PhoneNumber, DateRange, Coordinates
81
+
82
+ ---
83
+
84
+ ## Domain Event Patterns
85
+
86
+ ### Naming Convention
87
+ `[AggregateRoot][PastTense]` — e.g., `OrderPlaced`, `PaymentConfirmed`, `UserRegistered`
88
+
89
+ ### Event Payload Design
90
+ ```typescript
91
+ // Include: what happened, when, who, minimal context for consumers
92
+ interface OrderPlaced {
93
+ eventId: string // UUID
94
+ occurredAt: Date
95
+ orderId: string
96
+ customerId: string
97
+ totalAmount: number
98
+ lineItemCount: number
99
+ // Do NOT include: full line items, customer PII, computed fields
100
+ }
101
+ ```
102
+
103
+ ### Event → Consumer Mapping Table Format
104
+ ```
105
+ | Event | Emitted By | Consumed By | Purpose |
106
+ |-------|------------|-------------|---------|
107
+ | OrderPlaced | ordering ctx | inventory ctx | Reserve stock |
108
+ | OrderPlaced | ordering ctx | notification ctx | Send confirmation |
109
+ | PaymentConfirmed | payment ctx | ordering ctx | Transition order to paid |
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Repository Interface Rules
115
+
116
+ 1. **Return domain objects, not DTOs** — `findById` returns `Order`, not `OrderRow`
117
+ 2. **No query logic in interface** — business queries get named methods
118
+ 3. **Async always** — all methods return `Promise<T>`
119
+ 4. **Soft-delete pattern** — if entities are soft-deleted, interface reflects it
120
+
121
+ ```typescript
122
+ // ✅ Well-designed repository interface
123
+ interface OrderRepository {
124
+ findById(id: OrderId): Promise<Order | null>
125
+ findByCustomer(customerId: string, limit: number): Promise<Order[]>
126
+ findPendingPayment(): Promise<Order[]> // named business query
127
+ save(order: Order): Promise<void> // insert or update
128
+ // NO: findAll(), count(), rawQuery()
129
+ }
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Anti-Patterns to Flag in Pitch Analysis
135
+
136
+ When reading a pitch, look for these and document them as **Rabbit Holes**:
137
+
138
+ | Anti-Pattern | Symptom | Better Approach |
139
+ |---|---|---|
140
+ | Shared DB table | "Both services read the orders table" | Domain events + projection |
141
+ | Aggregate too large | "Order contains everything incl. shipping" | Split shipping to own aggregate |
142
+ | Anemic domain | "Service layer contains all business logic" | Move invariants into aggregate |
143
+ | Primitive obsession | `userId: string` everywhere | Typed `UserId` value object |
144
+ | Missing domain event | State change with no downstream consumer | Add event even if no consumer yet |
145
+
146
+ ---
147
+
148
+ ## Template: Aggregate Section in domain-model.md
149
+
150
+ ```markdown
151
+ ## Aggregate: [Name]
152
+
153
+ **Aggregate Root:** `[EntityName]`
154
+ **Invariants:**
155
+ - [invariant 1]
156
+ - [invariant 2]
157
+
158
+ \`\`\`
159
+ [EntityName] (Aggregate Root)
160
+ ├── id: [EntityName]Id (VO)
161
+ ├── status: [EntityName]Status ([values])
162
+ ├── [field]: [Type]
163
+ └── [childEntity]: [ChildEntity][] (Entity, owned)
164
+ ├── id: [ChildEntity]Id
165
+ └── [field]: [Type]
166
+ \`\`\`
167
+
168
+ **State Transitions:**
169
+ \`\`\`
170
+ draft ──place()──► placed ──confirm()──► confirmed
171
+ └───fail()────► failed
172
+ \`\`\`
173
+ ```
@@ -0,0 +1,275 @@
1
+ # Document Schemas — Frontmatter Taxonomy
2
+
3
+ Shared vocabulary used across all document types. Every field listed here uses the same
4
+ values so wikilinks and tag queries work consistently across the spec tree.
5
+
6
+ ---
7
+
8
+ ## Shared Taxonomy Fields
9
+
10
+ ```yaml
11
+ # TYPE — document classification
12
+ type: pitch | domain-model | ux-spec | usecase | integration | task
13
+ | assess-report | run-state | context-map | event-choreography
14
+ | migration-plan | team-handoff | synthesis
15
+
16
+ # FEATURE — namespace for the entire spec tree (kebab-case)
17
+ feature: checkout-vnpay
18
+
19
+ # LENS — architectural perspective used when generating this document
20
+ # Determines which phases ran and which documents are authoritative
21
+ lens: lite | standard | cross-context
22
+
23
+ # BOUNDED CONTEXT — DDD context that owns this feature
24
+ bounded_context: ordering | inventory | identity | notification | payment
25
+
26
+ # STATUS — lifecycle state
27
+ status: draft | ready | in-progress | blocked | done
28
+
29
+ # ENTITIES — domain entities referenced or defined
30
+ entities: [Order, LineItem, Payment]
31
+
32
+ # REPOSITORIES — repository interfaces referenced or defined
33
+ repositories: [OrderRepository, PaymentRepository]
34
+
35
+ # USECASES — use case IDs referenced (e.g. UC-CreateOrder)
36
+ usecases: [UC-CreateOrder, UC-InitiatePayment]
37
+
38
+ # TAGS — free-form, for cross-cutting search
39
+ tags: [payment, vnpay, checkout, mobile]
40
+
41
+ # DEPENDS_ON — wikilinks to docs this doc depends on
42
+ depends_on: ["[[_index]]", "[[domain-model]]"]
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Lens-Aware Document Authority
48
+
49
+ Each lens has a **central document** — the most detailed and authoritative spec.
50
+ Other documents exist but are less exhaustive.
51
+
52
+ | Lens | Central Document | Secondary | Skipped |
53
+ |------|-----------------|-----------|---------|
54
+ | `lite` | `ux-behavior.md` | domain-model, usecases, tasks | contracts/, integration.md, synthesis S-02/S-03 |
55
+ | `standard` | `contracts/` | domain-model, ux-behavior, usecases, integration, synthesis full | — |
56
+ | `cross-context` | `_cross-context/` | all standard docs per context | — |
57
+
58
+ When upgrading `lite → standard`:
59
+ - `ux-behavior.md` stays authoritative for screen specs
60
+ - Use cases are **reconciled** (API boundary sub-section added, not overwritten)
61
+ - `contracts/` generated from reconciled UC API sub-sections
62
+ - Reconciled files reported in the WorkResult's `deviations[]`
63
+
64
+ ---
65
+
66
+ ## Schema Per Document Type
67
+
68
+ ### `_index.md` — Pitch Digest
69
+
70
+ ```yaml
71
+ ---
72
+ type: pitch
73
+ feature: [slug]
74
+ appetite: "6 weeks" # Shape Up time box
75
+ status: draft | ready
76
+ bounded_context: [context]
77
+ entities: []
78
+ tags: []
79
+ ---
80
+ ```
81
+
82
+ Required sections: Problem, Appetite, Boundaries, Breadboarding, Rabbit Holes, Document Map
83
+
84
+ ---
85
+
86
+ ### `domain-model.md` — DDD Model
87
+
88
+ ```yaml
89
+ ---
90
+ type: domain-model
91
+ feature: [slug]
92
+ bounded_context: [context]
93
+ entities: []
94
+ value_objects: []
95
+ domain_events: []
96
+ repositories: []
97
+ tags: [ddd]
98
+ depends_on: ["[[_index]]"]
99
+ status: draft | ready
100
+ ---
101
+ ```
102
+
103
+ Required sections: Bounded Context, Aggregates (one subsection each), Value Objects table,
104
+ Domain Events table, Repository Interfaces (TypeScript interface blocks)
105
+
106
+ ---
107
+
108
+ ### `ux-behavior.md` — UX Spec
109
+
110
+ ```yaml
111
+ ---
112
+ type: ux-spec
113
+ feature: [slug]
114
+ entities: []
115
+ usecases: []
116
+ screens: [] # list of screen/view names
117
+ figma_link: [Figma Project URL] # Optional: Link to the overall Figma file
118
+ tags: [ux]
119
+ depends_on: ["[[domain-model]]"]
120
+ status: draft | ready
121
+ ---
122
+ ```
123
+
124
+ Required sections: Screen Flow (ASCII diagram), one section per Screen with:
125
+ - **Figma Frame**: [Figma Frame Node ID / URL] (Mandatory if Figma mocks exist)
126
+ - **Visual & Layout Specs**: Flex/Grid structure, spacing, alignment rules, and desktop/mobile responsiveness
127
+ - **Design Tokens**: Specific CSS variables or Tailwind classes used for background, borders, fonts, and actions
128
+ - **States table**, **Behavior Rules list**, **Error States table**
129
+
130
+
131
+ ---
132
+
133
+ ### `usecases/UC-[Name].md` — Use Case
134
+
135
+ ```yaml
136
+ ---
137
+ type: usecase
138
+ feature: [slug]
139
+ id: UC-[Name] # PascalCase, must be unique in feature
140
+ bounded_context: [context]
141
+ actor: Customer | Admin | System
142
+ entities: []
143
+ repositories: []
144
+ domain_events_emitted: []
145
+ tags: []
146
+ depends_on: ["[[domain-model]]", "[[ux-behavior]]"]
147
+ status: draft | ready
148
+ ---
149
+ ```
150
+
151
+ > **No `related_tasks` (retired in v3.3).** UC→task linkage is one-directional by design:
152
+ > tasks carry `use_case_refs` (LOCAL, per-machine board); reverse lookup is always computed
153
+ > live (synthesis S-01, audit coverage) — never stored on the committed UC. Rule: **never
154
+ > declare a bidirectional field across the committed/local boundary** — task IDs renumber
155
+ > per machine (generate-board bootstrap), so a stored back-link is wrong on every machine
156
+ > but one. Tolerate (ignore) the field on pre-v3.3 specs; do not emit or update it.
157
+
158
+ Required sections: Summary (1 sentence), Preconditions, Input (TS interface), Steps
159
+ (numbered application layer), Output (TS interface), Error Cases table, Integration Points
160
+
161
+ ---
162
+
163
+ ### `usecases/_index.md` — Use Case Index
164
+
165
+ ```yaml
166
+ ---
167
+ type: usecase-index
168
+ feature: [slug]
169
+ tags: []
170
+ ---
171
+ ```
172
+
173
+ Required: table of all UCs with columns: ID | Title | Actor | Status | Depends On
174
+ Plus: dependency diagram (ASCII or mermaid)
175
+
176
+ ---
177
+
178
+ ### `integration.md` — System Impact Map
179
+
180
+ ```yaml
181
+ ---
182
+ type: integration
183
+ feature: [slug]
184
+ affected_services: [] # internal services, external APIs
185
+ domain_events_consumed: []
186
+ domain_events_produced: []
187
+ tags: [integration]
188
+ depends_on: ["[[domain-model]]", "[[usecases/_index]]"]
189
+ status: draft | ready
190
+ ---
191
+ ```
192
+
193
+ Required sections: Impact Summary, one subsection per affected system with:
194
+ Data Flow, Trigger, Risk, Mitigation
195
+
196
+ ---
197
+
198
+ ### `tasks/TASK-NNN-slug.md` — Task
199
+
200
+ > **Locality (v3.2):** written under the LOCAL gitignored root
201
+ > (`.shapeup/<slug>/tasks/`), not `spec_folder`. Every other schema on this page is a
202
+ > SHARED, committed document. Tier direction: the task file must fully anchor INTO the
203
+ > committed spec (`use_case_refs`, `linked_docs`, the Context wikilink — LOCAL→SHARED);
204
+ > no SHARED doc ever wikilinks `[[tasks/...]]` back (spec-lint TIER-DIRECTION red).
205
+
206
+ ```yaml
207
+ ---
208
+ type: task
209
+ feature: [slug]
210
+ id: TASK-[NNN] # zero-padded 3 digits: TASK-001
211
+ title: "[imperative verb phrase]"
212
+ lens: lite | standard # inherited from run-state
213
+ package: apps/api | apps/web | packages/shared | apps/mobile
214
+ status: ready | in-progress | blocked | done
215
+ priority: [integer] # 1 = highest
216
+ depends_on: [] # other TASK IDs: [TASK-001, TASK-002] — the AUTHORITATIVE edge
217
+ unlocks: [] # DERIVED — inverse of the board's depends_on graph, recomputed
218
+ # on every board write; never hand-authored (v3.3)
219
+ use_case_refs: [] # UC IDs this task implements: [UC-CreateOrder]
220
+ entities: []
221
+ repositories: []
222
+ linked_docs: [] # [[usecase]], [[domain-model#section]]
223
+ estimated_hours: [number]
224
+ tags: []
225
+ ---
226
+ ```
227
+
228
+ Required sections: Context (2-3 sentences with wikilink to spec), Acceptance Criteria
229
+ (checkboxes, all verifiable by command), Implementation Notes (optional hints),
230
+ Non-go (what is explicitly NOT in scope for this task)
231
+
232
+ ---
233
+
234
+ ### `tasks/_index.md` — Task Board
235
+
236
+ ```yaml
237
+ ---
238
+ type: task-board
239
+ feature: [slug]
240
+ tags: []
241
+ ---
242
+ ```
243
+
244
+ Required: table with columns: ID | Title | Package | Status | Priority | Depends On | Est.Hours
245
+ Sorted by priority ascending. Status uses emoji: ⬜ ready | 🔄 in-progress | 🚫 blocked | ✅ done
246
+
247
+ ---
248
+
249
+ ## Wikilink Conventions
250
+
251
+ ```markdown
252
+ [[_index]] # pitch digest
253
+ [[domain-model]] # full domain model doc
254
+ [[domain-model#Aggregate-Order]] # specific section
255
+ [[ux-behavior#CheckoutScreen]] # specific screen
256
+ [[usecases/UC-CreateOrder]] # specific use case
257
+ [[usecases/_index]] # use case index
258
+ [[integration]] # integration map
259
+ ```
260
+
261
+ Always use wikilinks (double brackets), never relative paths like `../domain-model.md`.
262
+
263
+ **Tier-direction rule.** Persisted links flow **LOCAL → SHARED only**:
264
+
265
+ - A LOCAL task file must **fully anchor** into the committed spec — `use_case_refs`
266
+ (single-anchor rule), `linked_docs`, and the Context wikilink. spec-lint flags a task
267
+ with an empty or unresolvable anchor as a red `UC-ANCHOR` finding.
268
+ - A SHARED spec doc links only its committed siblings (the list above) and **never**
269
+ `[[tasks/...]]`: task ids are machine-local (boards regenerate and renumber) and
270
+ `.shapeup/` is gitignored, so a committed task link dangles on every fresh clone.
271
+ spec-lint flags it as a red `TIER-DIRECTION` finding. Coverage views (synthesis
272
+ traceability) record derived counts/status, not task ids.
273
+ - `[[tasks/...]]` wikilinks are valid only inside LOCAL documents (task files, the board,
274
+ EVAL reports), where they resolve against the LOCAL root (`.shapeup/<slug>/`);
275
+ every wikilink in a SHARED doc stays `spec_folder`-relative.