@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,113 +1,58 @@
|
|
|
1
1
|
# Distillation Method — the algorithm spec
|
|
2
2
|
|
|
3
|
-
The shared knowledge root for the `distiller` skill. Every mode reads this file.
|
|
4
|
-
It carries the four mechanisms the distiller runs, the fact-card format, and the
|
|
5
|
-
inbox-consumption protocol.
|
|
3
|
+
The shared knowledge root for the `distiller` skill. Every mode reads this file. It carries the four mechanisms the distiller runs, the fact-card format, and the inbox-consumption protocol.
|
|
6
4
|
|
|
7
|
-
**These methods are stolen, not invented.** Each is sourced to its primary paper
|
|
8
|
-
with an arXiv id — provenance matters here of all places. Embed them faithfully;
|
|
9
|
-
do not paraphrase the retention signal away.
|
|
5
|
+
**These methods are stolen, not invented.** Each is sourced to its primary paper with an arXiv id — provenance matters here of all places. Embed them faithfully; do not paraphrase the retention signal away.
|
|
10
6
|
|
|
11
7
|
---
|
|
12
8
|
|
|
13
9
|
## The four methods
|
|
14
10
|
|
|
15
|
-
### 1. Surprisal filter —
|
|
11
|
+
### 1. Surprisal filter — _what to keep_ (Nemori, arXiv:2508.03341)
|
|
16
12
|
|
|
17
|
-
Present the LLM with **(a)** a summary of the
|
|
18
|
-
new undigested inbox entries. Keep only what is **surprising** relative to
|
|
19
|
-
(a) — what the existing knowledge would **not** have predicted. Predictable ⇒
|
|
20
|
-
dropped.
|
|
13
|
+
Present the LLM with **(a)** a summary of the _current_ fact-set, and **(b)** the new undigested inbox entries. Keep only what is **surprising** relative to (a) — what the existing knowledge would **not** have predicted. Predictable ⇒ dropped.
|
|
21
14
|
|
|
22
|
-
No importance scores. No emotional tags. No templates. **Prediction error is the
|
|
23
|
-
only retention signal.**
|
|
15
|
+
No importance scores. No emotional tags. No templates. **Prediction error is the only retention signal.**
|
|
24
16
|
|
|
25
|
-
> **First run, empty fact-set.** With nothing to predict against, "predictable" =
|
|
26
|
-
> mechanical routine. Keep decisions, reversals, discovered constraints, and
|
|
27
|
-
> failures with a cause worth remembering. Drop the rote. (Inbox entries arrive
|
|
28
|
-
> semi-distilled — the `session-reflect` hook already dropped routine work — so
|
|
29
|
-
> most survive this filter; what it still catches is repetition of what the
|
|
30
|
-
> fact-set already knows.)
|
|
17
|
+
> **First run, empty fact-set.** With nothing to predict against, "predictable" = mechanical routine. Keep decisions, reversals, discovered constraints, and failures with a cause worth remembering. Drop the rote. (Inbox entries arrive semi-distilled — the `session-reflect` hook already dropped routine work — so most survive this filter; what it still catches is repetition of what the fact-set already knows.)
|
|
31
18
|
|
|
32
|
-
**Surprisal sources are not only inbox entries.** The inbox is the
|
|
33
|
-
stream, but the retention signal is prediction error wherever it lives. On a
|
|
34
|
-
project whose inbox is thin or empty, the decision record carries the surprise
|
|
35
|
-
instead: `docs/architecture/adr/**` (each accepted ADR is, by construction, a
|
|
36
|
-
decision the prior knowledge would not have predicted) and
|
|
37
|
-
`docs/memory/brainstorm.md` (reversals, owner pronouncements, discovered
|
|
38
|
-
constraints). Treat these as input (b) alongside any inbox entries; the filter
|
|
39
|
-
(keep the surprising, drop the predictable) is unchanged. Provenance then points
|
|
40
|
-
at the ADR file or brainstorm section rather than a session id.
|
|
19
|
+
**Surprisal sources are not only inbox entries.** The inbox is the _default_ stream, but the retention signal is prediction error wherever it lives. On a project whose inbox is thin or empty, the decision record carries the surprise instead: `docs/architecture/adr/**` (each accepted ADR is, by construction, a decision the prior knowledge would not have predicted) and `docs/memory/brainstorm.md` (reversals, owner pronouncements, discovered constraints). Treat these as input (b) alongside any inbox entries; the filter (keep the surprising, drop the predictable) is unchanged. Provenance then points at the ADR file or brainstorm section rather than a session id.
|
|
41
20
|
|
|
42
|
-
(Independently corroborated by Honcho's "Dream" — same prediction-error
|
|
43
|
-
retention, arrived at separately.)
|
|
21
|
+
(Independently corroborated by Honcho's "Dream" — same prediction-error retention, arrived at separately.)
|
|
44
22
|
|
|
45
|
-
### 2. Fact-card representation —
|
|
23
|
+
### 2. Fact-card representation — _non-lossy EDUs_ (EMem, arXiv:2511.17208)
|
|
46
24
|
|
|
47
|
-
Each survivor becomes **ONE atomic, self-contained statement** — an Elementary
|
|
48
|
-
Discourse Unit (EDU). Entity names normalized; the minimal context needed to
|
|
49
|
-
stand alone baked into the sentence itself. Each card carries **provenance**: the
|
|
50
|
-
session ids and/or commits it derives from.
|
|
25
|
+
Each survivor becomes **ONE atomic, self-contained statement** — an Elementary Discourse Unit (EDU). Entity names normalized; the minimal context needed to stand alone baked into the sentence itself. Each card carries **provenance**: the session ids and/or commits it derives from.
|
|
51
26
|
|
|
52
|
-
This is **decomposition, not summarization.** No information is destroyed; one
|
|
53
|
-
survivor may decompose into several cards; everything stays auditable back to
|
|
54
|
-
the session and commits that produced it.
|
|
27
|
+
This is **decomposition, not summarization.** No information is destroyed; one survivor may decompose into several cards; everything stays auditable back to the session and commits that produced it.
|
|
55
28
|
|
|
56
|
-
### 3. Reconciliation —
|
|
29
|
+
### 3. Reconciliation — _consistency_ (Mem0, arXiv:2504.19413)
|
|
57
30
|
|
|
58
|
-
For each candidate card, retrieve the existing facts' **semantic neighbors**,
|
|
59
|
-
then decide one of:
|
|
31
|
+
For each candidate card, retrieve the existing facts' **semantic neighbors**, then decide one of:
|
|
60
32
|
|
|
61
33
|
- **ADD** — genuinely new fact; write a new card.
|
|
62
|
-
- **UPDATE** — refines/extends a known fact; edit the existing card in place,
|
|
63
|
-
|
|
64
|
-
- **SUPERSEDE** — contradicts/replaces a known fact; invalidate the old, write
|
|
65
|
-
the new (see §4).
|
|
34
|
+
- **UPDATE** — refines/extends a known fact; edit the existing card in place, extend its provenance.
|
|
35
|
+
- **SUPERSEDE** — contradicts/replaces a known fact; invalidate the old, write the new (see §4).
|
|
66
36
|
- **NOOP** — already known; write nothing.
|
|
67
37
|
|
|
68
|
-
Neighbor retrieval: `qmd query --format json -c {repo}-facts "<statement>"`
|
|
69
|
-
(scope with `-c`, one collection) — **only when the `{repo}-facts` collection
|
|
70
|
-
exists** (`qmd collection list` shows it). The gate is the collection, not the
|
|
71
|
-
binary: a present qmd whose facts collection has never been built (first run)
|
|
72
|
-
returns nothing useful. **Fallback when the collection is missing** — qmd absent,
|
|
73
|
-
*or* present but `{repo}-facts` not yet built: filename / grep similarity over
|
|
74
|
-
`docs/memory/facts/*.md` (slug overlap + entity-name grep), and note in the
|
|
75
|
-
report that reconciliation ran without semantic retrieval.
|
|
38
|
+
Neighbor retrieval: `qmd query --format json -c {repo}-facts "<statement>"` (scope with `-c`, one collection) — **only when the `{repo}-facts` collection exists** (`qmd collection list` shows it). The gate is the collection, not the binary: a present qmd whose facts collection has never been built (first run) returns nothing useful. **Fallback when the collection is missing** — qmd absent, _or_ present but `{repo}-facts` not yet built: filename / grep similarity over `docs/memory/facts/*.md` (slug overlap + entity-name grep), and note in the report that reconciliation ran without semantic retrieval.
|
|
76
39
|
|
|
77
|
-
### 4. Bi-temporal supersession —
|
|
40
|
+
### 4. Bi-temporal supersession — _never delete_ (Zep/Graphiti, arXiv:2501.13956)
|
|
78
41
|
|
|
79
|
-
Superseding **never deletes.** On the **old** card, set `invalid_from:` (the date
|
|
80
|
-
it stopped being true) and `superseded_by:` (the new fact's id), and **leave the
|
|
81
|
-
file in place.** Write the **new** card with today's `valid_from:`. The old fact
|
|
82
|
-
stays queryable as history; nothing vanishes.
|
|
42
|
+
Superseding **never deletes.** On the **old** card, set `invalid_from:` (the date it stopped being true) and `superseded_by:` (the new fact's id), and **leave the file in place.** Write the **new** card with today's `valid_from:`. The old fact stays queryable as history; nothing vanishes.
|
|
83
43
|
|
|
84
|
-
This is the
|
|
85
|
-
`[valid_from, invalid_from)`; transaction time is the git history of the file.
|
|
44
|
+
This is the _valid-time_ axis of a bi-temporal model — a fact is true within `[valid_from, invalid_from)`; transaction time is the git history of the file.
|
|
86
45
|
|
|
87
|
-
#### Self-contained reversal —
|
|
46
|
+
#### Self-contained reversal — _both cards in one pass_
|
|
88
47
|
|
|
89
|
-
`SUPERSEDE` (§3) assumes the old fact already lives as a card. But a single input
|
|
90
|
-
can state a reversal whole — "X was decided, then reversed to Y" in one sentence
|
|
91
|
-
(e.g. brainstorm.md: *single-tenant → multi-tenant, same session*; or an ADR
|
|
92
|
-
whose **Options Considered** (the `documentation` §10 ADR template's
|
|
93
|
-
rejected-alternatives section) names a path "proposed and reversed within the
|
|
94
|
-
brainstorm"). Here there is no pre-existing X card to invalidate — both X and Y
|
|
95
|
-
arrive together.
|
|
48
|
+
`SUPERSEDE` (§3) assumes the old fact already lives as a card. But a single input can state a reversal whole — "X was decided, then reversed to Y" in one sentence (e.g. brainstorm.md: _single-tenant → multi-tenant, same session_; or an ADR whose **Options Considered** (the `documentation` §10 ADR template's rejected-alternatives section) names a path "proposed and reversed within the brainstorm"). Here there is no pre-existing X card to invalidate — both X and Y arrive together.
|
|
96
49
|
|
|
97
50
|
Emit **two cards in one pass**:
|
|
98
51
|
|
|
99
|
-
1. A **born-invalid historical card for X** — the superseded decision. Write it
|
|
100
|
-
|
|
101
|
-
`invalid_from:` (when it was reversed — the same date, for an in-session
|
|
102
|
-
reversal), and `superseded_by:` pointing at Y's fact-id. It is created already
|
|
103
|
-
carrying its own death so the reversal stays auditable.
|
|
104
|
-
2. A **live card for Y** — the decision that won. `valid_from:` the reversal date,
|
|
105
|
-
`invalid_from: null`, `superseded_by: null`.
|
|
52
|
+
1. A **born-invalid historical card for X** — the superseded decision. Write it with `valid_from:` (when X was decided, if known, else the input date), `invalid_from:` (when it was reversed — the same date, for an in-session reversal), and `superseded_by:` pointing at Y's fact-id. It is created already carrying its own death so the reversal stays auditable.
|
|
53
|
+
2. A **live card for Y** — the decision that won. `valid_from:` the reversal date, `invalid_from: null`, `superseded_by: null`.
|
|
106
54
|
|
|
107
|
-
Both share the input's provenance (the one ADR / brainstorm line). This is the
|
|
108
|
-
ADD-side mirror of SUPERSEDE: SUPERSEDE invalidates a card that already exists;
|
|
109
|
-
the self-contained reversal *manufactures* the invalidated card so the
|
|
110
|
-
abandoned-X history is recorded rather than silently dropped.
|
|
55
|
+
Both share the input's provenance (the one ADR / brainstorm line). This is the ADD-side mirror of SUPERSEDE: SUPERSEDE invalidates a card that already exists; the self-contained reversal _manufactures_ the invalidated card so the abandoned-X history is recorded rather than silently dropped.
|
|
111
56
|
|
|
112
57
|
---
|
|
113
58
|
|
|
@@ -117,50 +62,33 @@ abandoned-X history is recorded rather than silently dropped.
|
|
|
117
62
|
---
|
|
118
63
|
id: fact-{slug}
|
|
119
64
|
valid_from: YYYY-MM-DD
|
|
120
|
-
invalid_from: null
|
|
121
|
-
superseded_by: null
|
|
65
|
+
invalid_from: null # set on supersession — never delete the file
|
|
66
|
+
superseded_by: null # fact-id
|
|
122
67
|
entities: [qmd, anchors, maintenance]
|
|
123
68
|
provenance: [session 28b2cd5e, commit abc123]
|
|
124
69
|
---
|
|
70
|
+
|
|
125
71
|
One atomic, self-contained statement of the fact, entities normalized.
|
|
126
72
|
```
|
|
127
73
|
|
|
128
74
|
- `id` — `fact-{slug}`, the slug matching the filename.
|
|
129
|
-
- `valid_from` — the date the fact became true (the entry/commit date, or the
|
|
130
|
-
|
|
131
|
-
- `invalid_from` — `null` until superseded; then the date it stopped being true.
|
|
132
|
-
**Never delete the file** to express invalidity — set this field.
|
|
75
|
+
- `valid_from` — the date the fact became true (the entry/commit date, or the distill date if no better signal).
|
|
76
|
+
- `invalid_from` — `null` until superseded; then the date it stopped being true. **Never delete the file** to express invalidity — set this field.
|
|
133
77
|
- `superseded_by` — `null`, or the `fact-id` of the card that replaced it.
|
|
134
|
-
- `entities` — normalized names the fact concerns (used by the grep fallback and
|
|
135
|
-
|
|
136
|
-
-
|
|
137
|
-
and commits this card decomposes from. Inbox entries are consumed after
|
|
138
|
-
digestion, so the session id + commit hashes ARE the audit trail — commits
|
|
139
|
-
resolve in git; session ids resolve to transcripts while retained. ADR /
|
|
140
|
-
brainstorm inputs cite their file or section instead.
|
|
141
|
-
- The body — exactly one atomic, self-contained statement. Entities normalized,
|
|
142
|
-
context baked in, so the card stands alone.
|
|
78
|
+
- `entities` — normalized names the fact concerns (used by the grep fallback and by retrieval).
|
|
79
|
+
- `provenance` — the session ids (`session <id>`, as stamped on the inbox entry) and commits this card decomposes from. Inbox entries are consumed after digestion, so the session id + commit hashes ARE the audit trail — commits resolve in git; session ids resolve to transcripts while retained. ADR / brainstorm inputs cite their file or section instead.
|
|
80
|
+
- The body — exactly one atomic, self-contained statement. Entities normalized, context baked in, so the card stands alone.
|
|
143
81
|
|
|
144
82
|
---
|
|
145
83
|
|
|
146
84
|
## Inbox-consumption protocol (`docs/memory/inbox/`)
|
|
147
85
|
|
|
148
|
-
Consumption is what makes the distiller idempotent. The inbox
|
|
149
|
-
(`docs/memory/inbox/{actor}.md`, one file per actor) is a queue: every entry
|
|
150
|
-
block present is undigested, by definition. There is no separate high-water
|
|
151
|
-
mark and no `.digest-state.md`.
|
|
86
|
+
Consumption is what makes the distiller idempotent. The inbox (`docs/memory/inbox/{actor}.md`, one file per actor) is a queue: every entry block present is undigested, by definition. There is no separate high-water mark and no `.digest-state.md`.
|
|
152
87
|
|
|
153
88
|
**Protocol:**
|
|
154
89
|
|
|
155
|
-
1. **Collect first.** Read every entry block across `docs/memory/inbox/*.md`.
|
|
156
|
-
Empty inbox ⇒ fall through to the ADR/brainstorm surprisal sources (§1).
|
|
90
|
+
1. **Collect first.** Read every entry block across `docs/memory/inbox/*.md`. Empty inbox ⇒ fall through to the ADR/brainstorm surprisal sources (§1).
|
|
157
91
|
2. Digest the collected entries (filter → decompose → reconcile → write).
|
|
158
|
-
3. **Consume last** — only after every card is written, delete exactly the
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
re-run re-digests them — reconciliation NOOPs the already-written cards —
|
|
162
|
-
rather than silently dropping them.
|
|
163
|
-
|
|
164
|
-
A second run immediately after a successful one finds an empty inbox and is a
|
|
165
|
-
clean NOOP. ADR/brainstorm inputs are never consumed — reconciliation alone
|
|
166
|
-
keeps re-runs over them idempotent.
|
|
92
|
+
3. **Consume last** — only after every card is written, delete exactly the entry blocks this run digested (keep each file's header; never touch blocks that arrived mid-run). Last, so a crash mid-run leaves entries queued and the re-run re-digests them — reconciliation NOOPs the already-written cards — rather than silently dropping them.
|
|
93
|
+
|
|
94
|
+
A second run immediately after a successful one finds an empty inbox and is a clean NOOP. ADR/brainstorm inputs are never consumed — reconciliation alone keeps re-runs over them idempotent.
|
|
@@ -5,7 +5,7 @@ description: Template & generator library for technical docs — the skill agent
|
|
|
5
5
|
|
|
6
6
|
# Technical Documentation Skill
|
|
7
7
|
|
|
8
|
-
**This skill is a template & generator library, not an orchestrator.** It supplies the templates, the frontmatter-derivation generator, and the co-authoring workflow that
|
|
8
|
+
**This skill is a template & generator library, not an orchestrator.** It supplies the templates, the frontmatter-derivation generator, and the co-authoring workflow that _agents_ call to produce individual docs. It does **not** baseline, audit, or reconcile a repo's doc tree — that is the **`harness-manager` agent**, which calls this skill for each template it scaffolds. Reach here to generate _one_ doc from a template; reach for `harness-manager` to bring a whole repo into shape.
|
|
9
9
|
|
|
10
10
|
Document contracts and architecture, not implementation details. Show function signatures and API shapes — never paste full implementations (they rot fast). Use ASCII diagrams over prose for flows. Only document state at persistence boundaries (Redux persistence, DB schemas, API shapes), not component-level or transient state. Mark deprecated fields with `// UNUSED:` comments. Breaking changes belong in changelogs only, not module docs.
|
|
11
11
|
|
|
@@ -68,11 +68,11 @@ When creating or updating a feature doc in `docs/features/`, generate `owns`, `t
|
|
|
68
68
|
|
|
69
69
|
Read the feature doc's content. Extract every source file path referenced in the doc (file listings, function locations, component paths). Group them into the narrowest glob patterns that cover all referenced files without overlapping other features.
|
|
70
70
|
|
|
71
|
-
| Doc references
|
|
72
|
-
|
|
73
|
-
| Multiple files under one directory
|
|
71
|
+
| Doc references | `owns` pattern |
|
|
72
|
+
| ------------------------------------ | ------------------------- |
|
|
73
|
+
| Multiple files under one directory | `src/feature/**` |
|
|
74
74
|
| Specific files in a shared directory | List each file explicitly |
|
|
75
|
-
| A single entry-point file
|
|
75
|
+
| A single entry-point file | The exact file path |
|
|
76
76
|
|
|
77
77
|
Verify patterns match real files — glob each pattern against the codebase. Remove any that match nothing.
|
|
78
78
|
|
|
@@ -81,6 +81,7 @@ Verify patterns match real files — glob each pattern against the codebase. Rem
|
|
|
81
81
|
From the same source files the doc describes, find imports and calls to code outside the `owns` scope. These are files the feature uses but doesn't own.
|
|
82
82
|
|
|
83
83
|
Common `touches` candidates:
|
|
84
|
+
|
|
84
85
|
- Shared Redux slices the feature reads/writes
|
|
85
86
|
- Utility functions from other modules
|
|
86
87
|
- Shared hooks the feature calls
|
|
@@ -107,10 +108,12 @@ Check for explicit cross-references to other docs in `docs/features/` or `docs/a
|
|
|
107
108
|
For docs that don't match templates:
|
|
108
109
|
|
|
109
110
|
**Stage 1: Context Gathering**
|
|
111
|
+
|
|
110
112
|
- Ask: Audience? Purpose? Existing format?
|
|
111
113
|
- Have user dump all context, then ask 5-10 clarifying questions
|
|
112
114
|
|
|
113
115
|
**Stage 2: Structure & Draft**
|
|
116
|
+
|
|
114
117
|
- Propose section structure, draft section by section
|
|
115
118
|
- User indicates changes (don't edit directly — learn their style)
|
|
116
119
|
|
|
@@ -119,7 +122,7 @@ For docs that don't match templates:
|
|
|
119
122
|
## Resources
|
|
120
123
|
|
|
121
124
|
| File | Use For |
|
|
122
|
-
|
|
125
|
+
| --- | --- |
|
|
123
126
|
| `references/templates.md` | docs/README.md, structure.md, frontmatter, scaffolds (CHANGELOG, backlog, memory), feature, changelog, plan, protected files, ADR, project root README templates |
|
|
124
127
|
| `references/style-guide.md` | Writing rules, formatting conventions |
|
|
125
128
|
| `references/examples.md` | Good vs bad documentation examples |
|
|
@@ -11,12 +11,7 @@ Good vs bad examples showing the key differences.
|
|
|
11
11
|
```markdown
|
|
12
12
|
### mergeData
|
|
13
13
|
|
|
14
|
-
function mergeData(server, local, changes) {
|
|
15
|
-
const result = {};
|
|
16
|
-
const serverMap = new Map(server.map((i) => [i.id, i]));
|
|
17
|
-
// ... 30 more lines
|
|
18
|
-
return result;
|
|
19
|
-
}
|
|
14
|
+
function mergeData(server, local, changes) { const result = {}; const serverMap = new Map(server.map((i) => [i.id, i])); // ... 30 more lines return result; }
|
|
20
15
|
```
|
|
21
16
|
|
|
22
17
|
**Problems:** Will become obsolete, focuses on HOW not WHAT.
|
|
@@ -26,19 +21,17 @@ return result;
|
|
|
26
21
|
```markdown
|
|
27
22
|
### `mergeData(serverData, localData, changes)`
|
|
28
23
|
|
|
29
|
-
**Goal:** Merge server data with local changes
|
|
30
|
-
**Input:**
|
|
24
|
+
**Goal:** Merge server data with local changes **Input:**
|
|
31
25
|
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
**Output:** `{ merged: array, conflicts: array }`
|
|
26
|
+
- `serverData` (array) - Fresh from API
|
|
27
|
+
- `localData` (array) - Current state
|
|
28
|
+
- `changes` (object) - `{ added, updated, removed }` **Output:** `{ merged: array, conflicts: array }`
|
|
36
29
|
|
|
37
30
|
**Merge Rules:**
|
|
38
31
|
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
32
|
+
- Server wins for conflicts
|
|
33
|
+
- Local additions preserved
|
|
34
|
+
- Local removals marked as intent
|
|
42
35
|
```
|
|
43
36
|
|
|
44
37
|
---
|
|
@@ -68,20 +61,11 @@ const [items, setItems] = useState([]);
|
|
|
68
61
|
```markdown
|
|
69
62
|
## State
|
|
70
63
|
|
|
71
|
-
**Frontend (at persistence):**
|
|
72
|
-
{
|
|
73
|
-
"data": [],
|
|
74
|
-
"changes": { "added": [], "updated": [], "removed": [] }
|
|
75
|
-
// "cache": {} // UNUSED: Deprecated
|
|
76
|
-
}
|
|
64
|
+
**Frontend (at persistence):** { "data": [], "changes": { "added": [], "updated": [], "removed": [] } // "cache": {} // UNUSED: Deprecated }
|
|
77
65
|
|
|
78
66
|
**Storage:** localStorage `app_state`
|
|
79
67
|
|
|
80
|
-
**Backend:**
|
|
81
|
-
model Item {
|
|
82
|
-
id String @id
|
|
83
|
-
data Json
|
|
84
|
-
}
|
|
68
|
+
**Backend:** model Item { id String @id data Json }
|
|
85
69
|
```
|
|
86
70
|
|
|
87
71
|
---
|
|
@@ -95,13 +79,13 @@ data Json
|
|
|
95
79
|
|
|
96
80
|
## Changes
|
|
97
81
|
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
82
|
+
- Updated editor
|
|
83
|
+
- Fixed bugs
|
|
84
|
+
- Improved performance
|
|
101
85
|
|
|
102
86
|
## Files
|
|
103
87
|
|
|
104
|
-
-
|
|
88
|
+
- Various files in src/
|
|
105
89
|
```
|
|
106
90
|
|
|
107
91
|
### ✅ Good: Function-Level Detail
|
|
@@ -117,32 +101,32 @@ Replaced change-tracking merge with version-based conflict resolution.
|
|
|
117
101
|
|
|
118
102
|
### Added
|
|
119
103
|
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
|
|
104
|
+
- `mergeAndDerive(server, local, versionsMatch, type)` in `src/utils/merge.js`
|
|
105
|
+
- Purpose: Single-pass merge with change detection
|
|
106
|
+
- Returns: `{ merged, changes }`
|
|
123
107
|
|
|
124
108
|
### Modified
|
|
125
109
|
|
|
126
|
-
-
|
|
127
|
-
|
|
110
|
+
- `useDataSync()` in `src/hooks/useDataSync.js`
|
|
111
|
+
- Changed: Now compares versions before merge
|
|
128
112
|
|
|
129
113
|
### Removed
|
|
130
114
|
|
|
131
|
-
-
|
|
132
|
-
|
|
115
|
+
- `deriveChanges()` from `src/utils/derive.js`
|
|
116
|
+
- Replaced by: Logic in `mergeAndDerive()`
|
|
133
117
|
|
|
134
118
|
## Breaking Changes
|
|
135
119
|
|
|
136
120
|
⚠️ **Merge behavior changed**
|
|
137
121
|
|
|
138
|
-
-
|
|
139
|
-
-
|
|
122
|
+
- Old: Local changes always preserved
|
|
123
|
+
- New: Local preserved only if versions match
|
|
140
124
|
|
|
141
125
|
## Files Changed
|
|
142
126
|
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
127
|
+
- `src/hooks/useDataSync.js`
|
|
128
|
+
- `src/utils/merge.js`
|
|
129
|
+
- `src/utils/derive.js` (deleted)
|
|
146
130
|
```
|
|
147
131
|
|
|
148
132
|
---
|
|
@@ -152,9 +136,7 @@ Replaced change-tracking merge with version-based conflict resolution.
|
|
|
152
136
|
### ❌ Bad: Prose Description
|
|
153
137
|
|
|
154
138
|
```markdown
|
|
155
|
-
When the page loads, the useAppInit hook calls the syncData function.
|
|
156
|
-
This function first fetches data from the server using the API. Then
|
|
157
|
-
it gets the local data from Redux. After that, it compares versions...
|
|
139
|
+
When the page loads, the useAppInit hook calls the syncData function. This function first fetches data from the server using the API. Then it gets the local data from Redux. After that, it compares versions...
|
|
158
140
|
```
|
|
159
141
|
|
|
160
142
|
### ✅ Good: Diagram + Key Points
|
|
@@ -162,22 +144,9 @@ it gets the local data from Redux. After that, it compares versions...
|
|
|
162
144
|
```markdown
|
|
163
145
|
## Data Flow
|
|
164
146
|
|
|
165
|
-
┌─────────────────────────────────────────┐
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
│ │
|
|
169
|
-
│ ┌──────┐ ┌──────┐ ┌──────┐ │
|
|
170
|
-
│ │Server│────▶│Merge │────▶│Redux │ │
|
|
171
|
-
│ │ API │ │ │ │Store │ │
|
|
172
|
-
│ └──────┘ └──────┘ └──────┘ │
|
|
173
|
-
│ │ │
|
|
174
|
-
│ ▼ │
|
|
175
|
-
│ Version Check │
|
|
176
|
-
│ │
|
|
177
|
-
└─────────────────────────────────────────┘
|
|
178
|
-
|
|
179
|
-
**Trigger:** `useAppInit()` on page load
|
|
180
|
-
**Version Rule:** Match → local wins, Mismatch → server wins
|
|
147
|
+
┌─────────────────────────────────────────┐ │ DATA SYNC │ ├─────────────────────────────────────────┤ │ │ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │Server│────▶│Merge │────▶│Redux │ │ │ │ API │ │ │ │Store │ │ │ └──────┘ └──────┘ └──────┘ │ │ │ │ │ ▼ │ │ Version Check │ │ │ └─────────────────────────────────────────┘
|
|
148
|
+
|
|
149
|
+
**Trigger:** `useAppInit()` on page load **Version Rule:** Match → local wins, Mismatch → server wins
|
|
181
150
|
```
|
|
182
151
|
|
|
183
152
|
---
|
|
@@ -11,33 +11,30 @@ Writing rules for clear, maintainable documentation.
|
|
|
11
11
|
```markdown
|
|
12
12
|
### `functionName(param1, param2, options)`
|
|
13
13
|
|
|
14
|
-
**Goal:** One-line purpose
|
|
15
|
-
**Input:**
|
|
14
|
+
**Goal:** One-line purpose **Input:**
|
|
16
15
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
**Output:** `{ field1, field2 }`
|
|
20
|
-
**Side Effects:** State updates, API calls, etc.
|
|
16
|
+
- `param1` (type) - Description
|
|
17
|
+
- `param2` (type, optional) - Description **Output:** `{ field1, field2 }` **Side Effects:** State updates, API calls, etc.
|
|
21
18
|
```
|
|
22
19
|
|
|
23
20
|
### Parameter Rules
|
|
24
21
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
- Name + type + one-line purpose
|
|
23
|
+
- Mark optional params with `(type, optional)`
|
|
24
|
+
- Nest object properties:
|
|
25
|
+
```markdown
|
|
26
|
+
- `options` (object) - Configuration
|
|
27
|
+
- `options.retry` (boolean) - Enable retries
|
|
28
|
+
- `options.timeout` (number) - Timeout in ms
|
|
29
|
+
```
|
|
33
30
|
|
|
34
31
|
### Return Values
|
|
35
32
|
|
|
36
33
|
Always specify:
|
|
37
34
|
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
35
|
+
- Type: `Array<Object>`, `boolean`, `{ merged, changes }`
|
|
36
|
+
- Shape for objects/arrays
|
|
37
|
+
- Meaning: "True if sync successful"
|
|
41
38
|
|
|
42
39
|
---
|
|
43
40
|
|
|
@@ -47,15 +44,15 @@ Always specify:
|
|
|
47
44
|
|
|
48
45
|
✅ Do:
|
|
49
46
|
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
47
|
+
- Redux persistence (localStorage, IndexedDB)
|
|
48
|
+
- Database schemas
|
|
49
|
+
- API request/response shapes
|
|
53
50
|
|
|
54
51
|
❌ Don't:
|
|
55
52
|
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
53
|
+
- Component-level state
|
|
54
|
+
- Derived/computed state
|
|
55
|
+
- Temporary UI state
|
|
59
56
|
|
|
60
57
|
### Format
|
|
61
58
|
|
|
@@ -64,8 +61,8 @@ Always specify:
|
|
|
64
61
|
|
|
65
62
|
```json
|
|
66
63
|
{
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
"activeField": "value"
|
|
65
|
+
// "deprecated": null // UNUSED: Remove in v3
|
|
69
66
|
}
|
|
70
67
|
```
|
|
71
68
|
````
|
|
@@ -100,10 +97,10 @@ Always comment deprecated/unused fields:
|
|
|
100
97
|
|
|
101
98
|
### When to Use
|
|
102
99
|
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
100
|
+
- Data flows
|
|
101
|
+
- System architecture
|
|
102
|
+
- Component interactions
|
|
103
|
+
- Process flows
|
|
107
104
|
|
|
108
105
|
### Pattern
|
|
109
106
|
|
|
@@ -124,9 +121,9 @@ Always comment deprecated/unused fields:
|
|
|
124
121
|
|
|
125
122
|
### Characters
|
|
126
123
|
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
124
|
+
- Boxes: `┌─┐│└┘├┤┬┴┼`
|
|
125
|
+
- Arrows: `───▶` `◀───` `│▼` `│▲`
|
|
126
|
+
- Width: ~70 chars max
|
|
130
127
|
|
|
131
128
|
### UI Wireframes
|
|
132
129
|
|
|
@@ -142,11 +139,11 @@ For screen layouts (not data flows), use these conventions:
|
|
|
142
139
|
└────────────────────────────────────┘
|
|
143
140
|
```
|
|
144
141
|
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
142
|
+
- `[text]` = clickable button/badge
|
|
143
|
+
- `[i]` = icon (followed by label or count)
|
|
144
|
+
- `v` / `^` = expand/collapse indicator
|
|
145
|
+
- Show each UI state (collapsed/expanded) as separate diagrams
|
|
146
|
+
- Include Route/Tab context above wireframe
|
|
150
147
|
|
|
151
148
|
---
|
|
152
149
|
|
|
@@ -154,18 +151,18 @@ For screen layouts (not data flows), use these conventions:
|
|
|
154
151
|
|
|
155
152
|
### Rules
|
|
156
153
|
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
154
|
+
- Under 15 lines
|
|
155
|
+
- Show contracts, not implementations
|
|
156
|
+
- Use pseudocode for algorithms
|
|
160
157
|
|
|
161
158
|
✅ Good:
|
|
162
159
|
|
|
163
160
|
```javascript
|
|
164
161
|
// Critical: Balanced brace matching
|
|
165
162
|
function extract(json) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
163
|
+
// Track brace depth
|
|
164
|
+
// Ignore braces inside strings
|
|
165
|
+
// Return complete objects only
|
|
169
166
|
}
|
|
170
167
|
```
|
|
171
168
|
|
|
@@ -179,36 +176,36 @@ function extract(json) {
|
|
|
179
176
|
|
|
180
177
|
Use imperative/active:
|
|
181
178
|
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
-
|
|
179
|
+
- ✅ "Fetches data from server"
|
|
180
|
+
- ✅ "Returns array of objects"
|
|
181
|
+
- ❌ "This function is used to fetch"
|
|
182
|
+
- ❌ "An array is returned"
|
|
186
183
|
|
|
187
184
|
### When Prose Adds Value
|
|
188
185
|
|
|
189
186
|
Prose is valuable for context that contracts can't capture:
|
|
190
187
|
|
|
191
|
-
| Use Prose For
|
|
192
|
-
|
|
|
193
|
-
| Section intros
|
|
194
|
-
| Non-obvious behavior | "The hook always fetches fresh data. There is no caching or version checking."
|
|
195
|
-
| Design rationale
|
|
196
|
-
| Edge cases
|
|
197
|
-
| Current limitations
|
|
198
|
-
| Usage context
|
|
188
|
+
| Use Prose For | Example |
|
|
189
|
+
| --- | --- |
|
|
190
|
+
| Section intros | "When the editor mounts, `useAppInit` is called with the `appId` from URL." |
|
|
191
|
+
| Non-obvious behavior | "The hook always fetches fresh data. There is no caching or version checking." |
|
|
192
|
+
| Design rationale | "Why parallel fetches? Each entity type is independent, reducing load time." |
|
|
193
|
+
| Edge cases | "If created then deleted before save, it's removed from `added[]` without adding to `removed[]`." |
|
|
194
|
+
| Current limitations | "This hook is not currently integrated into the main flow." |
|
|
195
|
+
| Usage context | "Used to show 'Unsaved' badge, warn before navigation, enable save buttons." |
|
|
199
196
|
|
|
200
197
|
### When to Avoid Prose
|
|
201
198
|
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
-
|
|
199
|
+
- Describing WHAT code does (use signatures instead)
|
|
200
|
+
- Step-by-step flows (use diagrams instead)
|
|
201
|
+
- Structured comparisons (use tables instead)
|
|
205
202
|
|
|
206
203
|
### Conciseness
|
|
207
204
|
|
|
208
205
|
One line when possible:
|
|
209
206
|
|
|
210
|
-
-
|
|
211
|
-
-
|
|
207
|
+
- ✅ "Merge server data with local changes using version-based conflict resolution"
|
|
208
|
+
- ❌ "This function takes the data from the server and also takes the local data..."
|
|
212
209
|
|
|
213
210
|
### Tables
|
|
214
211
|
|
|
@@ -268,8 +265,8 @@ Always end with:
|
|
|
268
265
|
```markdown
|
|
269
266
|
## Files
|
|
270
267
|
|
|
271
|
-
-
|
|
272
|
-
-
|
|
268
|
+
- `src/path/main.js` - Core logic
|
|
269
|
+
- `src/path/hooks.js` - React hooks
|
|
273
270
|
```
|
|
274
271
|
|
|
275
272
|
---
|