@antoneeo/kb-agentic-skill 1.19.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,125 +1,125 @@
1
- # Portability — carrying knowledge between projects
2
-
3
- **For whom**: the agent moving a subgraph out of one project or into another.
4
- **Answers**: "what travels, what refuses to travel, and what an import may decide".
5
- **Does not answer**: where a claim's concept belongs (`taxonomy.md` — import *uses* that
6
- pass, it does not replace it) or how a disagreement is settled (`reconciliation.md`).
7
-
8
- ## 0. The two commands, and what to tell the user
9
-
10
- A bundle is a **folder**, not an archive. Nothing here compresses or unpacks anything:
11
- the user moves the folder however they already move folders.
12
-
13
- **Sending side** — run from the project that owns the knowledge:
14
-
15
- ```
16
- sdlc_check.py export --out ../kb-bundle # the whole KB
17
- sdlc_check.py export --out ../kb-bundle --topics pricing,licensing
18
- ```
19
-
20
- Write it **outside the docs root**. A bundle sitting inside `ai_docs/` is a second copy
21
- of topics and corpus files in the tree the validator walks, and that confusion is free
22
- to avoid.
23
-
24
- **Receiving side** — run from the project that is to gain it:
25
-
26
- ```
27
- sdlc_check.py import ../kb-bundle --dry-run # see what would land
28
- sdlc_check.py import ../kb-bundle
29
- sdlc_check.py check # always, right after
30
- ```
31
-
32
- **What to say to the user, in their words.** Say these four things and stop:
33
-
34
- 1. *"I've written the bundle to `<path>`. It's a folder — move it to the other project
35
- however you like."*
36
- 2. *"It carries the source documents too, not just the notes, so it is not small. That is
37
- the point: over there the claims can still be traced back to the page they came from."*
38
- 3. After importing: *"Nothing was overwritten. Anything already there stayed as it was"* —
39
- and, if a topic was skipped, *"a topic with the same name already exists; I have not
40
- merged them, because they may not be the same subject. Do you want me to look?"*
41
- 4. If an imported ruling arrived: *"one decision came from the other project. I have kept
42
- it, marked as theirs, and it cannot settle anything here until you confirm it."*
43
-
44
- Do not explain the closure, the id hashing or the provenance model unless asked. The
45
- user asked to move their knowledge, not to learn how it is stored.
46
-
47
- ## 1. What a bundle is
48
-
49
- A directory mirroring the docs-root layout:
50
-
51
- ```
52
- <bundle>/
53
- MANIFEST.md kb_bundle: 1, source_project, topics, per-artifact sha256
54
- topics/<slug>.md
55
- corpus/given/<name> + <name>.meta.md (+ the .txt extraction, when there is one)
56
- corpus/notes/<name>.md
57
- ```
58
-
59
- The layout is mirrored **on purpose**. Claim `source` cells are docs-root-relative, so
60
- nothing is rewritten on import — and because `kb_claim_id` hashes
61
- `path#locator#qty` with the text excluded, the same artifact cited at the same span
62
- mints **the same id in every project**. De-duplication is therefore mechanical, not a
63
- judgement call, and importing the same bundle twice is a provable no-op.
64
-
65
- ## 2. Export is a closure, not a selection
66
-
67
- You choose topics; the export decides what must travel with them.
68
-
69
- - **Every artifact a selected claim cites**, plus its sidecar and its stored extraction.
70
- A claim whose source cannot be reopened is model knowledge arriving by another route —
71
- the validator would reject it in the target, and correctly.
72
- - **Every row a `CONTESTED` row points at.** The symmetry check refuses a set that lost
73
- half its members, so a partial export ships a tree that cannot pass its own checks.
74
- When a partner row lives in an unselected topic, that topic is **added and reported** —
75
- never dropped, never silently.
76
-
77
- If a conflict partner resolves to no row at all, the export **refuses**: exporting a
78
- broken set is worse than exporting nothing.
79
-
80
- ## 3. Import is additive, and decides nothing
81
-
82
- `import` writes files. It does not place concepts, merge bodies, or settle disagreements.
83
-
84
- - **Never overwrites a topic.** A slug that already exists is reported and skipped: two
85
- projects using the word `pricing` may mean two different things, and that judgement is
86
- the placement pass's (`taxonomy.md`, five verdicts, `owns:` against double placement).
87
- - **Never deletes.** The doctrine is tombstones over deletion; an additive import has no
88
- business removing anything.
89
- - **All or nothing.** The whole plan is computed before a byte is written. An import that
90
- half-applies leaves a tree whose checks fail and whose owner cannot tell what landed.
91
-
92
- It refuses on: a missing or unmarked `MANIFEST.md`; a path that escapes the docs root; an
93
- artifact whose name matches an existing one **with different bytes** (content-addressed
94
- names must mean equal content — a mismatch means one of the two is lying about its
95
- origin); an incomplete conflict set; a dangling `supersedes:`.
96
-
97
- After importing, run `check`. The import is deliberately not a validator.
98
-
99
- ## 4. Knowledge crosses; authority does not
100
-
101
- `RULING` means *the fact you know and the corpus does not*, with a `basis:` you gave. It
102
- is the only thing that settles a `CONTESTED` set. A ruling from another project carries
103
- another owner's decision, and importing it unchanged would make that decision binding
104
- here without anyone here granting it — the machine deciding, which reconciliation
105
- refuses everywhere else.
106
-
107
- So an imported ruling arrives as **`prov: IMPORTED`** (owner ruling, 2026-08-03):
108
-
109
- - its text, span and original `basis:` travel **verbatim** — the knowledge is not lost,
110
- and pretending it is a `DERIVED` synthesis would make the row lie about where it came
111
- from;
112
- - its note carries `imported_from:`, and the validator refuses an `IMPORTED` row without
113
- it: unnamed, the class says nothing and the row is a `RULING` with the label filed off;
114
- - **it cannot supersede a local row.** The validator errors on `SUPERSEDED <id>` when
115
- that id is `IMPORTED`.
116
-
117
- **Re-ratification** is one act: read it, write your own note with your own `basis:`, and
118
- set the row's `prov` to `RULING`. That is you deciding, which is the only thing that ever
119
- settles anything here.
120
-
121
- ## 5. Triage
122
-
123
- Exporting is L1 — it writes nothing into the corpus and changes no knowledge. Importing
124
- is **L3**: a source enters the corpus and nodes are created, which is the L3 definition
125
- in Rule Zero, and the bundle is external input, which is never L1 whatever its size.
1
+ # Portability — carrying knowledge between projects
2
+
3
+ **For whom**: the agent moving a subgraph out of one project or into another.
4
+ **Answers**: "what travels, what refuses to travel, and what an import may decide".
5
+ **Does not answer**: where a claim's concept belongs (`taxonomy.md` — import *uses* that
6
+ pass, it does not replace it) or how a disagreement is settled (`reconciliation.md`).
7
+
8
+ ## 0. The two commands, and what to tell the user
9
+
10
+ A bundle is a **folder**, not an archive. Nothing here compresses or unpacks anything:
11
+ the user moves the folder however they already move folders.
12
+
13
+ **Sending side** — run from the project that owns the knowledge:
14
+
15
+ ```
16
+ sdlc_check.py export --out ../kb-bundle # the whole KB
17
+ sdlc_check.py export --out ../kb-bundle --topics pricing,licensing
18
+ ```
19
+
20
+ Write it **outside the docs root**. A bundle sitting inside `ai_docs/` is a second copy
21
+ of topics and corpus files in the tree the validator walks, and that confusion is free
22
+ to avoid.
23
+
24
+ **Receiving side** — run from the project that is to gain it:
25
+
26
+ ```
27
+ sdlc_check.py import ../kb-bundle --dry-run # see what would land
28
+ sdlc_check.py import ../kb-bundle
29
+ sdlc_check.py check # always, right after
30
+ ```
31
+
32
+ **What to say to the user, in their words.** Say these four things and stop:
33
+
34
+ 1. *"I've written the bundle to `<path>`. It's a folder — move it to the other project
35
+ however you like."*
36
+ 2. *"It carries the source documents too, not just the notes, so it is not small. That is
37
+ the point: over there the claims can still be traced back to the page they came from."*
38
+ 3. After importing: *"Nothing was overwritten. Anything already there stayed as it was"* —
39
+ and, if a topic was skipped, *"a topic with the same name already exists; I have not
40
+ merged them, because they may not be the same subject. Do you want me to look?"*
41
+ 4. If an imported ruling arrived: *"one decision came from the other project. I have kept
42
+ it, marked as theirs, and it cannot settle anything here until you confirm it."*
43
+
44
+ Do not explain the closure, the id hashing or the provenance model unless asked. The
45
+ user asked to move their knowledge, not to learn how it is stored.
46
+
47
+ ## 1. What a bundle is
48
+
49
+ A directory mirroring the docs-root layout:
50
+
51
+ ```
52
+ <bundle>/
53
+ MANIFEST.md kb_bundle: 1, source_project, topics, per-artifact sha256
54
+ topics/<slug>.md
55
+ corpus/given/<name> + <name>.meta.md (+ the .txt extraction, when there is one)
56
+ corpus/notes/<name>.md
57
+ ```
58
+
59
+ The layout is mirrored **on purpose**. Claim `source` cells are docs-root-relative, so
60
+ nothing is rewritten on import — and because `kb_claim_id` hashes
61
+ `path#locator#qty` with the text excluded, the same artifact cited at the same span
62
+ mints **the same id in every project**. De-duplication is therefore mechanical, not a
63
+ judgement call, and importing the same bundle twice is a provable no-op.
64
+
65
+ ## 2. Export is a closure, not a selection
66
+
67
+ You choose topics; the export decides what must travel with them.
68
+
69
+ - **Every artifact a selected claim cites**, plus its sidecar and its stored extraction.
70
+ A claim whose source cannot be reopened is model knowledge arriving by another route —
71
+ the validator would reject it in the target, and correctly.
72
+ - **Every row a `CONTESTED` row points at.** The symmetry check refuses a set that lost
73
+ half its members, so a partial export ships a tree that cannot pass its own checks.
74
+ When a partner row lives in an unselected topic, that topic is **added and reported** —
75
+ never dropped, never silently.
76
+
77
+ If a conflict partner resolves to no row at all, the export **refuses**: exporting a
78
+ broken set is worse than exporting nothing.
79
+
80
+ ## 3. Import is additive, and decides nothing
81
+
82
+ `import` writes files. It does not place concepts, merge bodies, or settle disagreements.
83
+
84
+ - **Never overwrites a topic.** A slug that already exists is reported and skipped: two
85
+ projects using the word `pricing` may mean two different things, and that judgement is
86
+ the placement pass's (`taxonomy.md`, five verdicts, `owns:` against double placement).
87
+ - **Never deletes.** The doctrine is tombstones over deletion; an additive import has no
88
+ business removing anything.
89
+ - **All or nothing.** The whole plan is computed before a byte is written. An import that
90
+ half-applies leaves a tree whose checks fail and whose owner cannot tell what landed.
91
+
92
+ It refuses on: a missing or unmarked `MANIFEST.md`; a path that escapes the docs root; an
93
+ artifact whose name matches an existing one **with different bytes** (content-addressed
94
+ names must mean equal content — a mismatch means one of the two is lying about its
95
+ origin); an incomplete conflict set; a dangling `supersedes:`.
96
+
97
+ After importing, run `check`. The import is deliberately not a validator.
98
+
99
+ ## 4. Knowledge crosses; authority does not
100
+
101
+ `RULING` means *the fact you know and the corpus does not*, with a `basis:` you gave. It
102
+ is the only thing that settles a `CONTESTED` set. A ruling from another project carries
103
+ another owner's decision, and importing it unchanged would make that decision binding
104
+ here without anyone here granting it — the machine deciding, which reconciliation
105
+ refuses everywhere else.
106
+
107
+ So an imported ruling arrives as **`prov: IMPORTED`** (owner ruling, 2026-08-03):
108
+
109
+ - its text, span and original `basis:` travel **verbatim** — the knowledge is not lost,
110
+ and pretending it is a `DERIVED` synthesis would make the row lie about where it came
111
+ from;
112
+ - its note carries `imported_from:`, and the validator refuses an `IMPORTED` row without
113
+ it: unnamed, the class says nothing and the row is a `RULING` with the label filed off;
114
+ - **it cannot supersede a local row.** The validator errors on `SUPERSEDED <id>` when
115
+ that id is `IMPORTED`.
116
+
117
+ **Re-ratification** is one act: read it, write your own note with your own `basis:`, and
118
+ set the row's `prov` to `RULING`. That is you deciding, which is the only thing that ever
119
+ settles anything here.
120
+
121
+ ## 5. Triage
122
+
123
+ Exporting is L1 — it writes nothing into the corpus and changes no knowledge. Importing
124
+ is **L3**: a source enters the corpus and nodes are created, which is the L3 definition
125
+ in Rule Zero, and the bundle is external input, which is never L1 whatever its size.
@@ -1,8 +1,11 @@
1
1
  # Review Discipline
