@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.
- package/CHANGELOG.md +332 -0
- package/README.md +85 -0
- package/gemini-extension.json +6 -0
- package/package.json +50 -0
- package/scripts/init.js +216 -0
- package/scripts/lib.js +152 -0
- package/scripts/postinstall.js +42 -0
- package/scripts/preuninstall.js +17 -0
- package/skills/kb-agentic-skill/ENFORCEMENT.md +123 -0
- package/skills/kb-agentic-skill/SKILL.md +134 -0
- package/skills/kb-agentic-skill/dispatch.md +87 -0
- package/skills/kb-agentic-skill/distillation.md +79 -0
- package/skills/kb-agentic-skill/elicitation.md +131 -0
- package/skills/kb-agentic-skill/guides.md +287 -0
- package/skills/kb-agentic-skill/reconciliation.md +79 -0
- package/skills/kb-agentic-skill/review.md +168 -0
- package/skills/kb-agentic-skill/routing.md +100 -0
- package/skills/kb-agentic-skill/scripts/sdlc_check.py +846 -0
- package/skills/kb-agentic-skill/scripts/sdlc_core.py +1996 -0
- package/skills/kb-agentic-skill/taxonomy.md +80 -0
- package/skills/kb-agentic-skill/templates.md +579 -0
- package/skills/kb-agentic-skill/vision.md +245 -0
|
@@ -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.
|