@nurix/etna 0.18.0 → 0.18.1
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/README.md +6 -5
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/CLAUDE.md +7 -18
- package/data/harnesses/code/agents/brainstorm.md +3 -3
- package/data/harnesses/code/agents/change-review.md +13 -10
- package/data/harnesses/code/agents/harness-manager.md +15 -15
- package/data/harnesses/code/agents/maintenance.md +10 -3
- package/data/harnesses/code/agents/performance-review.md +5 -0
- package/data/harnesses/code/harness.json +1 -1
- package/data/harnesses/code/rules/general.md +40 -36
- package/data/harnesses/code/skills/boundary/SKILL.md +15 -42
- package/data/harnesses/code/skills/boundary/references/boundary-taxonomy.md +366 -304
- package/data/harnesses/code/skills/brainstorm/README.md +9 -9
- package/data/harnesses/code/skills/brainstorm/SKILL.md +15 -15
- package/data/harnesses/code/skills/brainstorm/harvest.md +2 -2
- package/data/harnesses/code/skills/brainstorm/templates/backlog.md +2 -2
- package/data/harnesses/code/skills/brainstorm/templates/build.md +6 -6
- package/data/harnesses/code/skills/brainstorm/templates/decisions.md +3 -3
- package/data/harnesses/code/skills/brainstorm/templates/doctrine.md +2 -2
- package/data/harnesses/code/skills/brainstorm/templates/domain-model.md +2 -2
- package/data/harnesses/code/skills/brainstorm/templates/glossary.md +2 -1
- package/data/harnesses/code/skills/brainstorm/templates/non-goals.md +3 -7
- package/data/harnesses/code/skills/brainstorm/templates/questions.md +6 -5
- package/data/harnesses/code/skills/brainstorm/templates/state.md +1 -8
- package/data/harnesses/code/skills/brainstorm/templates/tech.md +6 -6
- package/data/harnesses/code/skills/brainstorm/templates/thesis.md +2 -2
- package/data/harnesses/code/skills/distiller/SKILL.md +48 -177
- package/data/harnesses/code/skills/distiller/references/docs-mode.md +116 -343
- package/data/harnesses/code/skills/distiller/references/method.md +37 -109
- package/data/harnesses/code/skills/documentation/SKILL.md +9 -6
- package/data/harnesses/code/skills/documentation/references/examples.md +30 -61
- package/data/harnesses/code/skills/documentation/references/style-guide.md +59 -62
- package/data/harnesses/code/skills/documentation/references/templates.md +25 -33
- package/data/harnesses/code/skills/workflow-mapper/SKILL.md +32 -11
- package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +1 -1
- package/data/harnesses/code-fable/CLAUDE.md +12 -23
- package/data/harnesses/code-fable/agents/brainstorm.md +3 -3
- package/data/harnesses/code-fable/agents/change-review.md +13 -10
- package/data/harnesses/code-fable/agents/harness-manager.md +15 -15
- package/data/harnesses/code-fable/agents/maintenance.md +10 -3
- package/data/harnesses/code-fable/agents/performance-review.md +5 -0
- package/data/harnesses/code-fable/harness.json +1 -1
- package/data/harnesses/code-fable/rules/general.md +40 -36
- package/data/harnesses/code-fable/skills/boundary/SKILL.md +15 -42
- package/data/harnesses/code-fable/skills/boundary/references/boundary-taxonomy.md +366 -304
- package/data/harnesses/code-fable/skills/brainstorm/README.md +9 -9
- package/data/harnesses/code-fable/skills/brainstorm/SKILL.md +15 -15
- package/data/harnesses/code-fable/skills/brainstorm/harvest.md +2 -2
- package/data/harnesses/code-fable/skills/brainstorm/templates/backlog.md +2 -2
- package/data/harnesses/code-fable/skills/brainstorm/templates/build.md +6 -6
- package/data/harnesses/code-fable/skills/brainstorm/templates/decisions.md +3 -3
- package/data/harnesses/code-fable/skills/brainstorm/templates/doctrine.md +2 -2
- package/data/harnesses/code-fable/skills/brainstorm/templates/domain-model.md +2 -2
- package/data/harnesses/code-fable/skills/brainstorm/templates/glossary.md +2 -1
- package/data/harnesses/code-fable/skills/brainstorm/templates/non-goals.md +3 -7
- package/data/harnesses/code-fable/skills/brainstorm/templates/questions.md +6 -5
- package/data/harnesses/code-fable/skills/brainstorm/templates/state.md +1 -8
- package/data/harnesses/code-fable/skills/brainstorm/templates/tech.md +6 -6
- package/data/harnesses/code-fable/skills/brainstorm/templates/thesis.md +2 -2
- package/data/harnesses/code-fable/skills/distiller/SKILL.md +48 -177
- package/data/harnesses/code-fable/skills/distiller/references/docs-mode.md +116 -343
- package/data/harnesses/code-fable/skills/distiller/references/method.md +37 -109
- package/data/harnesses/code-fable/skills/documentation/SKILL.md +9 -6
- package/data/harnesses/code-fable/skills/documentation/references/examples.md +30 -61
- package/data/harnesses/code-fable/skills/documentation/references/style-guide.md +59 -62
- package/data/harnesses/code-fable/skills/documentation/references/templates.md +25 -33
- package/data/harnesses/code-fable/skills/workflow-mapper/SKILL.md +32 -11
- package/data/harnesses/code-fable/skills/workflow-mapper/references/patterns.md +1 -1
- package/data/harnesses/discover/CLAUDE.md +41 -109
- package/data/harnesses/discover/agents/api.md +11 -28
- package/data/harnesses/discover/agents/codebase.md +12 -30
- package/data/harnesses/discover/agents/community.md +9 -21
- package/data/harnesses/discover/agents/deployed-client-bundle.md +16 -67
- package/data/harnesses/discover/agents/distribution-artifacts.md +21 -59
- package/data/harnesses/discover/agents/docs.md +11 -20
- package/data/harnesses/discover/agents/infra-backend-fingerprint.md +28 -68
- package/data/harnesses/discover/agents/packages.md +12 -28
- package/data/harnesses/discover/agents/session.md +18 -50
- package/data/harnesses/discover/agents/website.md +9 -19
- package/data/harnesses/discover/agents/wire-capture.md +22 -72
- package/data/harnesses/discover/harness.json +1 -1
- package/data/harnesses/discover/rules/discovery.md +73 -182
- package/data/harnesses/discover/rules/evaluation.md +90 -98
- package/data/harnesses/discover/rules/ingestion.md +123 -322
- package/data/harnesses/discover/rules/self-correction.md +67 -92
- package/data/harnesses/discover/rules/tradecraft.md +201 -172
- package/data/harnesses/hr/CLAUDE.md +21 -51
- package/data/harnesses/hr/harness.json +1 -1
- package/data/harnesses/hr/skills/interview-eval/SKILL.md +23 -11
- package/data/harnesses/hr/skills/interview-eval/TEMPLATE.md +49 -29
- package/data/harnesses/hr/skills/interview-eval/rubric.md +30 -30
- package/data/harnesses/kb-agi/CLAUDE.md +8 -8
- package/data/harnesses/kb-agi/agents/kb-agi-init.md +31 -22
- package/data/harnesses/kb-agi/agents/kb-catch-stale.md +1 -1
- package/data/harnesses/kb-agi/agents/kb-find-gaps.md +1 -1
- package/data/harnesses/kb-agi/agents/kb-fix-links.md +1 -1
- package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +2 -2
- package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +2 -2
- package/data/harnesses/kb-agi/harness.json +1 -1
- package/package.json +1 -1
|
@@ -1,73 +1,47 @@
|
|
|
1
1
|
# distiller · mode `docs` — facts → documentation deltas
|
|
2
2
|
|
|
3
|
-
The shared knowledge root for this mode is still [`references/method.md`](method.md) —
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
file is the *procedure* that sequences those mechanisms one hop further down the gradient:
|
|
7
|
-
from `docs/memory/facts/` (warm, distilled cards) into proposed edits to `docs/` (the cold,
|
|
8
|
-
human-owned SSoT). It NEVER writes a doc on its own — it **drafts and presents**; the human
|
|
9
|
-
disposes (P7).
|
|
10
|
-
|
|
11
|
-
> `facts` mode = inbox → cards. `docs` mode = cards → *presented* doc deltas. One component,
|
|
12
|
-
> two modes, one algorithm root. distill② is the greenfield hop no surveyed tool has built
|
|
13
|
-
> (prior art stops at index/retrieval); the discipline below is what keeps it from corrupting
|
|
14
|
-
> documentation.
|
|
3
|
+
The shared knowledge root for this mode is still [`references/method.md`](method.md) — **read it first, in this mode too.** `docs` mode reuses its surprisal, EDU-decomposition, reconciliation (ADD/UPDATE/SUPERSEDE/NOOP), and bi-temporal vocabulary unchanged. This file is the _procedure_ that sequences those mechanisms one hop further down the gradient: from `docs/memory/facts/` (warm, distilled cards) into proposed edits to `docs/` (the cold, human-owned SSoT). It NEVER writes a doc on its own — it **drafts and presents**; the human disposes (P7).
|
|
4
|
+
|
|
5
|
+
> `facts` mode = inbox → cards. `docs` mode = cards → _presented_ doc deltas. One component, two modes, one algorithm root. distill② is the greenfield hop no surveyed tool has built (prior art stops at index/retrieval); the discipline below is what keeps it from corrupting documentation.
|
|
15
6
|
|
|
16
7
|
---
|
|
17
8
|
|
|
18
9
|
## The audit-trail invariant (the spine)
|
|
19
10
|
|
|
20
|
-
Every rule here serves one invariant, because the load-bearing moment in this mode is the
|
|
21
|
-
**human-approval moment**, and that moment is only trustworthy if the reviewer can
|
|
22
|
-
mechanically check every claim:
|
|
11
|
+
Every rule here serves one invariant, because the load-bearing moment in this mode is the **human-approval moment**, and that moment is only trustworthy if the reviewer can mechanically check every claim:
|
|
23
12
|
|
|
24
|
-
> **Two-way traceability.** Every drafted delta
|
|
25
|
-
> from (forward: delta → card). Every consumed card names the doc(s) it was digested into
|
|
26
|
-
> (backward: card → delta). Every card already names the sessions/commits it came from
|
|
27
|
-
> (`provenance`, from `facts` mode). The chain **doc-line → card → session/commit**
|
|
28
|
-
> must resolve end to end with no orphan link. A delta line with no card, or a card marked
|
|
29
|
-
> digested into a doc that does not contain its content, is a **defect**: the run fails its
|
|
30
|
-
> acceptance check, the line is not presented.
|
|
13
|
+
> **Two-way traceability.** Every drafted delta _line_ names the fact-card(s) it decomposes from (forward: delta → card). Every consumed card names the doc(s) it was digested into (backward: card → delta). Every card already names the sessions/commits it came from (`provenance`, from `facts` mode). The chain **doc-line → card → session/commit** must resolve end to end with no orphan link. A delta line with no card, or a card marked digested into a doc that does not contain its content, is a **defect**: the run fails its acceptance check, the line is not presented.
|
|
31
14
|
|
|
32
|
-
This mode introduces **no prose that is not a decomposition of a card** — decomposition-with-
|
|
33
|
-
citation, exactly as `facts` mode decomposes inbox entries into cards. If the agent cannot
|
|
34
|
-
cite a card for a sentence, that sentence is not written.
|
|
15
|
+
This mode introduces **no prose that is not a decomposition of a card** — decomposition-with- citation, exactly as `facts` mode decomposes inbox entries into cards. If the agent cannot cite a card for a sentence, that sentence is not written.
|
|
35
16
|
|
|
36
17
|
---
|
|
37
18
|
|
|
38
19
|
## Design lens: the six ways facts→docs corrupts documentation
|
|
39
20
|
|
|
40
|
-
Designed **failure-modes-outward.** Every step below names the hole it closes; if a step
|
|
41
|
-
seems heavy, trace it to the failure it prevents.
|
|
21
|
+
Designed **failure-modes-outward.** Every step below names the hole it closes; if a step seems heavy, trace it to the failure it prevents.
|
|
42
22
|
|
|
43
23
|
| # | Failure mode | What it looks like | The protection that closes it |
|
|
44
|
-
|
|
24
|
+
| --- | --- | --- | --- |
|
|
45
25
|
| **F1** | **Invention** | The draft asserts something no card says — interpolated, generalized, or hallucinated prose. | Decomposition-never-invention: every line carries `[from: fact-…]`; a line with no card behind it is illegal and dropped (Step 3, Acceptance A2). |
|
|
46
26
|
| **F2** | **Stale-card application** | A superseded/invalidated card is written into a doc as if current. | Bi-temporal gate: only `invalid_from: null` cards are eligible; superseded cards are skipped and named in the report (Step 2). |
|
|
47
27
|
| **F3** | **Double digestion** | The same card is written into the same doc twice across runs. | `digested_into:` on the card is the idempotency mark — a (card, doc) pair already recorded is not re-drafted (Resolution 3, Step 2). |
|
|
48
28
|
| **F4** | **Conflict steamrolling** | A card contradicts existing prose and the draft silently overwrites it. | Card-vs-prose conflicts become **D7 questions**, never edits (Resolution 2, Step 4). |
|
|
49
|
-
| **F5** | **Pillar-drift absorption** | A card contradicting a doctrine/decision headline is quietly written into a doc, laundering a belief change. | Pillar escape valve: such a card emits a
|
|
50
|
-
| **F6** | **Partial-approval limbo** | Human approves 3 of 5 lines; the card is marked fully digested (losing 2) or fully un-digested (re-proposing 3). | Partial digestion: `digested_into:` records only the (card → doc) pairs
|
|
29
|
+
| **F5** | **Pillar-drift absorption** | A card contradicting a doctrine/decision headline is quietly written into a doc, laundering a belief change. | Pillar escape valve: such a card emits a _propose-Brainstorming-Mode_ item, never a doc edit (Resolution 4, Step 2.4). |
|
|
30
|
+
| **F6** | **Partial-approval limbo** | Human approves 3 of 5 lines; the card is marked fully digested (losing 2) or fully un-digested (re-proposing 3). | Partial digestion: `digested_into:` records only the (card → doc) pairs _actually written_; declined lines → backlog (D10); the card recirculates only its un-applied content (Resolution 3, Step 6). |
|
|
51
31
|
|
|
52
|
-
Two structural failures sit above these: **frozen-record corruption** (editing a pillar, a
|
|
53
|
-
`Complete`/`Abandoned` plan, or changelog history — forbidden outright) and **axis merge**
|
|
54
|
-
(folding distill② into maintenance — refused: reconcile owns *structure*, maintenance owns
|
|
55
|
-
*docs-vs-code fidelity*, distill② owns the *facts→docs distillation* hop; three distinct axes,
|
|
56
|
-
P19).
|
|
32
|
+
Two structural failures sit above these: **frozen-record corruption** (editing a pillar, a `Complete`/`Abandoned` plan, or changelog history — forbidden outright) and **axis merge** (folding distill② into maintenance — refused: reconcile owns _structure_, maintenance owns _docs-vs-code fidelity_, distill② owns the _facts→docs distillation_ hop; three distinct axes, P19).
|
|
57
33
|
|
|
58
34
|
---
|
|
59
35
|
|
|
60
36
|
## Execution model
|
|
61
37
|
|
|
62
|
-
Runs **in the main session.** No standing sub-agent, no daemon, no cron, no hook self-trigger
|
|
63
|
-
(P6). The harness proposes; the user disposes. Invoked one of three ways, all human-gated:
|
|
38
|
+
Runs **in the main session.** No standing sub-agent, no daemon, no cron, no hook self-trigger (P6). The harness proposes; the user disposes. Invoked one of three ways, all human-gated:
|
|
64
39
|
|
|
65
40
|
1. The user asks (`distiller docs`, "distill the facts into docs", "draft pending doc deltas").
|
|
66
41
|
2. The **Completion flow** points at it (one router line in the kit `CLAUDE.md` — Resolution 5a).
|
|
67
42
|
3. The user accepts the **maintenance threshold proposal** (≥N undigested cards map to one doc — Resolution 5b).
|
|
68
43
|
|
|
69
|
-
In every path the output is **a presented draft, never a written doc.** Nothing mutates a doc
|
|
70
|
-
without an explicit human "yes" on that specific draft.
|
|
44
|
+
In every path the output is **a presented draft, never a written doc.** Nothing mutates a doc without an explicit human "yes" on that specific draft.
|
|
71
45
|
|
|
72
46
|
### Invocation shapes
|
|
73
47
|
|
|
@@ -77,100 +51,54 @@ distiller docs --feature <slug> # just-completed feature → resolve to its
|
|
|
77
51
|
distiller docs --doc <path> # threshold path / direct: digest cards touching one named doc
|
|
78
52
|
```
|
|
79
53
|
|
|
80
|
-
`docs` mode runs against **one target doc at a time** — the unit of a delta is a single doc.
|
|
81
|
-
The Completion caller uses the bare/`--feature` form (it knows what just shipped); the
|
|
82
|
-
threshold caller (maintenance) uses `--doc` (it knows which doc the cards piled up against).
|
|
83
|
-
A card-first run may surface several single-doc deltas; each is presented and approved
|
|
84
|
-
independently.
|
|
54
|
+
`docs` mode runs against **one target doc at a time** — the unit of a delta is a single doc. The Completion caller uses the bare/`--feature` form (it knows what just shipped); the threshold caller (maintenance) uses `--doc` (it knows which doc the cards piled up against). A card-first run may surface several single-doc deltas; each is presented and approved independently.
|
|
85
55
|
|
|
86
56
|
---
|
|
87
57
|
|
|
88
58
|
## Procedure (executable, numbered)
|
|
89
59
|
|
|
90
|
-
> Each step names the failure mode(s) it closes. Ordering is load-bearing: the pillar check
|
|
91
|
-
> precedes drafting (a belief-changing card never reaches the draft); the digestion mark is
|
|
92
|
-
> written **last** (a crash re-presents rather than silently swallows — the mirror of `facts`
|
|
93
|
-
> mode's "consume the digested entries last").
|
|
60
|
+
> Each step names the failure mode(s) it closes. Ordering is load-bearing: the pillar check precedes drafting (a belief-changing card never reaches the draft); the digestion mark is written **last** (a crash re-presents rather than silently swallows — the mirror of `facts` mode's "consume the digested entries last").
|
|
94
61
|
|
|
95
62
|
### 0. Read the roots
|
|
96
63
|
|
|
97
|
-
Read [`method.md`](method.md) (surprisal / EDU / reconciliation / bi-temporal vocabulary) and
|
|
98
|
-
this file. Confirm the target doc exists, or note that none does (Edge Case A).
|
|
64
|
+
Read [`method.md`](method.md) (surprisal / EDU / reconciliation / bi-temporal vocabulary) and this file. Confirm the target doc exists, or note that none does (Edge Case A).
|
|
99
65
|
|
|
100
66
|
### 1. Resolve the target doc, read the three roots in order
|
|
101
67
|
|
|
102
68
|
1. `method.md` (algorithm vocabulary).
|
|
103
|
-
2. The **target doc** — full current prose + its `owns`/`touches` frontmatter. This is the
|
|
104
|
-
SSoT you are proposing to revise; you read it before you draft so conflicts surface as
|
|
105
|
-
questions, not silent overwrites.
|
|
69
|
+
2. The **target doc** — full current prose + its `owns`/`touches` frontmatter. This is the SSoT you are proposing to revise; you read it before you draft so conflicts surface as questions, not silent overwrites.
|
|
106
70
|
- `--doc <path>` → that doc.
|
|
107
|
-
- `--feature <slug>` / bare → the spec that just flipped to `Active` (Completion names it),
|
|
108
|
-
or the feature doc whose `owns` glob covers the plan's Proposed-Changes paths. Glob
|
|
109
|
-
`docs/{features,modules/*/features}/**/*.md`, match `owns` against changed paths.
|
|
110
|
-
Architecture/operations docs have no `owns` — for those, fall to entity/semantic match.
|
|
71
|
+
- `--feature <slug>` / bare → the spec that just flipped to `Active` (Completion names it), or the feature doc whose `owns` glob covers the plan's Proposed-Changes paths. Glob `docs/{features,modules/*/features}/**/*.md`, match `owns` against changed paths. Architecture/operations docs have no `owns` — for those, fall to entity/semantic match.
|
|
111
72
|
- No doc resolves → Edge Case A.
|
|
112
|
-
3. The **pillar headlines** — the doctrine pillar (`## Pn —` headlines) and the decisions
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
has reversed). Headlines only, never the bodies — this is the conservative
|
|
119
|
-
contradiction-check substrate (Resolution 4).
|
|
120
|
-
|
|
121
|
-
### 2. INPUT SELECTION — gather the cards "touching" the target (Resolution 1) — *closes F2, F3, F5*
|
|
122
|
-
|
|
123
|
-
1. **Structural retriever (always runs, qmd-independent).** Read every card in
|
|
124
|
-
`docs/memory/facts/*.md`. A card *structurally touches* the target when its `provenance`
|
|
125
|
-
paths or `entities` intersect the target's `owns`/`touches` globs — match defined precisely
|
|
126
|
-
in Resolution 1.
|
|
127
|
-
2. **Semantic retriever (qmd, optional).** If `command -v qmd` succeeds, for the target's
|
|
128
|
-
identity (title + each `owns` glob stem + any `anchors:` query) run
|
|
129
|
-
`qmd query --format json -c {repo}-facts "<the doc's subject>"`. `{repo}` = repo dir name;
|
|
130
|
-
scope with `-c` always; repeat `-c` per relevant `{repo}-*` facts collection (the set
|
|
131
|
-
`qmd collection list` names). qmd absent ⇒ skip silently, note in the report that selection
|
|
132
|
-
ran structural-only (changes recall, not correctness).
|
|
73
|
+
3. The **pillar headlines** — the doctrine pillar (`## Pn —` headlines) and the decisions pillar (`## Dn —` headlines) plus each one's one-line Principle/Decision statement. Read **every** decision headline except those marked superseded: a decision carrying a `Reversed by D-M` marker (or a legacy `Status: tentative`) is NOT a binding pillar headline and is skipped; absence of any status marker means the decision is live (the new append-only model has no `Status: committed` field — a live decision is simply one nothing has reversed). Headlines only, never the bodies — this is the conservative contradiction-check substrate (Resolution 4).
|
|
74
|
+
|
|
75
|
+
### 2. INPUT SELECTION — gather the cards "touching" the target (Resolution 1) — _closes F2, F3, F5_
|
|
76
|
+
|
|
77
|
+
1. **Structural retriever (always runs, qmd-independent).** Read every card in `docs/memory/facts/*.md`. A card _structurally touches_ the target when its `provenance` paths or `entities` intersect the target's `owns`/`touches` globs — match defined precisely in Resolution 1.
|
|
78
|
+
2. **Semantic retriever (qmd, optional).** If `command -v qmd` succeeds, for the target's identity (title + each `owns` glob stem + any `anchors:` query) run `qmd query --format json -c {repo}-facts "<the doc's subject>"`. `{repo}` = repo dir name; scope with `-c` always; repeat `-c` per relevant `{repo}-*` facts collection (the set `qmd collection list` names). qmd absent ⇒ skip silently, note in the report that selection ran structural-only (changes recall, not correctness).
|
|
133
79
|
3. **Bi-temporal + digestion gate (F2, F3).** From the union, drop:
|
|
134
80
|
- any card with `invalid_from` ≠ `null` (superseded — list as "skipped: superseded");
|
|
135
81
|
- any card whose `digested_into:` already lists the target doc path (already consumed here);
|
|
136
|
-
- any card whose `superseded_by:` chain leads to a live card already in the set (the live
|
|
137
|
-
card wins; keep the superseded one out of drafting, keep its trail — Edge Case D).
|
|
138
|
-
What remains is the **working card-set**.
|
|
82
|
+
- any card whose `superseded_by:` chain leads to a live card already in the set (the live card wins; keep the superseded one out of drafting, keep its trail — Edge Case D). What remains is the **working card-set**.
|
|
139
83
|
4. **Partition the working card-set (F5):**
|
|
140
|
-
- **pillar-conflicting** — cards in explicit headline-level conflict with a pillar/decision
|
|
141
|
-
|
|
142
|
-
drafting, so a belief-changing fact can never be laundered into prose.
|
|
143
|
-
- **doc-bound** — everything else (most cards).
|
|
144
|
-
A card can be both: handle both arms; do not let one suppress the other.
|
|
84
|
+
- **pillar-conflicting** — cards in explicit headline-level conflict with a pillar/decision (Resolution 4). These NEVER become a doc edit; they route to the escape valve **before** drafting, so a belief-changing fact can never be laundered into prose.
|
|
85
|
+
- **doc-bound** — everything else (most cards). A card can be both: handle both arms; do not let one suppress the other.
|
|
145
86
|
|
|
146
|
-
### 3. DELTA DRAFTING — classify, then decompose doc-bound cards (Resolution 2) —
|
|
87
|
+
### 3. DELTA DRAFTING — classify, then decompose doc-bound cards (Resolution 2) — _closes F1, F4_
|
|
147
88
|
|
|
148
|
-
First **surprisal-gate** each doc-bound card against the
|
|
149
|
-
whose content the doc already states is predictable ⇒ **NOOP** — draft nothing, but still mark
|
|
150
|
-
it digested on accept (Step 5; it is absorbed, so it must not re-surface forever). This is the
|
|
151
|
-
only retention signal; no importance scores.
|
|
89
|
+
First **surprisal-gate** each doc-bound card against the _doc_ (method §1, retargeted): a card whose content the doc already states is predictable ⇒ **NOOP** — draft nothing, but still mark it digested on accept (Step 5; it is absorbed, so it must not re-surface forever). This is the only retention signal; no importance scores.
|
|
152
90
|
|
|
153
|
-
For each surviving card, classify against existing prose — the card-vs-doc decision (method §3,
|
|
154
|
-
retargeted), exactly one of:
|
|
91
|
+
For each surviving card, classify against existing prose — the card-vs-doc decision (method §3, retargeted), exactly one of:
|
|
155
92
|
|
|
156
93
|
- **EXTEND** — adds behavior/rationale the doc lacks, no conflict → draft an additive line.
|
|
157
|
-
- **REFINE** — sharpens an existing doc claim that is incomplete, not wrong → draft an in-place
|
|
158
|
-
|
|
159
|
-
- **
|
|
160
|
-
question; draft the line only *conditionally*, gated on the answer (F4).
|
|
161
|
-
- **ESCALATE** — contradicts a pillar headline → already routed to the valve in Step 2.4
|
|
162
|
-
(Resolution 4); never drafted here.
|
|
94
|
+
- **REFINE** — sharpens an existing doc claim that is incomplete, not wrong → draft an in-place refinement (additive; never deletes prose).
|
|
95
|
+
- **CONFLICT** — card and prose disagree on a matter of fact → **do not resolve.** Emit a D7 question; draft the line only _conditionally_, gated on the answer (F4).
|
|
96
|
+
- **ESCALATE** — contradicts a pillar headline → already routed to the valve in Step 2.4 (Resolution 4); never drafted here.
|
|
163
97
|
- **NOOP** — doc already states it → mark digested, draft nothing.
|
|
164
98
|
|
|
165
|
-
For each EXTEND/REFINE card, decide which **allowed section** it informs (Resolution 2 fixes
|
|
166
|
-
the allow-list) and draft the smallest faithful prose change. Every drafted line carries an
|
|
167
|
-
inline provenance marker `[from: fact-<slug>]` for each contributing card. These markers are
|
|
168
|
-
**scaffolding for the review moment, not final doc text** — stripped on accept (Step 5.1), so
|
|
169
|
-
the human-owned prose stays clean. The durable forward-link survives as the card's
|
|
170
|
-
`digested_into:` back-pointer.
|
|
99
|
+
For each EXTEND/REFINE card, decide which **allowed section** it informs (Resolution 2 fixes the allow-list) and draft the smallest faithful prose change. Every drafted line carries an inline provenance marker `[from: fact-<slug>]` for each contributing card. These markers are **scaffolding for the review moment, not final doc text** — stripped on accept (Step 5.1), so the human-owned prose stays clean. The durable forward-link survives as the card's `digested_into:` back-pointer.
|
|
171
100
|
|
|
172
|
-
The output of this step is a **single presented delta document** (in chat, not written to
|
|
173
|
-
disk):
|
|
101
|
+
The output of this step is a **single presented delta document** (in chat, not written to disk):
|
|
174
102
|
|
|
175
103
|
```
|
|
176
104
|
TARGET: docs/features/memory-capture.md
|
|
@@ -198,61 +126,38 @@ TARGET: docs/features/memory-capture.md
|
|
|
198
126
|
──────────────────────────────────────────────────────────
|
|
199
127
|
```
|
|
200
128
|
|
|
201
|
-
### 4. PRESENT and await disposition — never auto-write (locked default #4) —
|
|
129
|
+
### 4. PRESENT and await disposition — never auto-write (locked default #4) — _the gate itself_
|
|
202
130
|
|
|
203
|
-
Present the delta document in chat and **stop.** The agent does not edit the target doc, write
|
|
204
|
-
the changelog, or touch any card frontmatter at this point. The human disposes:
|
|
131
|
+
Present the delta document in chat and **stop.** The agent does not edit the target doc, write the changelog, or touch any card frontmatter at this point. The human disposes:
|
|
205
132
|
|
|
206
133
|
- **Accept (whole or per-line)** → Step 5.
|
|
207
|
-
- **Accept with edits** → the human's edits are authored prose; apply them as doc text, but
|
|
208
|
-
digestion-marking (Step 5) still records the contributing cards as evidence consumed (the
|
|
209
|
-
human edited the *abstraction*; the *evidence* is unchanged). Lines the human deletes
|
|
210
|
-
entirely → their sole-source cards are **not** marked digested (nothing landed for them).
|
|
134
|
+
- **Accept with edits** → the human's edits are authored prose; apply them as doc text, but digestion-marking (Step 5) still records the contributing cards as evidence consumed (the human edited the _abstraction_; the _evidence_ is unchanged). Lines the human deletes entirely → their sole-source cards are **not** marked digested (nothing landed for them).
|
|
211
135
|
- **Decline** → Step 6 (backlog at par, D10).
|
|
212
|
-
- **Blocked-on-question (CONFLICT)** → leave undigested; the question re-surfaces next run if
|
|
213
|
-
unanswered. Not backlogged unless the user explicitly declines to engage it.
|
|
136
|
+
- **Blocked-on-question (CONFLICT)** → leave undigested; the question re-surfaces next run if unanswered. Not backlogged unless the user explicitly declines to engage it.
|
|
214
137
|
|
|
215
|
-
### 5. ON ACCEPT — write doc, write changelog, mark digestion LAST (Resolution 3) —
|
|
138
|
+
### 5. ON ACCEPT — write doc, write changelog, mark digestion LAST (Resolution 3) — _closes F3, F6_
|
|
216
139
|
|
|
217
|
-
Apply in this order so a crash leaves the audit trail consistent (doc content exists before
|
|
218
|
-
any card claims to have landed in it):
|
|
140
|
+
Apply in this order so a crash leaves the audit trail consistent (doc content exists before any card claims to have landed in it):
|
|
219
141
|
|
|
220
|
-
1. **Write the accepted prose into the target doc**, stripping the `[from: ...]` markers from
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
feature/changelog templates — this mode carries no copy of them.
|
|
224
|
-
2. **Write the changelog entry** if the delta included one (via the `documentation` skill's
|
|
225
|
-
Changelog template, `docs/history/changelog/`). Append-only; never edit an existing entry.
|
|
226
|
-
3. **Mark digestion LAST:** on each card that contributed an *accepted* line (and each NOOP'd
|
|
227
|
-
card the doc already stated), append the target doc path (and changelog path, if it
|
|
228
|
-
contributed there) to `digested_into:`. Marking last means a crash mid-write re-presents
|
|
229
|
-
the delta rather than falsely claiming digestion.
|
|
142
|
+
1. **Write the accepted prose into the target doc**, stripping the `[from: ...]` markers from the final text (review scaffolding; the doc's prose is the human-owned abstraction). Prefer handing approved lines to the **`documentation` skill**, which owns the feature/changelog templates — this mode carries no copy of them.
|
|
143
|
+
2. **Write the changelog entry** if the delta included one (via the `documentation` skill's Changelog template, `docs/history/changelog/`). Append-only; never edit an existing entry.
|
|
144
|
+
3. **Mark digestion LAST:** on each card that contributed an _accepted_ line (and each NOOP'd card the doc already stated), append the target doc path (and changelog path, if it contributed there) to `digested_into:`. Marking last means a crash mid-write re-presents the delta rather than falsely claiming digestion.
|
|
230
145
|
|
|
231
|
-
Cards STAY — `digested_into:` is the only mutation; bi-temporal rules from `method.md` still
|
|
232
|
-
apply (a card is never deleted; supersession is `facts` mode's surface). The card is now both
|
|
233
|
-
evidence-for-the-doc and a queryable audit record of *where its content went*.
|
|
146
|
+
Cards STAY — `digested_into:` is the only mutation; bi-temporal rules from `method.md` still apply (a card is never deleted; supersession is `facts` mode's surface). The card is now both evidence-for-the-doc and a queryable audit record of _where its content went_.
|
|
234
147
|
|
|
235
|
-
### 6. ON DECLINE — backlog at par, deduped (D10) —
|
|
148
|
+
### 6. ON DECLINE — backlog at par, deduped (D10) — _closes F6_
|
|
236
149
|
|
|
237
|
-
Append the declined delta to `docs/history/backlog.md` at the finding's own P0–P3 severity
|
|
238
|
-
(same scale as code work), deduped:
|
|
150
|
+
Append the declined delta to `docs/history/backlog.md` at the finding's own P0–P3 severity (same scale as code work), deduped:
|
|
239
151
|
|
|
240
152
|
```
|
|
241
153
|
- **[P2]** distiller-docs proposed updating docs/features/memory-capture.md §Current Behavior from fact-qmd-optional-retrieval-lens (declined) — discovered by distiller docs
|
|
242
154
|
```
|
|
243
155
|
|
|
244
|
-
Dedupe by (target doc § section, contributing card-ids): if an identical pending item exists,
|
|
245
|
-
leave it. Never a segregated section, never auto-lowest-tier (D10). Never block Completion.
|
|
246
|
-
The declined cards stay undigested, so they re-surface next pass.
|
|
156
|
+
Dedupe by (target doc § section, contributing card-ids): if an identical pending item exists, leave it. Never a segregated section, never auto-lowest-tier (D10). Never block Completion. The declined cards stay undigested, so they re-surface next pass.
|
|
247
157
|
|
|
248
158
|
### 7. Report (in chat)
|
|
249
159
|
|
|
250
|
-
Target doc; working-set cards; lines drafted and their cards; cards classified EXTEND / REFINE
|
|
251
|
-
/ NOOP / CONFLICT-question / ESCALATE / skipped-as-superseded; questions raised; pillar-conflict
|
|
252
|
-
items verbatim; on accept — doc + changelog written and cards marked digested; on decline — the
|
|
253
|
-
backlog line. If qmd was absent, the one advisory line that selection ran structural-only. A
|
|
254
|
-
run where no undigested card touches the target is **valid**: say "no undigested cards touch
|
|
255
|
-
{target}," do not pad — and **touch nothing**.
|
|
160
|
+
Target doc; working-set cards; lines drafted and their cards; cards classified EXTEND / REFINE / NOOP / CONFLICT-question / ESCALATE / skipped-as-superseded; questions raised; pillar-conflict items verbatim; on accept — doc + changelog written and cards marked digested; on decline — the backlog line. If qmd was absent, the one advisory line that selection ran structural-only. A run where no undigested card touches the target is **valid**: say "no undigested cards touch {target}," do not pad — and **touch nothing**.
|
|
256
161
|
|
|
257
162
|
---
|
|
258
163
|
|
|
@@ -260,72 +165,37 @@ run where no undigested card touches the target is **valid**: say "no undigested
|
|
|
260
165
|
|
|
261
166
|
### Resolution 1 — INPUT SELECTION: what "touching" means, precisely
|
|
262
167
|
|
|
263
|
-
A card **touches** the target doc iff it satisfies **either** retriever, and is not removed by
|
|
264
|
-
the Step-2.3 gates. "Touching" is a **union of retrievers, intersected with eligibility** —
|
|
265
|
-
broad capture, conservative gating.
|
|
168
|
+
A card **touches** the target doc iff it satisfies **either** retriever, and is not removed by the Step-2.3 gates. "Touching" is a **union of retrievers, intersected with eligibility** — broad capture, conservative gating.
|
|
266
169
|
|
|
267
170
|
**(a) Structural intersection (exact, always evaluated).** True when ANY of:
|
|
268
171
|
|
|
269
|
-
1. **Provenance match (STRONG signal).** A `commit <sha>` entry in the card's `provenance`
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
glob, the doc title, or a symbol the doc explicitly names. **Bare prose mentions do NOT
|
|
278
|
-
count** — only declared ownership, so "touching" can't be triggered by a doc that merely
|
|
279
|
-
discusses an entity it doesn't own.
|
|
280
|
-
|
|
281
|
-
**(b) Semantic neighborhood (qmd, optional, recall-only).** A card returned by
|
|
282
|
-
`qmd query -c {repo}-facts "<doc subject>"` within qmd's default result window. Semantic hits
|
|
283
|
-
with **no** structural intersection are still candidates but flagged `[semantic-only]` in the
|
|
284
|
-
delta — the link is associative, not provenance-grounded, so the reviewer treats it as
|
|
285
|
-
lower-trust and may reject on link-strength alone.
|
|
286
|
-
|
|
287
|
-
The candidate set is the **union** of (a) and (b); correctness rests on (a) (exact,
|
|
288
|
-
deterministic, qmd-independent), (b) only raises recall. This is why the mode runs fully
|
|
289
|
-
without qmd, and why the maintenance threshold (Resolution 5b) counts on (a) alone.
|
|
290
|
-
|
|
291
|
-
A card may touch **several** docs (its entities span modules) — expected, handled by partial
|
|
292
|
-
digestion (Resolution 3): the card is processed once per target doc, and `digested_into:`
|
|
293
|
-
accumulates each doc it actually fed.
|
|
172
|
+
1. **Provenance match (STRONG signal).** A `commit <sha>` entry in the card's `provenance` resolves to changed files (`git show --name-only <sha>` when the commit is local); a changed file under the target's `owns`/`touches` globs is a match. (`session <id>` entries carry no paths and do not participate; an ADR/brainstorm path matches the globs directly.) This is strong because the card derives from a commit that edited code the doc owns.
|
|
173
|
+
2. **Entity match (SUPPORTING signal).** A normalized name in the card's `entities` equals (case-insensitively, after kebab/camel normalization) a module/feature stem in an `owns` glob, the doc title, or a symbol the doc explicitly names. **Bare prose mentions do NOT count** — only declared ownership, so "touching" can't be triggered by a doc that merely discusses an entity it doesn't own.
|
|
174
|
+
|
|
175
|
+
**(b) Semantic neighborhood (qmd, optional, recall-only).** A card returned by `qmd query -c {repo}-facts "<doc subject>"` within qmd's default result window. Semantic hits with **no** structural intersection are still candidates but flagged `[semantic-only]` in the delta — the link is associative, not provenance-grounded, so the reviewer treats it as lower-trust and may reject on link-strength alone.
|
|
176
|
+
|
|
177
|
+
The candidate set is the **union** of (a) and (b); correctness rests on (a) (exact, deterministic, qmd-independent), (b) only raises recall. This is why the mode runs fully without qmd, and why the maintenance threshold (Resolution 5b) counts on (a) alone.
|
|
178
|
+
|
|
179
|
+
A card may touch **several** docs (its entities span modules) — expected, handled by partial digestion (Resolution 3): the card is processed once per target doc, and `digested_into:` accumulates each doc it actually fed.
|
|
294
180
|
|
|
295
181
|
### Resolution 2 — DELTA DRAFTING RULES: what a fact may update, with provenance
|
|
296
182
|
|
|
297
183
|
**Allow-list of writable targets** (a card may inform ONLY these):
|
|
298
184
|
|
|
299
185
|
| Target | What a card may do | Why bounded here |
|
|
300
|
-
|
|
301
|
-
| **`## Current Behavior`** (feature doc) | Add/modify a sentence describing how the system works
|
|
302
|
-
| **`## Background`** — why-built metadata (feature doc) | Add a sentence of
|
|
186
|
+
| --- | --- | --- |
|
|
187
|
+
| **`## Current Behavior`** (feature doc) | Add/modify a sentence describing how the system works _today_, when a card reports a now-true behavior the section omits or contradicts. The primary target. | The "how it works now" section cards are evidence for. |
|
|
188
|
+
| **`## Background`** — why-built metadata (feature doc) | Add a sentence of _why_ a decision was made, when a card records a decision/constraint/reversal Background omits. | Cards carry the "why" the loop captured; Background is its home. |
|
|
303
189
|
| **`## Architecture` / `## Key Functions`** (feature doc) | Additive correction only when a card names a concrete, code-anchored fact (a new function, a moved file). Prefer Current Behavior unless the card is structural. | Code-anchored structure, not prose. |
|
|
304
|
-
| **A new changelog entry** in `docs/history/changelog/` (via `documentation` skill's Changelog template, `### Added`/`### Modified`/`### Removed`) | Draft a changelog line for a code change a card witnesses, when a plan just completed. | Append-only history; a
|
|
305
|
-
|
|
306
|
-
**Never writable by distill②** (hard stops): `## Goal`, `## Goals & Non-Goals`, `## Approach`,
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
**
|
|
311
|
-
|
|
312
|
-
**
|
|
313
|
-
`[from: fact-<slug>]` for each contributing card. A line with no such tag is a **defect** — not
|
|
314
|
-
presented (Acceptance A2). On accept the tag is stripped from the final doc prose (it was
|
|
315
|
-
review scaffolding); the durable forward-link survives as `digested_into:` (Resolution 3) — so
|
|
316
|
-
traceability is preserved without polluting human-owned prose.
|
|
317
|
-
|
|
318
|
-
**Decomposition, never invention.** As in `facts` mode: one card may yield several doc lines;
|
|
319
|
-
the agent rephrases the card's atomic statement into doc-fit prose but **adds no claim the card
|
|
320
|
-
does not support.** When two cards are needed for one line, both ids attach. If doc-fit prose
|
|
321
|
-
would require a fact in no card, that fact is *missing* — raise it as a gap in the report, do
|
|
322
|
-
not invent it.
|
|
323
|
-
|
|
324
|
-
**Conflict → question (D7 phrasing), never silent resolution.** When a card contradicts an
|
|
325
|
-
existing sentence, the agent does NOT overwrite. It emits a D7 question — *"docs/x.md §S says
|
|
326
|
-
A; fact-<slug> (from <provenance>) says B. Confirm the doc is stale before I revise it."* —
|
|
327
|
-
and drafts the conflicting line only as a *conditional* proposal gated on the answer. Docs stay
|
|
328
|
-
SSoT: the card is evidence for revision, the human decides.
|
|
190
|
+
| **A new changelog entry** in `docs/history/changelog/` (via `documentation` skill's Changelog template, `### Added`/`### Modified`/`### Removed`) | Draft a changelog line for a code change a card witnesses, when a plan just completed. | Append-only history; a _new_ file, never an edit. |
|
|
191
|
+
|
|
192
|
+
**Never writable by distill②** (hard stops): `## Goal`, `## Goals & Non-Goals`, `## Approach`, `## Open Questions`, `## State`, frontmatter `owns`/`touches`/`anchors` (maintenance/spec axis — P19), any **pillar** file, any **plan** (frozen), any **existing** changelog entry (frozen history), any **boundary** file. A card implying one of these needs a change becomes a **question** (below) or, for pillars, an **escape item** (Resolution 4).
|
|
193
|
+
|
|
194
|
+
**Per-line provenance (the invariant, mechanized).** Every drafted line carries `[from: fact-<slug>]` for each contributing card. A line with no such tag is a **defect** — not presented (Acceptance A2). On accept the tag is stripped from the final doc prose (it was review scaffolding); the durable forward-link survives as `digested_into:` (Resolution 3) — so traceability is preserved without polluting human-owned prose.
|
|
195
|
+
|
|
196
|
+
**Decomposition, never invention.** As in `facts` mode: one card may yield several doc lines; the agent rephrases the card's atomic statement into doc-fit prose but **adds no claim the card does not support.** When two cards are needed for one line, both ids attach. If doc-fit prose would require a fact in no card, that fact is _missing_ — raise it as a gap in the report, do not invent it.
|
|
197
|
+
|
|
198
|
+
**Conflict → question (D7 phrasing), never silent resolution.** When a card contradicts an existing sentence, the agent does NOT overwrite. It emits a D7 question — _"docs/x.md §S says A; fact-<slug> (from <provenance>) says B. Confirm the doc is stale before I revise it."_ — and drafts the conflicting line only as a _conditional_ proposal gated on the answer. Docs stay SSoT: the card is evidence for revision, the human decides.
|
|
329
199
|
|
|
330
200
|
### Resolution 3 — DIGESTION MARKING: `digested_into:` semantics
|
|
331
201
|
|
|
@@ -337,7 +207,7 @@ id: fact-qmd-optional-retrieval-lens
|
|
|
337
207
|
valid_from: 2026-06-04
|
|
338
208
|
invalid_from: null
|
|
339
209
|
superseded_by: null
|
|
340
|
-
digested_into:
|
|
210
|
+
digested_into: # ← added by docs mode, on accept, never on draft
|
|
341
211
|
- docs/features/memory-capture.md
|
|
342
212
|
- docs/history/changelog/2026-06-04-qmd-lens.md
|
|
343
213
|
entities: [qmd, retrieval-lens, per-subtree-collections, inbox]
|
|
@@ -345,67 +215,28 @@ provenance: [session e3c4a623, commit d262e18]
|
|
|
345
215
|
---
|
|
346
216
|
```
|
|
347
217
|
|
|
348
|
-
A **flat list of doc paths** — the brief's shape. Track
|
|
349
|
-
sentence; whole-card-vs-target is the granularity, which keeps selection (Step 2.3) a simple
|
|
350
|
-
list-membership test.
|
|
218
|
+
A **flat list of doc paths** — the brief's shape. Track _which doc_ a card landed in, not which sentence; whole-card-vs-target is the granularity, which keeps selection (Step 2.3) a simple list-membership test.
|
|
351
219
|
|
|
352
220
|
Semantics:
|
|
353
221
|
|
|
354
|
-
- **Absent / empty** ⇒ undigested ⇒ eligible for selection and counted by the maintenance
|
|
355
|
-
|
|
356
|
-
- **A
|
|
357
|
-
|
|
358
|
-
- **
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
because selection drops a card only when the list already contains *the current target*. A
|
|
362
|
-
card stays in circulation until every doc it touches has consumed it. No separate flag.
|
|
363
|
-
Lines the human declined are not represented in the list (their cards recirculate); only
|
|
364
|
-
*applied* content is recorded.
|
|
365
|
-
- **One card, several docs** ⇒ the list grows **append-only across runs.** Each entry is
|
|
366
|
-
independently meaningful; order is run-order. **Never rewrite or remove an entry** — a doc
|
|
367
|
-
later reverted does not un-digest the card (the card *was* digested there at that transaction
|
|
368
|
-
time; the doc's own git history records the revert). This mirrors `method.md`'s bi-temporal
|
|
369
|
-
stance: the trail only grows.
|
|
370
|
-
- **Supersession interaction (F2 + F4 seam).** If a digested card is later superseded by a
|
|
371
|
-
`facts`-mode run, the *old* card keeps its `digested_into:` (it documents what the doc once
|
|
372
|
-
said and why) AND gains `invalid_from:`/`superseded_by:` from the normal bi-temporal path.
|
|
373
|
-
The *new* card is undigested → on the next `docs` run its content surfaces the now-stale doc
|
|
374
|
-
prose as a **CONFLICT question** (Resolution 2), never an auto-rewrite. The trail shows: doc
|
|
375
|
-
prose ← old card (now invalid) ← superseded_by → new card (pending). No link is ever broken.
|
|
376
|
-
|
|
377
|
-
`digested_into:` is the **only** field `docs` mode writes on a card. It never edits the card's
|
|
378
|
-
body, `provenance`, `entities`, or bi-temporal fields — those are `facts` mode's surface.
|
|
222
|
+
- **Absent / empty** ⇒ undigested ⇒ eligible for selection and counted by the maintenance threshold. The default state of a fresh `facts`-mode card.
|
|
223
|
+
- **A list of doc paths** ⇒ the card's content has been decomposed into each listed doc — the backward audit link completing the two-way trace.
|
|
224
|
+
- **Partial digestion (F6), keyed on whether THE CURRENT TARGET is listed.** A card may contribute to doc X yet have residual facts not placed elsewhere. Mark it `digested_into: [docs/X.md]` — digested into X, but **still selectable** for other targets, because selection drops a card only when the list already contains _the current target_. A card stays in circulation until every doc it touches has consumed it. No separate flag. Lines the human declined are not represented in the list (their cards recirculate); only _applied_ content is recorded.
|
|
225
|
+
- **One card, several docs** ⇒ the list grows **append-only across runs.** Each entry is independently meaningful; order is run-order. **Never rewrite or remove an entry** — a doc later reverted does not un-digest the card (the card _was_ digested there at that transaction time; the doc's own git history records the revert). This mirrors `method.md`'s bi-temporal stance: the trail only grows.
|
|
226
|
+
- **Supersession interaction (F2 + F4 seam).** If a digested card is later superseded by a `facts`-mode run, the _old_ card keeps its `digested_into:` (it documents what the doc once said and why) AND gains `invalid_from:`/`superseded_by:` from the normal bi-temporal path. The _new_ card is undigested → on the next `docs` run its content surfaces the now-stale doc prose as a **CONFLICT question** (Resolution 2), never an auto-rewrite. The trail shows: doc prose ← old card (now invalid) ← superseded_by → new card (pending). No link is ever broken.
|
|
227
|
+
|
|
228
|
+
`digested_into:` is the **only** field `docs` mode writes on a card. It never edits the card's body, `provenance`, `entities`, or bi-temporal fields — those are `facts` mode's surface.
|
|
379
229
|
|
|
380
230
|
### Resolution 4 — PILLAR ESCAPE VALVE: "contradicts a pillar," conservatively
|
|
381
231
|
|
|
382
|
-
**Definition (deliberately narrow).** A card
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
- ✅ Escapes: a card stating "the harness auto-runs the distiller on a cron" vs P6's "build no
|
|
392
|
-
enforcement machinery / no cron" — direct negation of a headline claim. A card recording a
|
|
393
|
-
reversal that negates a live decision headline — e.g. "modules auto-create at a
|
|
394
|
-
flat→modules threshold" vs a live D-headline "the user sets module granularity."
|
|
395
|
-
- ❌ Does NOT escape: a card that merely *touches a topic a pillar discusses*; adds nuance,
|
|
396
|
-
scope, or an exception not contemplated by a pillar (normal doc evolution); is "in tension
|
|
397
|
-
with the spirit"; or conflicts only with a pillar's **body** but not its headline (that is a
|
|
398
|
-
normal doc CONFLICT question — D7 — or nothing). **Vibes do not escape.**
|
|
399
|
-
|
|
400
|
-
If uncertain whether a conflict is headline-level, **do not escape** — treat it as a doc CONFLICT
|
|
401
|
-
question or drop it. Rationale (the decision rule under uncertainty): a false-negative — a real
|
|
402
|
-
conflict slips through as a question — is **recoverable** by the human in the review moment; a
|
|
403
|
-
false-positive — a spurious brainstorm proposal — costs the operator a mode-entry decision and
|
|
404
|
-
**erodes the valve's signal.** When unsure, the cheaper miss is the question.
|
|
405
|
-
|
|
406
|
-
**Emission (P7 mode-entry instance — propose, never enter).** A pillar-conflicting card
|
|
407
|
-
produces a **propose-Brainstorming-Mode item** in the PILLAR-CONFLICT block, never a doc edit
|
|
408
|
-
and never an auto-entry into Brainstorming Mode:
|
|
232
|
+
**Definition (deliberately narrow).** A card _contradicts a pillar_ iff its atomic statement is in **explicit, headline-level conflict** with a doctrine principle (`## Pn —` headline) or a live decision (`## Dn —` headline) — i.e. the card asserts X and the headline (or its one-line Principle/Decision statement) asserts not-X about the _same_ subject. A decision counts as a binding headline unless it has been superseded: a `Reversed by D-M` marker (or a legacy `Status: tentative`) drops it from the substrate, and the reversing decision is the live headline in its place. The operative test: **could you point to the exact pillar headline the card negates?** If not, it is not a pillar contradiction.
|
|
233
|
+
|
|
234
|
+
- ✅ Escapes: a card stating "the harness auto-runs the distiller on a cron" vs P6's "build no enforcement machinery / no cron" — direct negation of a headline claim. A card recording a reversal that negates a live decision headline — e.g. "modules auto-create at a flat→modules threshold" vs a live D-headline "the user sets module granularity."
|
|
235
|
+
- ❌ Does NOT escape: a card that merely _touches a topic a pillar discusses_; adds nuance, scope, or an exception not contemplated by a pillar (normal doc evolution); is "in tension with the spirit"; or conflicts only with a pillar's **body** but not its headline (that is a normal doc CONFLICT question — D7 — or nothing). **Vibes do not escape.**
|
|
236
|
+
|
|
237
|
+
If uncertain whether a conflict is headline-level, **do not escape** — treat it as a doc CONFLICT question or drop it. Rationale (the decision rule under uncertainty): a false-negative — a real conflict slips through as a question — is **recoverable** by the human in the review moment; a false-positive — a spurious brainstorm proposal — costs the operator a mode-entry decision and **erodes the valve's signal.** When unsure, the cheaper miss is the question.
|
|
238
|
+
|
|
239
|
+
**Emission (P7 mode-entry instance — propose, never enter).** A pillar-conflicting card produces a **propose-Brainstorming-Mode item** in the PILLAR-CONFLICT block, never a doc edit and never an auto-entry into Brainstorming Mode:
|
|
409
240
|
|
|
410
241
|
```
|
|
411
242
|
── PILLAR-CONFLICT ESCAPE (NOT a doc edit) ───────────────
|
|
@@ -418,109 +249,51 @@ and never an auto-entry into Brainstorming Mode:
|
|
|
418
249
|
into any doc.) [from: fact-<slug>, contradicts: P6]
|
|
419
250
|
```
|
|
420
251
|
|
|
421
|
-
The conflicting card is **NOT marked digested** (it was not absorbed — it escaped) and **NOT
|
|
422
|
-
backlogged** as a doc-delta (it awaits the brainstorm disposition). It stays undigested so the
|
|
423
|
-
conflict re-surfaces until brainstorm resolves it (the recurrence *is* the dedupe). Distillation
|
|
424
|
-
never quietly rewrites belief — the pillars are the human-owned headwater that *steers*;
|
|
425
|
-
distill② may not silently change what they steer. (If a brainstorm later lands a pillar change
|
|
426
|
-
plus a downstream doc edit, that doc edit re-enters this mode normally.)
|
|
252
|
+
The conflicting card is **NOT marked digested** (it was not absorbed — it escaped) and **NOT backlogged** as a doc-delta (it awaits the brainstorm disposition). It stays undigested so the conflict re-surfaces until brainstorm resolves it (the recurrence _is_ the dedupe). Distillation never quietly rewrites belief — the pillars are the human-owned headwater that _steers_; distill② may not silently change what they steer. (If a brainstorm later lands a pillar change plus a downstream doc edit, that doc edit re-enters this mode normally.)
|
|
427
253
|
|
|
428
254
|
### Resolution 5 — TRIGGER WIRING (P10: at most one line each)
|
|
429
255
|
|
|
430
|
-
**(a) Completion-flow pointer — ONE router-grade line in the kit `CLAUDE.md` Completion step.**
|
|
431
|
-
Added to the "On **Completion**" flow in `harness/code/CLAUDE.md` §Workflows. Terse, points,
|
|
432
|
-
does not re-teach (the procedure lives in this file). Verbatim:
|
|
256
|
+
**(a) Completion-flow pointer — ONE router-grade line in the kit `CLAUDE.md` Completion step.** Added to the "On **Completion**" flow in `harness/code/CLAUDE.md` §Workflows. Terse, points, does not re-teach (the procedure lives in this file). Verbatim:
|
|
433
257
|
|
|
434
258
|
> On Completion, after flipping the spec to `Active`, consult `distiller docs` for the just-completed feature's doc — it drafts any pending fact-card deltas for your approval (presented, never auto-written).
|
|
435
259
|
|
|
436
|
-
**(b) Maintenance threshold — ONE line in `agents/maintenance.md` Step 7**, sibling to the
|
|
437
|
-
existing inbox-distillation threshold (the `facts` analogue: ≥5 undigested *inbox entries*
|
|
438
|
-
proposes a `facts` run). Verbatim:
|
|
260
|
+
**(b) Maintenance threshold — ONE line in `agents/maintenance.md` Step 7**, sibling to the existing inbox-distillation threshold (the `facts` analogue: ≥5 undigested _inbox entries_ proposes a `facts` run). Verbatim:
|
|
439
261
|
|
|
440
262
|
> **Docs-distillation threshold.** Per target doc, count undigested fact-cards (`invalid_from: null`, the doc's path not in their `digested_into:`) that **touch** it by Resolution 1's structural intersection (exact, qmd-independent). If **≥10** map to **one** doc, add one line to the report **proposing** a `distiller docs --doc <path>` run on that doc — propose only, never auto-run, no cron. Declined/ignored ⇒ the count keeps growing and the proposal reappears next pass; that recurrence is the dedupe, so never backlog the proposal itself.
|
|
441
263
|
|
|
442
|
-
`N = 10` default (vs the inbox threshold's 5 — inbox entries are rare and rich; cards accrue per doc). "Touch" uses the
|
|
443
|
-
**structural** retriever only (deterministic, no qmd dependency in the maintenance loop).
|
|
444
|
-
Per-doc count, not repo-wide: the proposal names the one doc, so the run is already scoped. This
|
|
445
|
-
lands as a proposal emitter only — maintenance does not run the distiller (P19: distinct axis).
|
|
264
|
+
`N = 10` default (vs the inbox threshold's 5 — inbox entries are rare and rich; cards accrue per doc). "Touch" uses the **structural** retriever only (deterministic, no qmd dependency in the maintenance loop). Per-doc count, not repo-wide: the proposal names the one doc, so the run is already scoped. This lands as a proposal emitter only — maintenance does not run the distiller (P19: distinct axis).
|
|
446
265
|
|
|
447
266
|
---
|
|
448
267
|
|
|
449
268
|
## Edge cases
|
|
450
269
|
|
|
451
|
-
**A. No target doc exists yet for a completed feature.** distill② does **not** create the
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
**C. A card touching a FROZEN record (a plan, an existing changelog entry, a pillar).** Never
|
|
468
|
-
edited (hard stop). A card whose only relevant target is frozen:
|
|
469
|
-
- if it *contradicts* a pillar headline → escape valve (Resolution 4);
|
|
470
|
-
- if it reports a code change worth recording → draft a **new** changelog entry (append-only is
|
|
471
|
-
allowed; editing an existing one is not);
|
|
472
|
-
- otherwise → it touches a writable doc section instead, or touches zero docs (Edge Case B).
|
|
473
|
-
The frozen file is never the write target.
|
|
474
|
-
|
|
475
|
-
**D. Conflicting cards (two live cards disagree about the target's area).** distill② does not
|
|
476
|
-
adjudicate which is true — that is `facts`-mode reconciliation's job (ADD/UPDATE/SUPERSEDE/NOOP,
|
|
477
|
-
`method.md` §3). If two *live* (non-superseded) cards make contradictory claims about the same
|
|
478
|
-
doc sentence, surface **both** as a single D7 question — *"fact-A says X, fact-B says Y about §S;
|
|
479
|
-
these disagree — which holds? I will not draft a revision until the cards reconcile"* — and draft
|
|
480
|
-
**neither** line. Suggest the user run `distiller facts` to reconcile first. If one card is
|
|
481
|
-
already `superseded_by` the other, the live card wins and the superseded one is excluded from
|
|
482
|
-
drafting (Step 2.3) but its trail is preserved. distill② never resolves a fact-vs-fact conflict
|
|
483
|
-
by picking one — that crosses into fabricating belief.
|
|
484
|
-
|
|
485
|
-
**E. A card hand-edited into the doc (accept-with-edits), then re-surfaces.** Because
|
|
486
|
-
`digested_into:` was set on accept (Step 5.3) listing the target, selection (Step 2.3) drops the
|
|
487
|
-
card on the next run — it is digested into that doc regardless of whether the landed prose is the
|
|
488
|
-
agent's draft or the human's edit (the human edited the *abstraction*; the *evidence* is recorded
|
|
489
|
-
either way). The card does not re-surface for that doc. Only if the human *deleted* a line
|
|
490
|
-
entirely (so nothing landed for its sole-source card) does that card stay undigested and re-
|
|
491
|
-
surface — which is correct: its content never reached the doc.
|
|
492
|
-
|
|
493
|
-
**F. Disambiguation — prose-conflict vs pillar-conflict.** If a card collides with *both* a doc
|
|
494
|
-
sentence and a pillar headline, the **pillar escape wins** (the heavier, more conservative path):
|
|
495
|
-
emit the propose-Brainstorming-Mode item and do not draft the doc line, because the doc prose may
|
|
496
|
-
itself be downstream of the belief now in question. Resolve the belief first, then let any
|
|
497
|
-
resulting doc edit re-enter normally.
|
|
270
|
+
**A. No target doc exists yet for a completed feature.** distill② does **not** create the feature doc — that is the Completion step's job (flip spec to `Active`) via the `documentation` skill. If the invocation finds no doc, the mode reports _"no target doc yet for {feature}; create it via the spec flow first, then re-invoke `distiller docs`"_ and stops. It never scaffolds a doc from cards alone — a doc born purely from distilled facts would have no human-authored abstraction (Background/Goal/Approach) and would violate docs-as-SSoT + decomposition-never-invention. Cards stay undigested; they'll be drafted once the doc exists. If the gap persists, backlog at par: `- **[P2]** Feature {slug} has {N} undigested cards but no owning doc — discovered by distiller docs`.
|
|
271
|
+
|
|
272
|
+
**B. A card touching zero docs.** Not selected for any target — it stays undigested, queryable, counted toward no threshold. Normal and valid: not every fact belongs in a doc (a transient observation, a fact about an unowned path). **Never** force-fit into the nearest doc (that is invention). If maintenance reports many undigested cards touching _no_ doc, that is an **unowned-code** signal for maintenance's existing unowned-path step, not a distill② action. Report it as a count (_"{N} cards touch no current doc"_); do not absorb it. No doc is touched.
|
|
273
|
+
|
|
274
|
+
**C. A card touching a FROZEN record (a plan, an existing changelog entry, a pillar).** Never edited (hard stop). A card whose only relevant target is frozen:
|
|
275
|
+
|
|
276
|
+
- if it _contradicts_ a pillar headline → escape valve (Resolution 4);
|
|
277
|
+
- if it reports a code change worth recording → draft a **new** changelog entry (append-only is allowed; editing an existing one is not);
|
|
278
|
+
- otherwise → it touches a writable doc section instead, or touches zero docs (Edge Case B). The frozen file is never the write target.
|
|
279
|
+
|
|
280
|
+
**D. Conflicting cards (two live cards disagree about the target's area).** distill② does not adjudicate which is true — that is `facts`-mode reconciliation's job (ADD/UPDATE/SUPERSEDE/NOOP, `method.md` §3). If two _live_ (non-superseded) cards make contradictory claims about the same doc sentence, surface **both** as a single D7 question — _"fact-A says X, fact-B says Y about §S; these disagree — which holds? I will not draft a revision until the cards reconcile"_ — and draft **neither** line. Suggest the user run `distiller facts` to reconcile first. If one card is already `superseded_by` the other, the live card wins and the superseded one is excluded from drafting (Step 2.3) but its trail is preserved. distill② never resolves a fact-vs-fact conflict by picking one — that crosses into fabricating belief.
|
|
281
|
+
|
|
282
|
+
**E. A card hand-edited into the doc (accept-with-edits), then re-surfaces.** Because `digested_into:` was set on accept (Step 5.3) listing the target, selection (Step 2.3) drops the card on the next run — it is digested into that doc regardless of whether the landed prose is the agent's draft or the human's edit (the human edited the _abstraction_; the _evidence_ is recorded either way). The card does not re-surface for that doc. Only if the human _deleted_ a line entirely (so nothing landed for its sole-source card) does that card stay undigested and re- surface — which is correct: its content never reached the doc.
|
|
283
|
+
|
|
284
|
+
**F. Disambiguation — prose-conflict vs pillar-conflict.** If a card collides with _both_ a doc sentence and a pillar headline, the **pillar escape wins** (the heavier, more conservative path): emit the propose-Brainstorming-Mode item and do not draft the doc line, because the doc prose may itself be downstream of the belief now in question. Resolve the belief first, then let any resulting doc edit re-enter normally.
|
|
498
285
|
|
|
499
286
|
---
|
|
500
287
|
|
|
501
288
|
## Acceptance checks
|
|
502
289
|
|
|
503
|
-
1. **Presented, never auto-written.** A run produces a chat-presented draft and waits; no doc
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
5. **Conflict surfaces as a question.** A card disagreeing with doc prose yields a D7-phrased
|
|
514
|
-
QUESTION, never a silent rewrite (Resolution 2, F4).
|
|
515
|
-
6. **Declined delta → backlog at par, deduped.** Declining produces one P-tiered backlog line
|
|
516
|
-
interleaved with code items; a second decline adds nothing (D10).
|
|
517
|
-
7. **Docs without relevant cards untouched.** A doc no card touches is never opened or modified;
|
|
518
|
-
a run with an empty working set reports "no undigested cards touch {target}" and changes
|
|
519
|
-
nothing.
|
|
520
|
-
8. **Idempotent via the digestion mark.** An immediate re-run on the same doc finds its touching
|
|
521
|
-
cards already `digested_into:` that doc and is a clean NOOP — the digestion mark is to `docs`
|
|
522
|
-
mode what inbox consumption is to `facts` mode (F3).
|
|
523
|
-
9. **Trigger budget.** Exactly one line added to `CLAUDE.md` Completion; exactly one line added to
|
|
524
|
-
maintenance Step 7. No procedure inlined into either (P10).
|
|
525
|
-
10. **Not autonomous.** No cron/daemon/hook; invoked by the Completion step, by accepting
|
|
526
|
-
maintenance's threshold proposal, or by direct user request only (P6).
|
|
290
|
+
1. **Presented, never auto-written.** A run produces a chat-presented draft and waits; no doc file changes until the human approves (locked default #4).
|
|
291
|
+
2. **Per-line provenance.** Every drafted prose line / changelog bullet carries a `[from: ...]` tag naming ≥1 source card; a line with no card behind it does not exist in the draft (F1).
|
|
292
|
+
3. **Digestion recorded + cards survive.** On approval, every consumed (incl. NOOP'd) card gains the target path in `digested_into:` and the file remains in `docs/memory/facts/` (F3); marking happens last, after the doc write.
|
|
293
|
+
4. **Pillar-contradicting card → brainstorm proposal, not a doc edit.** A planted card negating a doctrine/decision headline produces a propose-Brainstorming-Mode item and zero doc/pillar edits; it is neither digested nor backlogged (Resolution 4, F5).
|
|
294
|
+
5. **Conflict surfaces as a question.** A card disagreeing with doc prose yields a D7-phrased QUESTION, never a silent rewrite (Resolution 2, F4).
|
|
295
|
+
6. **Declined delta → backlog at par, deduped.** Declining produces one P-tiered backlog line interleaved with code items; a second decline adds nothing (D10).
|
|
296
|
+
7. **Docs without relevant cards untouched.** A doc no card touches is never opened or modified; a run with an empty working set reports "no undigested cards touch {target}" and changes nothing.
|
|
297
|
+
8. **Idempotent via the digestion mark.** An immediate re-run on the same doc finds its touching cards already `digested_into:` that doc and is a clean NOOP — the digestion mark is to `docs` mode what inbox consumption is to `facts` mode (F3).
|
|
298
|
+
9. **Trigger budget.** Exactly one line added to `CLAUDE.md` Completion; exactly one line added to maintenance Step 7. No procedure inlined into either (P10).
|
|
299
|
+
10. **Not autonomous.** No cron/daemon/hook; invoked by the Completion step, by accepting maintenance's threshold proposal, or by direct user request only (P6).
|