2
2
 
3
- The single definition of how to request, receive, and perform a review. Other
4
- places that need review behavior point here instead of restating it (DRY) —
5
- including devPNT's §4.5/§4.6 gates and any future review step.
3
+ The single definition of how to request, receive, and perform an agent review,
4
+ in Standalone and in Hybrid alike. Other places that need review behavior point
5
+ here instead of restating it (DRY) — including devPNT doctrine §4.5/§4.6, which
6
+ invoke this same review, and any future review step. **devPNT performs no
7
+ review**: it hosts the governed artifacts and is where the human reviews and
8
+ approves them — after the agent review this file defines, never instead of it.
6
9
 
7
10
  ## When a review is due
8
11
 
@@ -14,6 +17,20 @@ Two moments, and they review different things:
14
17
  | **1b. Late arrival** | Work that became L3 *after* code existed — an L1/L2 reclassified mid-flight, or a design increment on a feature already implemented — runs moment 1 **now**, before any further implementation, logged `design (late)` | same | L3 |
15
18
  | **2. Closure review** | Phase 5, before DONE | the actual diff, against that approved design | L2 / L3 — the L2 closure review is optional; every review that runs logs its row |
16
19
 
20
+ **The agent review comes first, the human's after — never instead (Hybrid).**
21
+ No governed artifact that this file reviews — the design (`E-ISP`, `E-TDD`),
22
+ and whatever else the client's devPNT doctrine §4.5/§4.6 sends to review — is
23
+ proposed to devPNT before an agent review of it under this file has a final
24
+ verdict of PASS; the proposal's notes cite that
25
+ REVIEW_LOG row (date, doc_key, verdict), so the human sees which review it
26
+ passed. When the round cap is reached with findings still standing, the artifact
27
+ goes back to the user in chat with those findings, and it reaches devPNT only on
28
+ the user's explicit decision — with the open findings attached to the proposal
29
+ and the decision recorded. Where the client also follows devPNT doctrine
30
+ §4.5/§4.6, that invocation IS this review: one review, one REVIEW_LOG row in the
31
+ Hybrid realization below, and the doctrine's extra requirements add to this
32
+ mandate, never replace it.
33
+
17
34
  **Why the design review is its own moment, and not a nicety.** The closure review
