@antoneeo/agentic-sdlc-skill 1.35.0 → 1.37.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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agentic-sdlc
3
- version: 1.35.0
3
+ version: 1.37.0
4
4
  description: Documentation-First SDLC protocol with risk-proportional triage, Vision as a guide, a complete Standalone mode and optional symbiosis with devPNT. Use for features, significant bugs, refactors, audits and documented maintenance.
5
5
  author: Antonio Pinto (https://github.com/Antoneeo)
6
6
  copyright: (c) 2026 Antonio Pinto
@@ -20,7 +20,7 @@ Support files in the skill directory:
20
20
  - `vision.md`: how to write a Vision a cold reviewer can actually apply — the properties that make a rule hold, the minimum operable sections, and the blind check run before promoting one to APPROVED.
21
21
  - `hybrid.md`: the devPNT seam — the authoritative hierarchy, the ownership matrix (who owns what when both authorities are live), the triage equivalence, the feature-state mapping and the shadow discipline. Read it when the `devpnt_*` tools point at this project; a Standalone session never needs it.
22
22
  - `routing.md`: which lens owns this unit of work. Read ONLY when a sibling lens skill is installed alongside this one; a single-lens install never reads it.
23
- - `scripts/sdlc_check.py` + `scripts/sdlc_core.py`: the mechanical validator for the docs root (`check`, `validate`, `index`, `stale`, `mark`, `benefit`, `gate`, `plan`, `orient`, `migrate`). Keep the entry point, `scripts/sdlc_core.py` and `scripts/knowledge.py` together; the last supplies common memory and KB integrity.
23
+ - `scripts/sdlc_check.py` + `scripts/sdlc_core.py`: the mechanical validator for the docs root (`check`, `validate`, `index`, `stale`, `mark`, `benefit`, `gate`, `plan`, `orient`, `migrate`). Keep the entry point, `scripts/sdlc_core.py` and `scripts/knowledge.py` together; the last supplies common memory and KB integrity.
24
24
  - `ENFORCEMENT.md`: optional setup for CI and hooks.
25
25
 
26
26
  Read these files only when needed. `SKILL.md` is the operating contract; the support files are progressive resources.
@@ -37,15 +37,15 @@ Read these files only when needed. `SKILL.md` is the operating contract; the sup
37
37
 
38
38
  If a patch looks easy but you do not understand why the current code is shaped the way it is, investigate first.
39
39
 
40
- ## Shared project memory
41
-
42
- Project memory is available by default, independently of installed sibling lenses.
43
- Read `memory.md` for the common consult/capture contract during orientation and
44
- closure. Use `recall` for cross-domain discovery; `index` registers original guides,
45
- plans and decisions without copying them. One owner still governs each unit.
46
- The validator now ships as three files: entry point, `sdlc_core.py`, `knowledge.py`.
47
-
48
- ## Rule Zero: Triage
40
+ ## Shared project memory
41
+
42
+ Project memory is available by default, independently of installed sibling lenses.
43
+ Read `memory.md` for the common consult/capture contract during orientation and
44
+ closure. Use `recall` for cross-domain discovery; `index` registers original guides,
45
+ plans and decisions without copying them. One owner still governs each unit.
46
+ The validator now ships as three files: entry point, `sdlc_core.py`, `knowledge.py`.
47
+
48
+ ## Rule Zero: Triage
49
49
 
50
50
  Always classify the request before choosing the process. Declare the chosen level to the user when you start operational work.
51
51
 
@@ -59,11 +59,12 @@ Always classify the request before choosing the process. Declare the chosen leve
59
59
  | **Spike** | Time-boxed exploration to reduce uncertainty | Code not mergeable into main. Outcome in `ai_docs/solutions/SPIKE_[topic].md`. For production, reclassify as L2 or L3. |
60
60
 
61
61
  Cross-cutting rules:
62
- - **Domain routing (multi-lens installs only).** After the level is set, and only when a sibling lens skill of this family is installed (`kb-agentic`, `mkt-agentic-sdlc`), run the router in `routing.md` for every L2, L3 and Spike: it decides which lens's method and validation rules govern this unit of work. L1 never reaches it, and a single-lens install never reads the file — detection fails open. In such a project, never refer to a document whose meaning differs by lens ("threat model", "vision", `principles.md`, `handoff.md`) by its bare name: qualify it with its domain, or name its path.
62
+ - **Domain routing (multi-lens installs only).** After the level is set, and only when a sibling lens skill of this family is installed (`kb-agentic`, `mkt-agentic-sdlc`, `course-creator`), run the router in `routing.md` for every L2, L3 and Spike: it decides which lens's method and validation rules govern this unit of work. L1 never reaches it, and a single-lens install never reads the file — detection fails open. In such a project, never refer to a document whose meaning differs by lens ("threat model", "vision", `principles.md`, `handoff.md`) by its bare name: qualify it with its domain, or name its path.
63
63
  - Parsing of external input, authN/authZ, cryptography, networking, personal data and filesystem access are security-sensitive: never L1.
64
64
  - If a bigger impact emerges during L1/L2 work, stop, reclassify and declare it.
65
65
  - When in doubt, pick the higher level.
66
- - **Before asking the user anything — any phase, any level — the question must pass the legality test: search first and name the search with its result; name the decision or fact blocked without the answer.** Blocking the work is the exception, not the default. `elicitation.md` §The question discipline owns the rule and is the only place it is stated — read it before you ask, and do not work from a summary of it.
66
+ - For L2/L3 bugs, load `debugging.md` at the start of analysis, before proposing a cause or fix: incident evidence, ranked hypotheses and causal verification precede correction.
67
+ - **A real doubt is asked when it emerges, before its answer is written — any phase, any level; a question is legal only after naming the search with its result and the decision it blocks.** `elicitation.md` §The question discipline owns the rule — what is a real doubt, the pros-and-cons weighing, the form — and is the only place it is stated: read it before you ask or assume, and do not work from a summary of it.
67
68
  - The full audit does not start for L1/L2 unless explicitly requested.
68
69
 
69
70
  Triage rationalizations — the thought on the left is the signal to STOP and re-triage:
@@ -204,7 +205,7 @@ Hybrid L3:
204
205
  - Implementation work follows the TDD discipline in `tdd.md` (RED/GREEN/REFACTOR — the L2/L3 default; record the reason when it does not apply).
205
206
  - Before implementing (L2/L3; L1 exempt), **consult the guide router** — the verdict already declared with the triage level (`## Operative Guides`). Re-run the lookup here only if the work has moved to a topic the first one did not cover, and say so if the verdict changes.
206
207
  - If the environment does not allow automated tests, declare the alternative verification and the reason.
207
- - For bugs (L2/L3), follow the systematic debugging method in `debugging.md`.
208
+ - For bugs (L2/L3), continue the investigation and design-verification method in `debugging.md`; implementation follows the `tdd.md` discipline above.
208
209
  - Circuit breaker: after 3 consecutive runs without progress on the tests, stop, switch to the systematic method in `debugging.md`, and ask for instructions if still stuck. `debugging.md` also covers **chronic fragility** — a component that breaks repeatedly across sessions is a comprehension + complexity signal (write the `source_kind: code` guide AND escalate a refactor), not a fourth patch.
209
210
  - Update the ANALYSIS Diary or the Action Plan when you complete milestones, hit blockers, change decisions, or a session ends with work unfinished.
210
211
  - **Opt-in subagent execution**: for an L3 with an approved design, the orchestrator MAY execute the work via subagents per `dispatch.md`, gated by `sdlc_check.py plan validate` ("no valid plan, no dispatch"); default stays same-session. Hybrid: the executable `PLAN_[feature].md` is `derived-from` the accepted E-TDD, never independently authored. `dispatch.md` also carries the family-wide **delegation boundary** (what may be delegated at all, and what never may) — that section is not gated by the opt-in trigger and applies at any level, dispatch or no dispatch.
@@ -1,215 +1,215 @@
1
- # The Architect Pass
2
-
3
- Applies at L3, in phase 3, AFTER the spec elicitation and BEFORE the Impact is
4
- drafted. It answers the one question the Impact cannot ask: *does the system
5
- already have the components and services this feature needs?*
6
-
7
- Why it exists: **a feature is not a unit of construction.** Left alone, an agent
8
- designs the feature and builds whatever it lacks inside the feature's own code
9
- path — so no component owns the capability, the next feature that needs it
10
- rebuilds it differently, and the platform accretes feature-shaped code nobody can
11
- reuse. That is myopia one level above the file: the change is complete, the tests
12
- pass, and the architecture is worse.
13
-
14
- ## 1. State the feature as capabilities, not as files
15
-
16
- Write what the system must be able to DO for this feature to exist — "persist a
17
- draft across sessions", "notify a third party asynchronously", "authorize per
18
- tenant". A capability is a verb over a domain noun. It names no file, no class and
19
- no library: **that** is the decoupling. Files come later, in the Impact.
20
-
21
- Two or three capabilities is a normal feature. When the list has one obvious entry
22
- and it plainly exists, say so in one line **under the `## Capability Ledger`
23
- heading, still naming the component and where it lives**, and move on — this pass
24
- is a question to answer, not a form to fill. The heading is what makes a cheap
25
- answer distinguishable from a skipped pass; a bare "everything already exists"
26
- names nothing and is the **Paper ledger** anti-pattern, not the licence.
27
-
28
- ## 2. Rule each capability against the platform
29
-
30
- One verdict per capability:
31
-
32
- | Verdict | Meaning | What the row must carry |
33
- |---|---|---|
34
- | **EXISTS** | a component already owns this capability and covers the need | the component, where it lives (path / symbol), and the one guarantee you re-read it to confirm |
35
- | **INADEQUATE** | a component owns it but does not cover the need | the same, plus the gap in one line |
36
- | **MISSING** | no component owns it | the terms you searched, the tool, and the areas covered |
37
-
38
- Read the **`## Component Map`** in `strategic/architecture.md` first — the project's
39
- inventory of what owns which capability, kept so this pass does not re-derive the
40
- platform from source every session.
41
-
42
- **The map is a cache of evidence somebody already paid for. It lowers the COST of a
43
- verdict, never the STANDARD of one.** Every verdict carries the same evidence
44
- whether the map answered it or not; a hit means the search is already written down,
45
- a miss means you pay full price. Reading a row does not excuse you from checking
46
- that it is still true — the map is the index, the code is the evidence.
47
-
48
- **Its silence is unread, not empty.** The map covers only the areas `audit/
49
- audit_plan.md` marks ANALYZED — and that state is a claim someone made, not a fact
50
- the tooling verified: marking asserts *the area was read closely enough to name the
51
- capabilities it owns*, so an area marked after two greps is a false ANALYZED and
52
- the person who wrote it owns the duplicate that follows. In an area still PENDING —
53
- or SKIPPED, or absent from the plan entirely — **the map can never ground a MISSING
54
- verdict.** Nothing there has been looked at yet, and "the inventory does not mention
55
- it" is the reasoning that builds a second copy of a component that already exists.
56
-
57
- **Searching for an owner** is text search first, symbol-graph second — in that
58
- order, because you are looking for a name you do not know yet, and a call-hierarchy
59
- tool needs a resolved symbol as *input*. Grep the repository (minus SKIPPED areas)
60
- for the domain noun, at least two plausible synonyms, and the verb; then use the
61
- symbol-graph tool to confirm or dismiss the candidates the search surfaced.
62
-
63
- **The floor for a MISSING** is about triage, not term count: every hit that lands in
64
- an unmapped area gets opened, or the MISSING is **provisional** and says so in its
65
- row. Record what you ran — terms, tool, areas — and stop when the terms are
66
- exhausted and no candidate remains unopened. A provisional MISSING is honest and
67
- cheap; an unfalsifiable one is the same defect as an EXISTS with no symbol named.
68
-
69
- **Understanding is never deferred; only WRITING the map is.** You may leave the rest
70
- of the repository unmapped and grow the inventory feature by feature — you may not
71
- leave unexamined anything this change touches or depends on. That blast zone is
72
- understood now, at full standard, mapped or not. The incremental licence is about
73
- the artifact, never about the comprehension.
74
-
75
- Ground every verdict. An EXISTS with no named symbol is an assumption wearing a
76
- verdict's clothes, and it is the row that breaks in implementation. A MISSING
77
- declared without a real search is how duplication enters — the component may be
78
- there under a name you did not guess. This is the DRY check at architecture level.
79
-
80
- ## 3. Design what is missing as a component, not as feature internals
81
-
82
- INADEQUATE and MISSING produce design work of their own, governed by one rule:
83
-
84
- **The component's contract is stated in the component's own vocabulary. The feature
85
- is one consumer, never the owner.**
86
-
87
- The test is mechanical: write the contract — what it does, what it takes, what it
88
- guarantees — *without naming the feature*. If you cannot, the contract is
89
- feature-shaped, and the second consumer will force it open. **Renaming the
90
- feature's nouns is not stating the contract in the component's vocabulary**:
91
- `store(ConfirmationPayload) -> id` described as "stores records by id" still fails.
92
- The question the wording cannot dodge — *would a second plausible consumer have to
93
- change this signature?* If yes it is feature-shaped, however it is phrased.
94
-
95
- The opposite error is equally real: this is not a licence to build a framework.
96
- Build for the need you have, at the size you need. What the rule constrains is the
97
- contract's **vocabulary and ownership**, not its scope — a five-line component with
98
- a clean contract satisfies it in full.
99
-
100
- ## 4. Decide the unit of change
101
-
102
- A capability that needs building becomes **its own ANALYSIS, its own branch and its
103
- own closure** when ANY of these holds:
104
-
105
- - it will have more than one consumer, now or in the declared roadmap;
106
- - **it can ship before this feature does** — merged and adopted on its own cadence,
107
- with the feature still unfinished. (Not "buildable and testable on its own": §3
108
- requires that of every component, so reading it that way makes the default branch
109
- below unreachable and puts every five-line helper through its own L3.) IN: a
110
- storage layer another team can adopt next sprint while this feature is still in
111
- design. OUT: a helper nobody can use until the feature that motivated it lands;
112
- - it carries its own risk surface: security, a public contract, a data model, or a
113
- new dependency.
114
-
115
- Otherwise it is a **phase inside this feature's plan** — the first phase, before the
116
- feature consumes it — and it is still a component: own contract, own tests, never
117
- inlined into the feature's code path. **The split rule decides the paperwork; it
118
- never decides whether the component exists.**
119
-
120
- When it does become its own unit, each document names the other: the feature's
121
- ANALYSIS points at the component's, and the component's lists its consumers.
122
-
123
- ## 5. Order
124
-
125
- The component is designed before the feature that consumes it, and normally built
126
- and tested before it too. A feature blocked on a capability it does not have is not
127
- "in progress" — it is a component task wearing a feature's name.
128
-
129
- ## Anti-patterns
130
-
131
- - **Inlining** — the capability is implemented inside the feature's code path and no
132
- component owns it. Symptom: the next feature that needs it must copy it or
133
- refactor yours. This is the failure the pass exists to prevent.
134
- - **Feature-shaped platform** — the component exists, but its contract speaks the
135
- feature's vocabulary. Symptom: the second consumer forces a contract change.
136
- - **Silent degradation** — a capability comes out MISSING, nobody wants to build it,
137
- so the feature is quietly reshaped around what exists and ships as less than what
138
- was asked. The reduced benefit must be surfaced to the user as a scope change and
139
- recorded in the ANALYSIS; absorbing it silently is the Vision-divergence rule
140
- broken one level down.
141
- - **Speculative platform** — a general framework built for a single known need.
142
- - **Paper ledger** — every row EXISTS, nothing named. Unfalsifiable, exactly like a
143
- review that reports "I checked".
144
- - **Empty-map MISSING** — ruling a capability MISSING because the Component Map is
145
- silent about it, in an area nobody has analyzed yet. The map's silence is
146
- *unread*, not *empty*. On a project the methodology has just arrived in, the map
147
- is nearly all silence, and this is the anti-pattern that duplicates the existing
148
- codebase one component at a time.
149
-
150
- ## Where the output is recorded
151
-
152
- Standalone: the `## Capability Ledger` section of the ANALYSIS (`templates.md`),
153
- immediately before `## Impact`, which it feeds — every INADEQUATE or MISSING row
154
- lands there as files to create or change. The closure review maps the ledger row by
155
- row (`review.md`).
156
-
157
- **A component that gets built lands in the `## Component Map`** of
158
- `strategic/architecture.md`, in the same closure — capability owned, contract,
159
- where it lives. This is the loop that makes the pass repeatable instead of
160
- per-session: the ledger asks the map what exists, so a component the map never
161
- learned about is one the next feature rules MISSING and builds a second time. The
162
- trigger is the component's birth, not a stack change (Write Triggers).
163
-
164
- **So does a component you merely discovered.** When the pass searches an unmapped
165
- area and finds an existing owner, write that row too, then `sdlc_check.py mark` the
166
- area you covered — **in that order, and never the mark without the rows.** Marking
167
- an area ANALYZED while its owners stay unwritten is the worst of both states: the
168
- area now looks read, so the map's silence there becomes groundable, and the next
169
- feature rules MISSING and builds a duplicate — lawfully. What a mark asserts is
170
- exactly this: *the area was read closely enough to name the capabilities it owns.*
171
- The map then grows by the feature that needed the knowledge instead of by an
172
- up-front sweep — the understanding was paid for either way, and this is the step
173
- that stops the next session paying for it again.
174
-
175
- Hybrid: the ledger goes in the `E-ISP`, above its Impacted Components map. A
176
- capability split out as its own unit of change gets its own `E-ISP`/`E-TDD`, and the
177
- feature's `E-ISP` names it as a dependency.
178
-
179
- ## Mechanical backstops
180
-
181
- Prose is not enforcement; these are the checks that notice when the pass did not
182
- run or its output rotted. Both are **advisories** — printed as `[note]`, never
183
- counted as warnings, and never failing a build, **not even under `--strict`**. That
184
- is deliberate: the ceremony budget accepted for this pass was a signal, and a
185
- warning that reddens a pipeline is a gate under another name.
186
-
187
- - **Skipped pass**: `validate` notes an L3 ANALYSIS started on/after 2026-07-28
188
- that lacks `## Capability Ledger`. Grandfathered by `start_date` alone —
189
- analyses born before the pass existed never nag — and deliberately NOT by
190
- status: closure flips the ANALYSIS to COMPLETED *before* `check` runs, so a
191
- status filter would silence the backstop at the exact moment the process
192
- mandates the validator.
193
- - **Rotting map**: `validate` resolves every path-shaped ref in the Component
194
- Map's `Where` column — a path that no longer exists, or a `#symbol` no longer
195
- present as a whole word in the file, is flagged; so is a map whose rows carry
196
- no checkable path at all, or whose header has no `Where` column (an inert check
197
- reported as a clean one is the same defect as an unread map reported as empty).
198
- This is the map's equivalent of the guides' `source_hash`, with the same honest
199
- limit: it proves the ref resolves, never that the row still describes the
200
- component correctly.
201
- - **A mark nobody paid for**: `validate` notes an area the audit plan marks
202
- ANALYZED that owns no Component Map row. Marking is one cheap command and it is
203
- what converts the map's silence into a groundable MISSING — so this is the other
204
- half of the loop, the check that a mark asserted something real.
205
- - **Adherence** (non-gating, **skill development only** — `evals/` is not shipped
206
- in the installed package): `architect_rules_before_impact.md` runs the pass
207
- cold; `unmapped_never_grounds_missing.md` sets the brownfield trap — an existing
208
- component in a PENDING area, where ruling MISSING from the map's silence is the
209
- failure.
210
-
211
- ## Below L3
212
-
213
- L1 and L2 do not run this pass. A capability discovered MISSING during L2 work is
214
- itself an escalation trigger: stop, reclassify to L3, declare it (Rule Zero). "The
215
- component was not there" is never a reason to build it inside an L2.
1
+ # The Architect Pass
2
+
3
+ Applies at L3, in phase 3, AFTER the spec elicitation and BEFORE the Impact is
4
+ drafted. It answers the one question the Impact cannot ask: *does the system
5
+ already have the components and services this feature needs?*
6
+
7
+ Why it exists: **a feature is not a unit of construction.** Left alone, an agent
8
+ designs the feature and builds whatever it lacks inside the feature's own code
9
+ path — so no component owns the capability, the next feature that needs it
10
+ rebuilds it differently, and the platform accretes feature-shaped code nobody can
11
+ reuse. That is myopia one level above the file: the change is complete, the tests
12
+ pass, and the architecture is worse.
13
+
14
+ ## 1. State the feature as capabilities, not as files
15
+
16
+ Write what the system must be able to DO for this feature to exist — "persist a
17
+ draft across sessions", "notify a third party asynchronously", "authorize per
18
+ tenant". A capability is a verb over a domain noun. It names no file, no class and
19
+ no library: **that** is the decoupling. Files come later, in the Impact.
20
+
21
+ Two or three capabilities is a normal feature. When the list has one obvious entry
22
+ and it plainly exists, say so in one line **under the `## Capability Ledger`
23
+ heading, still naming the component and where it lives**, and move on — this pass
24
+ is a question to answer, not a form to fill. The heading is what makes a cheap
25
+ answer distinguishable from a skipped pass; a bare "everything already exists"
26
+ names nothing and is the **Paper ledger** anti-pattern, not the licence.
27
+
28
+ ## 2. Rule each capability against the platform
29
+
30
+ One verdict per capability:
31
+
32
+ | Verdict | Meaning | What the row must carry |
33
+ |---|---|---|
34
+ | **EXISTS** | a component already owns this capability and covers the need | the component, where it lives (path / symbol), and the one guarantee you re-read it to confirm |
35
+ | **INADEQUATE** | a component owns it but does not cover the need | the same, plus the gap in one line |
36
+ | **MISSING** | no component owns it | the terms you searched, the tool, and the areas covered |
37
+
38
+ Read the **`## Component Map`** in `strategic/architecture.md` first — the project's
39
+ inventory of what owns which capability, kept so this pass does not re-derive the
40
+ platform from source every session.
41
+
42
+ **The map is a cache of evidence somebody already paid for. It lowers the COST of a
43
+ verdict, never the STANDARD of one.** Every verdict carries the same evidence
44
+ whether the map answered it or not; a hit means the search is already written down,
45
+ a miss means you pay full price. Reading a row does not excuse you from checking
46
+ that it is still true — the map is the index, the code is the evidence.
47
+
48
+ **Its silence is unread, not empty.** The map covers only the areas `audit/
49
+ audit_plan.md` marks ANALYZED — and that state is a claim someone made, not a fact
50
+ the tooling verified: marking asserts *the area was read closely enough to name the
51
+ capabilities it owns*, so an area marked after two greps is a false ANALYZED and
52
+ the person who wrote it owns the duplicate that follows. In an area still PENDING —
53
+ or SKIPPED, or absent from the plan entirely — **the map can never ground a MISSING
54
+ verdict.** Nothing there has been looked at yet, and "the inventory does not mention
55
+ it" is the reasoning that builds a second copy of a component that already exists.
56
+
57
+ **Searching for an owner** is text search first, symbol-graph second — in that
58
+ order, because you are looking for a name you do not know yet, and a call-hierarchy
59
+ tool needs a resolved symbol as *input*. Grep the repository (minus SKIPPED areas)
60
+ for the domain noun, at least two plausible synonyms, and the verb; then use the
61
+ symbol-graph tool to confirm or dismiss the candidates the search surfaced.
62
+
63
+ **The floor for a MISSING** is about triage, not term count: every hit that lands in
64
+ an unmapped area gets opened, or the MISSING is **provisional** and says so in its
65
+ row. Record what you ran — terms, tool, areas — and stop when the terms are
66
+ exhausted and no candidate remains unopened. A provisional MISSING is honest and
67
+ cheap; an unfalsifiable one is the same defect as an EXISTS with no symbol named.
68
+
69
+ **Understanding is never deferred; only WRITING the map is.** You may leave the rest
70
+ of the repository unmapped and grow the inventory feature by feature — you may not
71
+ leave unexamined anything this change touches or depends on. That blast zone is
72
+ understood now, at full standard, mapped or not. The incremental licence is about
73
+ the artifact, never about the comprehension.
74
+
75
+ Ground every verdict. An EXISTS with no named symbol is an assumption wearing a
76
+ verdict's clothes, and it is the row that breaks in implementation. A MISSING
77
+ declared without a real search is how duplication enters — the component may be
78
+ there under a name you did not guess. This is the DRY check at architecture level.
79
+
80
+ ## 3. Design what is missing as a component, not as feature internals
81
+
82
+ INADEQUATE and MISSING produce design work of their own, governed by one rule:
83
+
84
+ **The component's contract is stated in the component's own vocabulary. The feature
85
+ is one consumer, never the owner.**
86
+
87
+ The test is mechanical: write the contract — what it does, what it takes, what it
88
+ guarantees — *without naming the feature*. If you cannot, the contract is
89
+ feature-shaped, and the second consumer will force it open. **Renaming the
90
+ feature's nouns is not stating the contract in the component's vocabulary**:
91
+ `store(ConfirmationPayload) -> id` described as "stores records by id" still fails.
92
+ The question the wording cannot dodge — *would a second plausible consumer have to
93
+ change this signature?* If yes it is feature-shaped, however it is phrased.
94
+
95
+ The opposite error is equally real: this is not a licence to build a framework.
96
+ Build for the need you have, at the size you need. What the rule constrains is the
97
+ contract's **vocabulary and ownership**, not its scope — a five-line component with
98
+ a clean contract satisfies it in full.
99
+
100
+ ## 4. Decide the unit of change
101
+
102
+ A capability that needs building becomes **its own ANALYSIS, its own branch and its
103
+ own closure** when ANY of these holds:
104
+
105
+ - it will have more than one consumer, now or in the declared roadmap;
106
+ - **it can ship before this feature does** — merged and adopted on its own cadence,
107
+ with the feature still unfinished. (Not "buildable and testable on its own": §3
108
+ requires that of every component, so reading it that way makes the default branch
109
+ below unreachable and puts every five-line helper through its own L3.) IN: a
110
+ storage layer another team can adopt next sprint while this feature is still in
111
+ design. OUT: a helper nobody can use until the feature that motivated it lands;
112
+ - it carries its own risk surface: security, a public contract, a data model, or a
113
+ new dependency.
114
+
115
+ Otherwise it is a **phase inside this feature's plan** — the first phase, before the
116
+ feature consumes it — and it is still a component: own contract, own tests, never
117
+ inlined into the feature's code path. **The split rule decides the paperwork; it
118
+ never decides whether the component exists.**
119
+
120
+ When it does become its own unit, each document names the other: the feature's
121
+ ANALYSIS points at the component's, and the component's lists its consumers.
122
+
123
+ ## 5. Order
124
+
125
+ The component is designed before the feature that consumes it, and normally built
126
+ and tested before it too. A feature blocked on a capability it does not have is not
127
+ "in progress" — it is a component task wearing a feature's name.
128
+
129
+ ## Anti-patterns
130
+
131
+ - **Inlining** — the capability is implemented inside the feature's code path and no
132
+ component owns it. Symptom: the next feature that needs it must copy it or
133
+ refactor yours. This is the failure the pass exists to prevent.
134
+ - **Feature-shaped platform** — the component exists, but its contract speaks the
135
+ feature's vocabulary. Symptom: the second consumer forces a contract change.
136
+ - **Silent degradation** — a capability comes out MISSING, nobody wants to build it,
137
+ so the feature is quietly reshaped around what exists and ships as less than what
138
+ was asked. The reduced benefit must be surfaced to the user as a scope change and
139
+ recorded in the ANALYSIS; absorbing it silently is the Vision-divergence rule
140
+ broken one level down.
141
+ - **Speculative platform** — a general framework built for a single known need.
142
+ - **Paper ledger** — every row EXISTS, nothing named. Unfalsifiable, exactly like a
143
+ review that reports "I checked".
144
+ - **Empty-map MISSING** — ruling a capability MISSING because the Component Map is
145
+ silent about it, in an area nobody has analyzed yet. The map's silence is
146
+ *unread*, not *empty*. On a project the methodology has just arrived in, the map
147
+ is nearly all silence, and this is the anti-pattern that duplicates the existing
148
+ codebase one component at a time.
149
+
150
+ ## Where the output is recorded
151
+
152
+ Standalone: the `## Capability Ledger` section of the ANALYSIS (`templates.md`),
153
+ immediately before `## Impact`, which it feeds — every INADEQUATE or MISSING row
154
+ lands there as files to create or change. The closure review maps the ledger row by
155
+ row (`review.md`).
156
+
157
+ **A component that gets built lands in the `## Component Map`** of
158
+ `strategic/architecture.md`, in the same closure — capability owned, contract,
159
+ where it lives. This is the loop that makes the pass repeatable instead of
160
+ per-session: the ledger asks the map what exists, so a component the map never
161
+ learned about is one the next feature rules MISSING and builds a second time. The
162
+ trigger is the component's birth, not a stack change (Write Triggers).
163
+
164
+ **So does a component you merely discovered.** When the pass searches an unmapped
165
+ area and finds an existing owner, write that row too, then `sdlc_check.py mark` the
166
+ area you covered — **in that order, and never the mark without the rows.** Marking
167
+ an area ANALYZED while its owners stay unwritten is the worst of both states: the
168
+ area now looks read, so the map's silence there becomes groundable, and the next
169
+ feature rules MISSING and builds a duplicate — lawfully. What a mark asserts is
170
+ exactly this: *the area was read closely enough to name the capabilities it owns.*
171
+ The map then grows by the feature that needed the knowledge instead of by an
172
+ up-front sweep — the understanding was paid for either way, and this is the step
173
+ that stops the next session paying for it again.
174
+
175
+ Hybrid: the ledger goes in the `E-ISP`, above its Impacted Components map. A
176
+ capability split out as its own unit of change gets its own `E-ISP`/`E-TDD`, and the
177
+ feature's `E-ISP` names it as a dependency.
178
+
179
+ ## Mechanical backstops
180
+
181
+ Prose is not enforcement; these are the checks that notice when the pass did not
182
+ run or its output rotted. Both are **advisories** — printed as `[note]`, never
183
+ counted as warnings, and never failing a build, **not even under `--strict`**. That
184
+ is deliberate: the ceremony budget accepted for this pass was a signal, and a
185
+ warning that reddens a pipeline is a gate under another name.
186
+
187
+ - **Skipped pass**: `validate` notes an L3 ANALYSIS started on/after 2026-07-28
188
+ that lacks `## Capability Ledger`. Grandfathered by `start_date` alone —
189
+ analyses born before the pass existed never nag — and deliberately NOT by
190
+ status: closure flips the ANALYSIS to COMPLETED *before* `check` runs, so a
191
+ status filter would silence the backstop at the exact moment the process
192
+ mandates the validator.
193
+ - **Rotting map**: `validate` resolves every path-shaped ref in the Component
194
+ Map's `Where` column — a path that no longer exists, or a `#symbol` no longer
195
+ present as a whole word in the file, is flagged; so is a map whose rows carry
196
+ no checkable path at all, or whose header has no `Where` column (an inert check
197
+ reported as a clean one is the same defect as an unread map reported as empty).
198
+ This is the map's equivalent of the guides' `source_hash`, with the same honest
199
+ limit: it proves the ref resolves, never that the row still describes the
200
+ component correctly.
201
+ - **A mark nobody paid for**: `validate` notes an area the audit plan marks
202
+ ANALYZED that owns no Component Map row. Marking is one cheap command and it is
203
+ what converts the map's silence into a groundable MISSING — so this is the other
204
+ half of the loop, the check that a mark asserted something real.
205
+ - **Adherence** (non-gating, **skill development only** — `evals/` is not shipped
206
+ in the installed package): `architect_rules_before_impact.md` runs the pass
207
+ cold; `unmapped_never_grounds_missing.md` sets the brownfield trap — an existing
208
+ component in a PENDING area, where ruling MISSING from the map's silence is the
209
+ failure.
210
+
211
+ ## Below L3
212
+
213
+ L1 and L2 do not run this pass. A capability discovered MISSING during L2 work is
214
+ itself an escalation trigger: stop, reclassify to L3, declare it (Rule Zero). "The
215
+ component was not there" is never a reason to build it inside an L2.