@antoneeo/kb-agentic-skill 1.0.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.
@@ -0,0 +1,80 @@
1
+ # The Knowledge Taxonomy Pass — placing a claim in the topic graph
2
+
3
+ **For whom**: the agent holding extracted claims (`distillation.md`) that need a home.
4
+ **Answers**: "which node owns this concept, and what do I do when none does".
5
+ **Does not answer**: how claims are extracted (below — `distillation.md`) or what happens
6
+ when two claims disagree (below — `reconciliation.md`).
7
+
8
+ Why it exists: **a fact placed twice is a fact that will diverge.** Left alone, an agent
9
+ creates a new topic for every document it reads, no node owns the authoritative concept,
10
+ and the base accretes near-duplicates that answer the same question differently.
11
+
12
+ ## 0. The graph, in one paragraph
13
+
14
+ `topics/<slug>.md`, one file per topic, **flat** — hierarchy lives in `parents:`
15
+ (a list: a topic may sit under several), never in the path, so inserting a parent above
16
+ ten existing nodes is an edit, not a file move. The graph grows **upward as well as
17
+ downward**. `topics/INDEX.md` (generated) is the router: slug, description, parents,
18
+ synonyms. Coverage state does not exist — `gaps:` inside a node says what that node
19
+ knows is missing, and nothing collects it.
20
+
21
+ ## 1. Descend, do not scan
22
+
23
+ Placement is semantic judgement; no query performs it. What makes it affordable is the
24
+ abstraction hierarchy: read the top-level rows of `topics/INDEX.md`, pick the branch
25
+ whose description covers the claim's concept, repeat. Follow **every** parent listed —
26
+ a topic can be legitimately reachable from two branches, and descending only one is how
27
+ a duplicate gets created while the rules are obeyed. Synonyms are in the index precisely
28
+ so "listino" finds `pricing`. Open only the final candidates.
29
+
30
+ During a batch, the candidate set **includes what this run already created** — held in
31
+ memory, rebuilt at start by reading `topics/*.md` frontmatter (the files are the state;
32
+ a crash loses nothing a directory read does not restore). `topics/INDEX.md` is written
33
+ once, by `sdlc_check.py index`, at the end — never hand-appended mid-run.
34
+
35
+ ## 2. Five verdicts
36
+
37
+ | Verdict | When | Action |
38
+ |---|---|---|
39
+ | **EXISTS** | a node owns the concept | reconcile the claim into it (`reconciliation.md`) |
40
+ | **INADEQUATE** | a node covers the area, the claim is finer-grained | deepen it, or create a child under it |
41
+ | **MISSING** | no node covers it | create under the nearest more-general node: slug, one-line `description:`, `parents:` |
42
+ | **GENERALIZES** | the concept sits **above** existing nodes | an **escalation trigger** — see §4 |
43
+ | **UNPLACED** | about no topic (document metadata, a signature, a procurement window) | `topics/unplaced.md` — a holding pen; nothing ranks or counts it |
44
+
45
+ **MISSING may only be declared after querying the graph.** An unread index can never
46
+ ground a MISSING verdict — otherwise the same thing gets built twice. The mechanical
47
+ side (double-owner check, near-duplicate warning) verifies afterwards; it does not
48
+ replace the descent.
49
+
50
+ ## 3. Similar but perhaps not the same → sibling, never a merge
51
+
52
+ Create the node at the same level, set `related: <existing-slug>`, and write **one line
53
+ stating the distinction** ("distinct from `pricing` because it covers negotiated
54
+ exceptions, not list prices"). If that line cannot be written, they are the same concept
55
+ — go to reconciliation instead.
56
+
57
+ Why this direction: over-merging is the harmful error. One wrong merge contaminates
58
+ both topics' claims and propagates through every reference; a redundant sibling costs a
59
+ later merge. The deferral is only correct because merging **does** happen later: the
60
+ **canonicalization pass** — run at closure, or when the near-duplicate warning fires —
61
+ revisits `related:` pairs and either merges (tombstone the loser: `status: SUPERSEDED` +
62
+ `redirect_to:`, body emptied) or strengthens the distinction line.
63
+
64
+ ## 4. GENERALIZES escalates; re-parenting is guarded
65
+
66
+ Re-parenting rewrites the graph's shape, and kb's Rule Zero makes hierarchy changes L3
67
+ (escalation triggers, `SKILL.md`): stop, declare, and treat it as its own unit — never a
68
+ side effect of placing one claim. A GENERALIZES that would create a **new root** also
69
+ stops for the practitioner: reframing the whole base is a decision, not a placement.
70
+
71
+ Before writing `parents:`, walk the target's ancestor chain; if the node itself appears,
72
+ **refuse** — a cycle detaches a subtree, and since descent is the only retrieval path, a
73
+ detached ring is invisible forever. The validator's `graph` check reports cycles and
74
+ unreachable nodes as errors, but the refusal at write time is what prevents them.
75
+
76
+ ## 5. Tombstones, never deletion
77
+
78
+ A merged or renamed topic keeps its file: `status: SUPERSEDED`, `redirect_to: <slug>`,
79
+ body emptied. Inbound references resolve through it; a claim re-placed from an old
80
+ source lands on the survivor instead of resurrecting the dead slug.
@@ -0,0 +1,579 @@
1
+ # Document templates — KB Agentic
2
+
3
+ General rules:
4
+ - Concise documents: ≤ ~80 lines each (handoff ≤ 20). If a document grows beyond that, split it, do not inflate it.
5
+ - Template conformance is not the goal: if a section has no real content, state explicitly why it does not apply. Never filler text.
6
+ - Dates always absolute, UTC where indicated.
7
+
8
+ ## Canonical document header (vision/ reference/ architecture/ functional/ strategic/)
9
+
10
+ Every durable canonical document opens with this frontmatter: it feeds the generated manifest `ai_docs/INDEX.md` and gives an agent the freshness signal before it trusts the content.
11
+
12
+ ```markdown
13
+ ---
14
+ description: One line — what the document is and when to read it.
15
+ status: CURRENT # CURRENT | SUPERSEDED | DRAFT | DEPRECATED
16
+ supersedes: old_doc.md # only if it replaces another canonical doc
17
+ ---
18
+ # Document Title
19
+ ```
20
+
21
+ When a doc replaces another: the new one declares `supersedes:`, the old one switches to `status: SUPERSEDED` (it stays as history, do not delete it). `sdlc_check.py validate` warns if `status` is missing or if a superseded doc is still `CURRENT`.
22
+
23
+ ## ai_docs/reference/GUIDE_[topic].md
24
+
25
+ A guide is either OPERATIVE (`source_kind: document` — distilled from USER-PROVIDED
26
+ indications, "how to act") or a COMPREHENSION map (`source_kind: code` — distilled from
27
+ the project's own code, "how a complex component works"). Never from model knowledge:
28
+ every claim traces to the snapshot (a handed document, or verbatim code excerpts).
29
+ The guide is a SYNTHESIS — the compact training a reader takes in whole before acting;
30
+ the verbatim snapshot in `ai_docs/reference/.sources/<slug>-<hash8>.md` is the book,
31
+ reached on demand. `source_hash` is the snapshot's SHA-256. Every `##` section carries
32
+ a fidelity marker: `[source: <snapshot-file>#<anchor-or-line>]` for covered content
33
+ (doubling as the detail-lookup pointer into the book), or a literal
34
+ `[not covered by source]` for gaps. Sections are CHOSEN from the repertoire below —
35
+ only those the source actually supports; never force empty ones. A guide approaching
36
+ the source's own length is a paraphrase, not a synthesis.
37
+
38
+ ```markdown
39
+ ---
40
+ description: One line, ≤160 chars — when to consult this guide.
41
+ status: CURRENT
42
+ source_kind: document # document (user indications, operative) | code (comprehension map)
43
+ source: Human-readable name of what the user provided (or the component, for source_kind: code).
44
+ source_version: v1.2 # optional — only when the origin is versioned
45
+ distilled_from: ai_docs/reference/.sources/topic-a1b2c3d4.md
46
+ source_hash: <sha256 of the snapshot file>
47
+ overrides: GUIDE_topic.md # optional — only for a project guide overriding an agent-KB guide
48
+ ---
49
+ # Guide: [Topic]
50
+
51
+ ## How to do [X]
52
+ [source: topic-a1b2c3d4.md#setup]
53
+ <!-- operative steps, imperative voice -->
54
+
55
+ ## How to verify it is done right
56
+ [source: topic-a1b2c3d4.md#checks]
57
+
58
+ ## What NOT to do
59
+ [not covered by source]
60
+ <!-- the user's material does not address this: do not invent. -->
61
+ ```
62
+
63
+ Section repertoire (pick what the source supports):
64
+ - **`document` (operative):** How to do X / How to verify / What NOT to do / What to
65
+ watch out for / Core principles / When this applies.
66
+ - **`code` (comprehension):** How it works / Control & data flow / Key invariants /
67
+ Extension points / Where it breaks (failure modes) / Why it is shaped this way.
68
+ Every marker points into the code-excerpt snapshot: `[source: <slug>-<hash8>.md#path:symbol]`.
69
+
70
+ ## ai_docs/README.md
71
+
72
+ Curated must-read index, by hand (it is NOT the generated manifest). Created at init, updated rarely, only for real must-reads.
73
+
74
+ ```markdown
75
+ ---
76
+ default_domain: knowledge
77
+ ---
78
+ # ai_docs — reading guide
79
+
80
+ Must-reads for this project, in order. The full manifest of canonical docs is
81
+ `INDEX.md` (generated — regenerate with `sdlc_check.py index`, never edit by hand).
82
+
83
+ 1. `reference/INDEX.md` — the guide router: which guide already governs the work you are about to do (generated).
84
+ 2. `vision/project_vision.md` — why the project exists (check its Status first).
85
+ 3. `strategic/architecture.md` — how it is built.
86
+ 4. `audit/handoff.md` — where work stopped last session (if present).
87
+
88
+ Directory purposes: `vision/` (project direction), `strategic/` (architecture and
89
+ feature catalog), `reference/` (operative guides), `solutions/` (per-feature
90
+ analyses, discovery-by-grep), `audit/` (audit plan and handoff).
91
+ ```
92
+
93
+ ## ai_docs/vision/project_vision.md
94
+
95
+ A Vision states **the benefit to be obtained while leaving the most degrees of
96
+ freedom possible** — it binds nothing that does not obstruct that benefit (the
97
+ deletion test, `vision.md` §What-a-Vision-IS). It is *applied* as a **gate**: a
98
+ cold reader must be able to rule ACCEPT or REJECT on a proposed change, quoting
99
+ one line, without asking anyone anything. Write it against `vision.md` §1–§4 from
100
+ the first draft — the properties that make a rule survive a motivated reader are
101
+ cheap to apply while writing and expensive to retrofit. `vision.md` §6 is the
102
+ blind check that gates promotion to APPROVED.
103
+
104
+ Sections below marked **[gate]** are load-bearing for that ruling; the others are
105
+ orientation for humans. Keep the human ones — just know which is which.
106
+
107
+ ```markdown
108
+ # Project Vision
109
+ Status: DRAFT
110
+ <!-- Status: DRAFT (reconstructed by the agent, NOT a gating authority)
111
+ or APPROVED (by <who>, <date>) — only after the user's explicit confirmation
112
+ AND the blind check in vision.md §6. -->
113
+
114
+ ## North Star
115
+ <!-- [gate, partly] The BENEFIT to be obtained — what the actor gets, never the
116
+ mechanism, and never by comparison to another product (a comparative
117
+ definition rots silently when the comparison target moves). Concrete enough
118
+ that an obstacle to it is recognizable: that is what makes every Non-Goal
119
+ below derivable and refutable. Also restate here any boundary a ruling
120
+ depends on but that is defined elsewhere: risk tiers, lifecycle states,
121
+ scale levels. Routing the reader to another file breaks the cold-read
122
+ premise. -->
123
+ ## Core Problem
124
+ <!-- Human orientation: what goes wrong without this product. Carries no gate
125
+ weight unless the admission test names it. -->
126
+ ## Actors
127
+ <!-- [gate] the cast this product serves. One light line per actor:
128
+ **Role** — primary goal; good UX = what a good experience means to them.
129
+ The "good UX =" clauses are admissible work, not decoration — say so in the
130
+ admission test. Define each actor ONCE here; use-cases (Standalone) / D-UC
131
+ (Hybrid) reference them by role and never re-describe them (anti-DRY).
132
+ Proportional: a role list, not persona research. -->
133
+ ## Goals
134
+ <!-- [gate — the ACCEPT side] Each with a baseline and headroom, so "advances this"
135
+ has meaning. A goal phrased as an already-true state cannot be advanced.
136
+ Include the recurring legitimate work explicitly (packaging and installation,
137
+ the product's own tests, reducing what the agent must read, one more client) —
138
+ otherwise your own test rejects the maintenance the product needs. -->
139
+ ## Invariants
140
+ <!-- [gate] The promises that outrank everything: what the user is guaranteed, what
141
+ the architecture must always be true of. State each as ONE decision question
142
+ with BOTH branches answered, plus an anti-laundering clause naming the
143
+ re-descriptions you expect. Omit the section if the product has none. -->
144
+ ## Non-Goals
145
+ <!-- [gate — the REJECT side; this is your ENTIRE rejection surface]
146
+ Derive every rule by the deletion test: remove it — if the benefit is still
147
+ reachable, the rule does not belong (it spends a degree of freedom on
148
+ nothing); if not, keep it and name the obstacle it removes. Constraints
149
+ accumulate as work reveals obstacles — an almost-empty first draft is
150
+ correct, not incomplete.
151
+ Open with a supremacy clause: what these bind (all layers, tiers, paid
152
+ components, future components), and that packaging or naming is irrelevant.
153
+ Each rule: an observable property of the artifact (never intent or a promise),
154
+ a closed enumeration with a closure rule, the near-miss verbs, an IN and an OUT
155
+ example on the same axis, and its exception attached in the same bullet.
156
+ Nothing here that cannot be violated by a proposed change — a rule about this
157
+ document's own prose can never fire, and wastes a slot. -->
158
+ ## The admission test
159
+ <!-- [gate] One sentence naming EXACTLY which sections are positive sources and
160
+ EXACTLY which are prohibitions. State what the test does NOT govern (defect
161
+ fixes, performance, maintenance) and give that exemption its own anti-abuse
162
+ clause. State the default for anything unreached, per path. -->
163
+ ## Success Signals
164
+ <!-- [gate] Each checkable against a NAMED artifact or command by someone who was
165
+ not here. Not "we are the best" — a file, a command, a battery, and what the
166
+ result must be. -->
167
+ ## Where the rest lives
168
+ <!-- Pointers, so an absence reads as intentional rather than as a gap. Competitive
169
+ positioning goes here as a dated snapshot, never in the Vision body. -->
170
+ ```
171
+
172
+ ## ai_docs/vision/roadmap.md
173
+
174
+ ```markdown
175
+ # Roadmap
176
+ Status: DRAFT
177
+
178
+ ## Milestones
179
+ <!-- for each: expected benefit, priority, progress indicator -->
180
+ ```
181
+
182
+ ## ai_docs/vision/principles.md
183
+
184
+ ```markdown
185
+ # Decision Principles
186
+ Status: DRAFT
187
+
188
+ <!-- bullet list of the stable principles guiding trade-offs and scope, most critical first -->
189
+ ```
190
+
191
+ ## ai_docs/vision/features/VISION_[feature_name].md
192
+
193
+ Only for features spanning multiple ANALYSIS documents or multiple milestones: otherwise the feature vision lives in the `## Feature Vision` section of the ANALYSIS.
194
+
195
+ ```markdown
196
+ # Feature Vision: [Name]
197
+
198
+ ## Problem
199
+ ## Expected Benefit
200
+ ## Actors
201
+ <!-- the cast this feature serves — usually a subset/refinement of the project
202
+ Actors, or a distinct feature-local cast for internal-tooling work. One light
203
+ line each: **Role** — primary goal; good UX = what good feels like.
204
+ Referenced by the use-cases, not re-described in them. -->
205
+ ## Success Signals
206
+ ## Non-Goals / Out of Scope
207
+ ## Related Constraints and Principles
208
+ ```
209
+
210
+ ## ai_docs/solutions/ANALYSIS_[feature_name].md
211
+
212
+ The frontmatter is the source of truth for the feature state (the `features_history.md` index is generated from it).
213
+
214
+ ```markdown
215
+ ---
216
+ id: F-001
217
+ feature: Feature Name
218
+ status: PLANNED
219
+ level: L3
220
+ start_date: 2026-06-11
221
+ end_date:
222
+ ---
223
+ # Feature Analysis: [Name]
224
+
225
+ ## Objective
226
+ <!-- what we want to achieve and which problems it solves -->
227
+
228
+ ## Feature Vision
229
+ <!-- expected benefit and problem solved; alignment with the project vision
230
+ (cite the document and its DRAFT/APPROVED state); non-goals/out-of-scope
231
+ for this feature; success signals; the Actors this feature serves (name them,
232
+ or point to the project Vision's ## Actors — do not re-describe them here).
233
+ This is the single home of the feature vision: the separate file
234
+ VISION_[feature].md is created only if the feature spans multiple
235
+ ANALYSIS documents or multiple milestones. -->
236
+
237
+ ## Use Cases / User Needs
238
+ <!-- who needs this and why: the concrete use-cases / user-needs the change serves
239
+ (the Standalone home for what Hybrid keeps in D-UC). Each use-case NAMES the
240
+ Actor it serves (defined in the Vision's ## Actors) — actor = who they are,
241
+ use-case = what they do. Derived from the elicitation round; the Impact below
242
+ must cover each, and the closure review checks coverage + actor UX fit. -->
243
+
244
+ ## Capability Ledger
245
+ <!-- this lens's capability pass is the TAXONOMY pass (`taxonomy.md`), run BEFORE
246
+ the Impact below. One row per knowledge concept, topic or SOP the unit
247
+ requires — a domain subject, naming no file. Verdict EXISTS (name the owning
248
+ node/document and where) / INADEQUATE (same, plus the gap) / MISSING (say
249
+ what you searched: the topic index descended, the synonyms tried, the guides
250
+ consulted — an unread index can never ground a MISSING, `taxonomy.md` §2).
251
+ Every INADEQUATE or MISSING row becomes a node or document with its own home,
252
+ stated without naming this unit, and lands in the Impact below. Evidence is
253
+ what makes a verdict falsifiable. A question, not a form: when every concept
254
+ plainly has its owner, one line under this heading answers it. -->
255
+
256
+ | Capability | Verdict | Component / gap | Evidence |
257
+ |---|---|---|---|
258
+ | persist an order | EXISTS | `path/to/store.py#OrderStore` | re-read `save()`: durable, returns the id |
259
+ | notify the customer | MISSING | — | grep notify/alert/dispatch + send, over src/ and legacy/; no owner |
260
+
261
+ ## Impact
262
+ <!-- existing files touched, APIs/contracts, performance, new dependencies.
263
+ Derived from the ledger above: every INADEQUATE/MISSING row appears here. -->
264
+
265
+ ## Sources and Verification
266
+ <!-- ALWAYS mandatory, also in Standalone. This is the knowledge domain's account of
267
+ what could go wrong, and it is the risk slot the validator requires here — the
268
+ code domain's `## Security and Threat Model` belongs to a different lens and is
269
+ not what this one owes.
270
+ CITE, do not restate: provenance is owned by the claim rows in `topics/` and by
271
+ the corpus sidecars. This section names WHICH nodes and sources the unit rests on
272
+ and how they were verified — it never carries a second copy of their provenance
273
+ (two provenance tables in one project is the restated-fact finding `review.md`
274
+ defines).
275
+ A distillation whose origin cannot be reopened is model knowledge, not knowledge
276
+ work. If something could not be confirmed, say so explicitly — an open CONTESTED
277
+ set is a state this section may honestly report; silence is not. -->
278
+
279
+ Rests on: `topics/pricing.md` (claims c7f3a91b0e42, 4d20be71c8a9 — both GIVEN, verified
280
+ against `corpus/given/contract-9a1f2b7c.pdf` and its superseding amendment). Open
281
+ CONTESTED: none.
282
+
283
+ ## Action Plan
284
+ - [ ] ...
285
+
286
+ ## Test Strategy
287
+ <!-- AAA unit tests, integration, examples. If the environment is not executable (firmware/HIL):
288
+ explicit alternative verification and reason. -->
289
+
290
+ ## Diary / Current State
291
+ <!-- updated at every milestone: where I am, last problem, next step.
292
+ It is the handoff source for this feature. -->
293
+ ```
294
+
295
+ Allowed frontmatter states: `PLANNED` | `IN_PROGRESS` | `COMPLETED` | `CANCELLED`. `COMPLETED` requires `end_date`. (The validator also accepts the deprecated Italian keys `stato`/`livello`/`data_inizio`/`data_fine` in existing projects.)
296
+
297
+ ## ai_docs/solutions/SPIKE_[topic].md
298
+
299
+ ```markdown
300
+ # Spike: [topic]
301
+
302
+ ## Question to answer
303
+ ## Time-box
304
+ ## What was tried
305
+ ## Answer / Outcome
306
+ ## Consequences
307
+ <!-- max 1 page. Spike code is NOT mergeable: for production reclassify L2/L3. -->
308
+ ```
309
+
310
+ ## ai_docs/solutions/PLAN_[feature].md
311
+
312
+ Opt-in, L3 only (see `dispatch.md`): the executable task list an orchestrator
313
+ drives through subagents. It is `derived-from` the accepted E-TDD (Hybrid) or
314
+ the ANALYSIS Action Plan (Standalone) — never independently authored. The
315
+ validator gate is `sdlc_check.py plan validate PLAN_[feature].md` ("no valid
316
+ plan, no dispatch").
317
+
318
+ ````markdown
319
+ ---
320
+ status: DRAFT
321
+ derived-from: e_tdd_[feature] vX.Y
322
+ ---
323
+ # Plan: [Feature]
324
+
325
+ ```json
326
+ {
327
+ "tasks": [
328
+ {
329
+ "id": "T1",
330
+ "title": "Add the confine_under helper",
331
+ "paths": ["skills/kb-agentic-skill/scripts/sdlc_check.py"],
332
+ "consumes": [],
333
+ "produces": ["skills/kb-agentic-skill/scripts/sdlc_check.py#confine_under"],
334
+ "verify": "python skills/kb-agentic-skill/scripts/test_plan.py",
335
+ "guides": ["GUIDE_python_style.md"]
336
+ }
337
+ ]
338
+ }
339
+ ```
340
+ ````
341
+
342
+ Task fields: `id`/`title`/`verify` are required; at least one of `paths`/
343
+ `produces` is required. `paths` are files the task touches; `consumes`/
344
+ `produces` declare interfaces between tasks (what an earlier task hands to a
345
+ later one); `guides` are pointers (paths, not pasted content) into
346
+ `ai_docs/reference/` or the agent-global KB. All path-shaped fields are
347
+ confined fail-closed under the project root (or the reference/KB root for
348
+ `guides`) — an absolute path or a `..` escape is rejected. `verify` is opaque
349
+ text: the validator only prints it (`plan brief`), never runs it — the
350
+ orchestrator executes it out of band.
351
+
352
+ Sidecar ledger `ai_docs/solutions/PLAN_[feature].ledger.json` (orchestrator-
353
+ owned, validator-read-only): `{ "<task_id>": {"status": "done", "verify_result":
354
+ "pass", "timestamp": "2026-07-03T00:00:00Z"} }`. Only the exact `status: done`
355
+ sentinel skips re-dispatch; any other value (or a missing `status`) is treated
356
+ as pending. A ledger id absent from the plan is a non-fatal orphan warning.
357
+
358
+ ## ai_docs/audit/audit_plan.md (Standalone mode only)
359
+
360
+ The `Reference` field (git hash or ISO UTC timestamp) is managed by `sdlc_check.py mark` — do not fill it by hand. Freshness is verified with `sdlc_check.py stale`.
361
+
362
+ ```markdown
363
+ # Audit Plan
364
+
365
+ States: PENDING (to analyze) | ANALYZED (analyzed, with reference) | SKIPPED (with reason).
366
+
367
+ | Path | Status | Reference | Notes |
368
+ |---|---|---|---|
369
+ | src/core/ | PENDING | - | |
370
+ | vendor/ | SKIPPED | - | vendored code |
371
+ ```
372
+
373
+ ## ai_docs/audit/handoff.md — the workstream registry
374
+
375
+ One row per OPEN workstream, ≤ 20 lines. **Parallel-safe by construction**: closing
376
+ one milestone removes one row and never touches another's resume point — the defect
377
+ this replaces was a single narrative slot where the last session to close overwrote
378
+ everyone else's handoff. It is an **inventory for lookup** (like the generated
379
+ manifest), not a work board: no assignment, no due dates, no execution ordering.
380
+
381
+ Updated at every L3 closure (row removed) AND at session end with work still
382
+ IN_PROGRESS (row refreshed) — see Write Triggers.
383
+
384
+ **Coming from a pre-1.17 project** (narrative handoff with `## Active features` /
385
+ `## Next step` / `## Session notes`): nothing is broken and nothing is urgent — the
386
+ validator only checks the `Date:` header and its age, and the orientation hook reads
387
+ the file verbatim. Read it as a one-row registry, and convert it the next time the
388
+ write trigger fires: each `## Active features` bullet becomes a row, `## Next step`
389
+ becomes that row's next step, `## Session notes` becomes `## Project-wide notes`.
390
+ Migrating a repository that is not being worked on buys nothing.
391
+
392
+ ```markdown
393
+ # Handoff — workstream registry
394
+ Date: 2026-06-11 (UTC)
395
+
396
+ | Workstream | Level | Branch | Status | Since | Next step | Details |
397
+ |---|---|---|---|---|---|---|
398
+ | F-001 SSO login | L3 | feature/sso-login | PROGRESS | 2026-06-10 | wire callback tests | HANDOFF_login_sso.md · ANALYSIS_login_sso.md |
399
+ | F-002 Audit refresh | L3 | feature/audit | PAUSED | 2026-06-02 | resume at Phase 4 | ANALYSIS_audit_refresh.md (no volatile state) |
400
+
401
+ ## Project-wide notes
402
+ <!-- one or two lines: release pending, environment quirks that affect everyone -->
403
+ ```
404
+
405
+ ## ai_docs/audit/reviews/REVIEW_LOG.md
406
+
407
+ One row per completed review (`review.md` §When a review is due). Append-only; it
408
+ is the record that the gate ran and what it was worth. **One schema for both
409
+ modes** — a Hybrid project's devPNT gates write to this same file, so Standalone
410
+ adds values to the existing columns rather than a second table.
411
+
412
+ ```markdown
413
+ # Independent Review Log
414
+
415
+ | date | doc_key | tier | reviewer | findings_raised | findings_real | verdict | revise_rounds |
416
+ |---|---|---|---|---|---|---|---|
417
+ | 2026-06-11 | ANALYSIS_login_sso.md | design | subagent (opus, fresh ctx) | 4 | 3 | PASS | 2 |
418
+ | 2026-06-12 | diff feature/sso-login | closure | self-pass (declared; no subagent facility) | 2 | 2 | PASS | 1 |
419
+
420
+ ## Notes
421
+ <!-- One short paragraph per review that found something worth remembering: what
422
+ the findings actually were, and what changed because of them. The table
423
+ answers "was it reviewed and by what"; this answers "what did it find" —
424
+ which is where `review.md`'s per-finding outcomes live. Omit for a clean
425
+ review; a row with 0 findings needs no note. -->
426
+ ```
427
+
428
+ `tier` is the moment plus, in Hybrid, the reviewer weight: `design`, `design (late)`
429
+ and `closure` (Standalone); `deep`, `light`, `code`, `guide`, `vision` (devPNT gates
430
+ and the Vision blind check). The validator reads this column by its header name, so
431
+ extra or reordered columns are fine — but the header must say `tier`. `reviewer`
432
+ records the realization actually used — fresh subagent, one-shot client run, or a
433
+ **declared** self-pass. Writing `self-pass` where independence was unavailable is
434
+ honest; writing nothing, or implying independence you did not have, is the failure
435
+ this column exists to prevent. `findings_real` is how many raised findings survived
436
+ triage: over time it is the only evidence of whether the gate earns its cost.
437
+
438
+ ## ai_docs/audit/HANDOFF_[topic].md — volatile resume logistics (ephemeral)
439
+
440
+ **Resume logistics ONLY; the ANALYSIS Diary keeps the durable narrative (DRY).**
441
+ The boundary: Diary = what happened and why (decisions, state of the work — survives
442
+ forever); this file = how to pick the work back up (branch/worktree, uncommitted
443
+ state, environment notes, the next concrete command — worthless once resumed).
444
+ Created only when a session pauses the feature WITH volatile state to record;
445
+ **DELETED at the feature's closure**, in the same step that flips the ANALYSIS to
446
+ COMPLETED — anything in it worth keeping was in the wrong file.
447
+
448
+ ```markdown
449
+ # HANDOFF: [topic] (ephemeral — deleted at closure)
450
+ Updated: 2026-06-11 (UTC)
451
+ Branch: feature/sso-login (worktree ../wt-sso)
452
+
453
+ ## Resume state
454
+ <!-- uncommitted files, half-run migrations, env vars, running services -->
455
+
456
+ ## Next command
457
+ <!-- the literal next thing to run or edit -->
458
+
459
+ ## Watch out
460
+ <!-- traps discovered this session that bite on resume (locks, CRLF, flaky test) -->
461
+ ```
462
+
463
+ ## ai_docs/strategic/architecture.md and existing_features.md
464
+
465
+ Canonical docs: they open with the header (`description:`/`status:`) so they enter the `INDEX.md` manifest cleanly.
466
+
467
+ ```markdown
468
+ ---
469
+ description: Stack, directory structure, component map and architectural patterns of the project.
470
+ status: CURRENT
471
+ ---
472
+ # Project Architecture
473
+ ## Technology Stack
474
+ ## Directory Structure
475
+ ## Component Map
476
+ <!-- The inventory the taxonomy pass reads BEFORE searching the corpus and the
477
+ graph (`taxonomy.md` §1–§2). One row per component that OWNS a capability:
478
+ Capability = what it lets the system DO (a verb over a domain noun, naming
479
+ no file). Contract = what it guarantees its consumers, in one line, stated
480
+ without naming any single consumer. Where = a path, or `path#symbol` when
481
+ the component is smaller than its file.
482
+ Seeded at bootstrap; a row is added or corrected in the SAME closure that
483
+ builds — or merely discovers — a component, and the area is marked ANALYZED.
484
+ A directory is not a component: rows name what owns a capability, not where
485
+ files sit (that is ## Directory Structure above). An absent or stale map is
486
+ why the next feature rules the same capability MISSING a second time and
487
+ builds it again. -->
488
+
489
+ Coverage: whatever `audit/audit_plan.md` marks ANALYZED — **read it, do not trust a
490
+ list restated here** (a hand-copied list is a cache with no invalidation). Outside
491
+ those areas this map is **unread, not empty**: it can never ground a MISSING
492
+ verdict, and the corpus and graph are searched instead (`taxonomy.md` §2).
493
+
494
+ | Component | Capability it owns | Contract | Where |
495
+ |---|---|---|---|
496
+ | ... | ... | ... | ... |
497
+
498
+ <!-- Where is `path/to/file.py#Symbol`. Leave the placeholder row untouched until
499
+ the map has a real component: the validator skips an all-`...` row, so a
500
+ freshly seeded project is never nagged about a table nobody has filled in. -->
501
+
502
+ ## Architectural Patterns
503
+ ```
504
+
505
+ ```markdown
506
+ ---
507
+ description: Concise catalog of the project's existing features.
508
+ status: CURRENT
509
+ ---
510
+ # Existing Features
511
+ - [ID] **Feature Name**: Description
512
+ ```
513
+
514
+ `ai_docs/strategic/features_history.md` and `ai_docs/INDEX.md` have NO template: they are generated by `sdlc_check.py index`.
515
+
516
+ ## ai_docs/topics/[slug].md (topic node)
517
+
518
+ One file per topic, flat directory, hierarchy in frontmatter (`taxonomy.md`).
519
+
520
+ ```markdown
521
+ ---
522
+ topic: pricing
523
+ description: How the offer is priced — list prices and negotiated exceptions.
524
+ parents: [offerta-commerciale]
525
+ owns: [pricing/list-price]
526
+ synonyms: [listino, price list]
527
+ gaps:
528
+ - volume tiers above 500 units
529
+ status: CURRENT
530
+ ---
531
+
532
+ ## Claims
533
+
534
+ | id | claim | valid | qty | about | source | prov | state |
535
+ |---|---|---|---|---|---|---|---|
536
+ | | List price of module A is 12000 EUR | until 2026-03-01 | 12000 EUR cost | - | corpus/given/contract-9a1f2b7c.pdf#p=17@412-509 | GIVEN | OK |
537
+ ```
538
+
539
+ - `id` empty when writing by hand: `sdlc_check.py claim-id --fill <file>` computes it.
540
+ - `valid` half-open: `from` inclusive, `until` exclusive; `if <cond>` for conditionals.
541
+ - `qty`: `<value> <unit> <kind>` — effort in person-days (h/d/w/mo/fte-mo; 8h=1d, 1w=5d,
542
+ 1mo=21d), duration in calendar days (h/d/w/mo), cost within one currency, count unit-matched.
543
+ - `about`: `<predicate> -> <slug>` for relationship claims; stored once, under the subject.
544
+ - `state`: `OK` | `CONTESTED <id>[,..]` | `SUPERSEDED <id>` — per claim, never per node.
545
+ - A tombstone (merged/renamed topic): `status: SUPERSEDED` + `redirect_to: <slug>`, body empty.
546
+
547
+ ## ai_docs/corpus/given/[name].meta.md (source sidecar)
548
+
549
+ ```markdown
550
+ ---
551
+ sha256: <raw-byte digest of the original — NOT the LF-normalized text digest>
552
+ date: 2026-08-01
553
+ provenance: GIVEN
554
+ supersedes: contract-1a2b3c4d.pdf
555
+ extractor: pdftotext 24.02, form-feed page breaks, whitespace collapsed
556
+ ---
557
+ Handed over by <who>, <context in one line>.
558
+ ```
559
+
560
+ `supersedes:` is what makes "which claims rest on a superseded version" answerable —
561
+ without it the two content-addressed files are unrelated. `extractor:` pins the stored
562
+ canonical extraction (`<name>-<hash8>.txt`) that offset locators address.
563
+
564
+ ## ai_docs/corpus/notes/RULING_[topic]_[date].md (practitioner ruling)
565
+
566
+ ```markdown
567
+ ---
568
+ origin: ruling
569
+ basis: Client confirmed Q3 delivery by phone, 2026-07-30.
570
+ date: 2026-08-01
571
+ status: CURRENT
572
+ ---
573
+ Ruling on the contested delivery date of module B: Q3 stands.
574
+ Supersedes claims <id>, <id> (see topics/<slug>.md).
575
+ ```
576
+
577
+ `basis:` is mandatory and states THE FACT the practitioner knows that the corpus lacks —
578
+ a preference is not a fact; the validator refuses a ruling without it. The ruling enters
579
+ the topic's claim table as a row with `prov: RULING` sourcing this note.