18
35
  can only tell you the code matches the design; it cannot tell you the design was
19
36
  wrong. An omission in the design — an impacted file nobody listed, a threat with no
@@ -165,7 +182,7 @@ policy pays — could not be drawn.
165
182
  **mode-specific** realization columns. The core is what both modes actually share: `date`, `doc_key`,
166
183
  `tier`, `model`, `findings_raised`, `findings_real`, `verdict`, `revise_rounds`.
167
184
  Around it, Standalone adds `reviewer` and Hybrid adds `instrument` and `notes` —
168
- a devPNT row carries no `reviewer` column at all, so "one identical column list"
185
+ a Hybrid row carries no `reviewer` column at all, so "one identical column list"
169
186
  was never true of the two modes. This costs nothing for the reason `templates.md`
170
187
  §`ai_docs/audit/reviews/REVIEW_LOG.md` owns and states.
171
188
  The log is how the gate's value is measured over time; skipping it makes the gate
@@ -195,7 +212,42 @@ marks anything DONE, and a PASS is not an approval to merge — the human owns t
195
212
 
196
213
  ## Requesting
197
214
 
198
- When you hand work to a reviewer (human or agent), give them:
215
+ **Open every request to an agent reviewer with the REVIEW MANDATE block, copied
216
+ verbatim.** Only the angle-bracket fields change; specific instructions follow
217
+ the block and cannot weaken it. A paraphrased mandate is how a check disappears
218
+ without anyone deciding to drop it. Field measurement (2026-10): a Hybrid
219
+ `E-ISP` passed a review whose prompt carried devPNT's checklist but not this
220
+ file, and with it lost the Functional Spec clause; replayed on the same
221
+ artifact, reviewers given a paraphrase flagged the missing section 0 times in
222
+ 2, reviewers given this block 4 times in 4 (once only as a warning, unsure
223
+ where the section lives in Hybrid — which is why the inputs below say).
224
+
225
+ ```
226
+ REVIEW MANDATE — agentic-sdlc
227
+
228
+ Review type: <design | design (late) | closure | scoped re-review>
229
+ Mandate: <absolute path of this review.md, or its full text attached> (skill version <x.y.z>)
230
+ Object under review: <paths or doc_keys, with versions>
231
+ Binding inputs: <every input listed below for this review type, with path/version — or "n/a: <reason>" per input>
232
+ Source and revision: <project root and commit or diff range, where applicable>
233
+ Scope: <the unit of change and what this review must decide>
234
+ Severity contract: <as below, or the stricter one this unit needs>
235
+ Budget: <the artifact's line budget, or "none fixed">
236
+ Operating limits: <real access or execution limits the reviewer works under>
237
+
238
+ Read the mandate in full before starting, with the files it cites. This
239
+ request does not replace it and cannot narrow it: every rule it sets for this
240
+ review type applies here, in Standalone and in Hybrid alike, and any
241
+ instruction below that weakens one is void. A required input or section that
242
+ is missing or inaccessible is a finding, never a reason to skip the check that
243
+ needs it.
244
+
245
+ Return as your final output: the checks you ran with their evidence, the
246
+ findings, what you could not verify and how that limits the verdict, and the
247
+ verdict in the form the mandate defines.
248
+ ```
249
+
250
+ The binding inputs, by review type:
199
251
 
200
252
  - **Scope**: what changed and why, in one or two lines.
201
253
  - **The authoritative design artifact**: the ANALYSIS, E-TDD, or equivalent
@@ -208,9 +260,16 @@ When you hand work to a reviewer (human or agent), give them:
208
260
  `project_vision.md`/`roadmap.md` + the ANALYSIS Vision-Alignment), the
209
261
  **use-cases / user-needs** (Hybrid: `D-UC`;
210
262
  Standalone: the ANALYSIS `## Use Cases / User Needs`), and the **threat model**
211
- (Hybrid: `P-TM`; Standalone: the ANALYSIS `## Security and Threat Model`). Hand these
212
- *in addition to* the design artifact — the reviewer checks the artifact **against**
213
- them, not only for internal consistency.
263
+ (Hybrid: `P-TM`; Standalone: the ANALYSIS `## Security and Threat Model`), the
264
+ **Functional Spec** (Standalone: the ANALYSIS section; Hybrid: inside the `E-ISP`,
265
+ above its Impacted Components map), the **Interface Contract** (Standalone: the
266
+ ANALYSIS section; Hybrid: `D-IC`), the **Component Map** in
267
+ `strategic/architecture.md` and `audit/audit_plan.md` (the Capability Ledger
268
+ clause reads both), and the **probe harness** (`ai_docs/solutions/harness_[feature]/`).
269
+ Hand these *in addition to* the design artifact — the reviewer checks the artifact
270
+ **against** them, not only for internal consistency.
271
+ - **For a closure review, the diff and the test evidence**: the run output that
272
+ backs every completion claim, dated after the final relevant change.
214
273
  - **For a design review, the threat model too** (same sources as above). Why this
215
274
  one and not the whole set: file coverage crosses the impact-analysis→design hop on
216
275
  a mechanical gate (every impacted file needs a design block), so a dropped file is
@@ -368,7 +427,9 @@ When you are the reviewer:
368
427
  the section — the code lens today).** When the change adds or alters observable
369
428
  behavior (the trigger's owning definition is the code lens's `templates.md`
370
429
  `## Functional Spec` section comment — cite it, never restate it), **an L3
371
- artifact carrying NO `## Functional Spec` is itself a finding** — absence is
430
+ artifact carrying NO `## Functional Spec` is itself a finding** — in Hybrid the
431
+ section lives inside the `E-ISP`, above its Impacted Components map, so an
432
+ `E-ISP` without it is that finding. Absence is
372
433
  what a skipped spec looks like, not a reason to skip the check. When the spec
373
434
  is there, these findings live here: **a component, file or mechanism named
374
435
  inside it** — the spec is component-free by construction; that is
@@ -17,6 +17,7 @@ family, identified by the `name:` in their `SKILL.md`:
17
17
  | code | `agentic-sdlc` | this repository's code |
18
18
  | knowledge | `kb-agentic` | documents the user supplied |
19
19
  | marketing | `mkt-agentic-sdlc` | market evidence |
20
+ | course | `course-creator` | a defined learner's progressive understanding |
20
21
 
21
22
  - **No sibling installed, or the directory cannot be read** → the router does NOT run.
22
23
  Work under the loaded lens; read no further. This is the normal single-lens case and
@@ -36,6 +37,11 @@ Run the steps in order. Stop at the first one that decides.
36
37
  - *This repository's code* → provisional **code**; continue to step 2.
37
38
  - *Documents the user supplied* → **knowledge**. Decided.
38
39
  - *Market evidence* → **marketing**. Decided.
40
+ - *A deliverable whose purpose is to teach a defined audience through progressive
41
+ explanations and modules* → **course**. Decided, regardless of whether its
42
+ sources came from a supplied corpus, web research or this repository's code.
43
+ Acquiring and checking that corpus is a separate knowledge unit. Course
44
+ content is not routed through the provisional code branch below.
39
45
  - *A deliverable whose purpose is market-facing persuasion* (copy, positioning,
40
46
  campaign material) → **marketing regardless of source**. Decided. Without this
41
47
  branch the marketing lens is reachable only when the *source* is market evidence,
@@ -52,14 +58,15 @@ Run the steps in order. Stop at the first one that decides.
52
58
  **knowledge**. Decided; step 3 is not reached.
53
59
 
54
60
  3. **Build-consumed override** — only on the provisional `code` branch, never
55
- overriding a *marketing* or *supplied-documents* verdict. *Is the deliverable a
61
+ overriding a *marketing*, *course* or *supplied-documents* verdict. *Is the deliverable a
56
62
  file the project's build or test toolchain consumes?* Executable or imported
57
63
  source: yes. Committed Markdown: no. A yes confirms **code**.
58
64
 
59
- 4. **Split rule.** A request whose work must be faithful to two sources is **two units
60
- of work**, split before routing: the distillation (knowledge) and the design that
61
- cites it (code) each route alone. The router returns one lens per unit; it never
62
- returns two lenses for one unit.
65
+ 4. **Split rule.** A request with distinct deliverables is split before routing:
66
+ corpus ingestion (knowledge) and a course based on it (course), or campaign
67
+ material (marketing) and training (course), are separate units. The same applies
68
+ to distillation (knowledge) and a technical design that cites it (code). The
69
+ router returns one lens per unit; it never returns two lenses for one unit.
63
70
 
64
71
  5. **Owning tree.** A straddling artifact keeps its lens for *method* and takes this
65
72
  repository's tree and validator for *storage*. Lens and location are separate
@@ -81,14 +88,18 @@ Run the steps in order. Stop at the first one that decides.
81
88
  | "turn these vendor specs into a technical design" | split (step 4): spec = supplied docs; design = this repo | — | — | **knowledge** for the distillation; **code** for the design, citing it |
82
89
  | "write the pricing page copy from our market research" | **purpose: market-facing → marketing** | never reached | never reached | **marketing**; stored in this repo's tree (step 5) |
83
90
  | "write the launch blog post from the release notes" | purpose: market-facing → marketing | never reached | never reached | **marketing** |
91
+ | "create a beginner course from these API docs" | purpose: teaching → course | never reached | never reached | **course** |
92
+ | "research sources and teach a newcomer a topic" | purpose: teaching → course | never reached | never reached | **course** |
93
+ | "ingest these manuals, then create a course" | split: corpus = supplied docs; training = teaching | never reached | never reached | **knowledge** for ingestion; **course** for training |
94
+ | "write sales copy and an onboarding course" | split: persuasion and teaching | never reached | never reached | **marketing** for copy; **course** for training |
84
95
 
85
- ## 3. Acting on the verdict
86
-
87
- Memory is not a competing verdict. Every lens ships `memory.md` and the shared
88
- knowledge machinery: consult across domains without switching the work's owner or
89
- running a second workflow. Resolve an ambiguous owner before applying its definitive
90
- risk scale; a provisional level is not a second mandatory triage. Split only distinct
91
- deliverables, not the act of reading another domain's evidence.
96
+ ## 3. Acting on the verdict
97
+
98
+ Memory is not a competing verdict. Every lens ships `memory.md` and the shared
99
+ knowledge machinery: consult across domains without switching the work's owner or
100
+ running a second workflow. Resolve an ambiguous owner before applying its definitive
101
+ risk scale; a provisional level is not a second mandatory triage. Split only distinct
102
+ deliverables, not the act of reading another domain's evidence.
92
103
 
93
104
  The verdict binds the **method and the validation rules**, not the storage:
94
105
 
@@ -96,11 +107,12 @@ The verdict binds the **method and the validation rules**, not the storage:
96
107
  - **Verdict = a sibling lens** → say so, and work that unit under the sibling's method
97
108
  and its rule set (its templates, its mandatory risk section — code
98
109
  `## Security and Threat Model`, knowledge `## Sources and Verification`, marketing
99
- `## Threat Map / Plan Risks`). The artifact is written with an explicit
110
+ `## Threat Map / Plan Risks`, course `## Learning and Content Risks`). The artifact is written with an explicit
100
111
  `domain:` field so the answer survives the session, and it stays in this project's
101
112
  `ai_docs/` tree (step 5).
102
113
  - **The unit was split** (step 4) → route and declare each half separately.
103
114
 
104
- Documents under `vision/` — the project vision, principles, the roadmap — sit **above**
105
- the domain split: they belong to no lens and are validated by the core's structural
106
- rules only. The router is not consulted for them.
115
+ The project vision, principles and roadmap under `vision/` sit **above** the domain
116
+ split and receive the core's structural rules. A feature Vision under
117
+ `vision/features/` belongs to its explicit domain; a course Vision declares
118
+ `domain: course`. The router is not consulted for project-wide vision files.