@tenkara/afm-linux-arm64 4.0.0-alpha.8 → 4.0.0-alpha.9
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/bin/afm +2 -2
- package/content/CHANGELOG.md +22 -0
- package/content/core/afm.md +1 -1
- package/content/ops/evolve.md +61 -9
- package/content/ops/reflect.md +18 -13
- package/content/ops/restructure.md +2 -2
- package/content/ops/update.md +26 -2
- package/content/roles/explorer.md +1 -1
- package/content/roles/reviewer.md +1 -1
- package/content/skills/adr.md +3 -3
- package/content/skills/analyze.md +2 -8
- package/content/skills/clarify.md +2 -8
- package/content/skills/deliver.md +4 -20
- package/content/skills/diagnose.md +3 -11
- package/content/skills/evolve.md +6 -30
- package/content/skills/export-template.md +2 -5
- package/content/skills/generalize.md +6 -22
- package/content/skills/gotcha.md +3 -3
- package/content/skills/init.md +2 -7
- package/content/skills/plan.md +3 -9
- package/content/skills/policy.md +0 -6
- package/content/skills/promote.md +1 -3
- package/content/skills/protocol.md +2 -3
- package/content/skills/reconcile.md +2 -6
- package/content/skills/refactor.md +2 -7
- package/content/skills/reflect.md +7 -17
- package/content/skills/remediate.md +3 -9
- package/content/skills/restructure.md +8 -14
- package/content/skills/rule.md +3 -4
- package/content/skills/specify.md +3 -9
- package/content/skills/tasks.md +4 -14
- package/content/skills/update.md +6 -4
- package/content/skills/verify.md +1 -3
- package/content/templates/evolution-report.template.md +5 -0
- package/package.json +1 -1
- package/plugin/agy/plugin.json +1 -1
- package/plugin/agy/skills/afm-adr/SKILL.md +7 -3
- package/plugin/agy/skills/afm-analyze/SKILL.md +4 -6
- package/plugin/agy/skills/afm-clarify/SKILL.md +4 -6
- package/plugin/agy/skills/afm-deliver/SKILL.md +6 -20
- package/plugin/agy/skills/afm-diagnose/SKILL.md +5 -9
- package/plugin/agy/skills/afm-evolve/SKILL.md +9 -29
- package/plugin/agy/skills/afm-export-template/SKILL.md +6 -5
- package/plugin/agy/skills/afm-generalize/SKILL.md +8 -20
- package/plugin/agy/skills/afm-gotcha/SKILL.md +7 -3
- package/plugin/agy/skills/afm-init/SKILL.md +3 -6
- package/plugin/agy/skills/afm-plan/SKILL.md +5 -7
- package/plugin/agy/skills/afm-policy/SKILL.md +2 -4
- package/plugin/agy/skills/afm-promote/SKILL.md +4 -2
- package/plugin/agy/skills/afm-protocol/SKILL.md +6 -3
- package/plugin/agy/skills/afm-reconcile/SKILL.md +5 -5
- package/plugin/agy/skills/afm-refactor/SKILL.md +3 -6
- package/plugin/agy/skills/afm-reflect/SKILL.md +9 -15
- package/plugin/agy/skills/afm-remediate/SKILL.md +5 -7
- package/plugin/agy/skills/afm-restructure/SKILL.md +10 -12
- package/plugin/agy/skills/afm-rule/SKILL.md +7 -4
- package/plugin/agy/skills/afm-specify/SKILL.md +5 -7
- package/plugin/agy/skills/afm-tasks/SKILL.md +6 -12
- package/plugin/agy/skills/afm-update/SKILL.md +10 -4
- package/plugin/agy/skills/afm-verify/SKILL.md +4 -2
- package/plugin/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugin/claude-code/agents/afm-explorer.md +1 -1
- package/plugin/claude-code/agents/afm-reviewer.md +1 -1
- package/plugin/claude-code/skills/adr/SKILL.md +7 -3
- package/plugin/claude-code/skills/analyze/SKILL.md +4 -6
- package/plugin/claude-code/skills/clarify/SKILL.md +4 -6
- package/plugin/claude-code/skills/deliver/SKILL.md +6 -20
- package/plugin/claude-code/skills/diagnose/SKILL.md +5 -9
- package/plugin/claude-code/skills/evolve/SKILL.md +9 -29
- package/plugin/claude-code/skills/export-template/SKILL.md +6 -5
- package/plugin/claude-code/skills/generalize/SKILL.md +8 -20
- package/plugin/claude-code/skills/gotcha/SKILL.md +7 -3
- package/plugin/claude-code/skills/init/SKILL.md +3 -6
- package/plugin/claude-code/skills/plan/SKILL.md +5 -7
- package/plugin/claude-code/skills/policy/SKILL.md +2 -4
- package/plugin/claude-code/skills/promote/SKILL.md +4 -2
- package/plugin/claude-code/skills/protocol/SKILL.md +6 -3
- package/plugin/claude-code/skills/reconcile/SKILL.md +5 -5
- package/plugin/claude-code/skills/refactor/SKILL.md +3 -6
- package/plugin/claude-code/skills/reflect/SKILL.md +9 -15
- package/plugin/claude-code/skills/remediate/SKILL.md +5 -7
- package/plugin/claude-code/skills/restructure/SKILL.md +10 -12
- package/plugin/claude-code/skills/rule/SKILL.md +7 -4
- package/plugin/claude-code/skills/specify/SKILL.md +5 -7
- package/plugin/claude-code/skills/tasks/SKILL.md +6 -12
- package/plugin/claude-code/skills/update/SKILL.md +10 -4
- package/plugin/claude-code/skills/verify/SKILL.md +4 -2
- package/plugin/opencode/agents/afm-explorer.md +9 -0
- package/plugin/opencode/agents/afm-reviewer.md +9 -0
- package/plugin/opencode/skills/afm-adr/SKILL.md +7 -3
- package/plugin/opencode/skills/afm-analyze/SKILL.md +4 -6
- package/plugin/opencode/skills/afm-clarify/SKILL.md +4 -6
- package/plugin/opencode/skills/afm-deliver/SKILL.md +6 -20
- package/plugin/opencode/skills/afm-diagnose/SKILL.md +5 -9
- package/plugin/opencode/skills/afm-evolve/SKILL.md +9 -29
- package/plugin/opencode/skills/afm-export-template/SKILL.md +6 -5
- package/plugin/opencode/skills/afm-generalize/SKILL.md +8 -20
- package/plugin/opencode/skills/afm-gotcha/SKILL.md +7 -3
- package/plugin/opencode/skills/afm-init/SKILL.md +3 -6
- package/plugin/opencode/skills/afm-plan/SKILL.md +5 -7
- package/plugin/opencode/skills/afm-policy/SKILL.md +2 -4
- package/plugin/opencode/skills/afm-promote/SKILL.md +4 -2
- package/plugin/opencode/skills/afm-protocol/SKILL.md +6 -3
- package/plugin/opencode/skills/afm-reconcile/SKILL.md +5 -5
- package/plugin/opencode/skills/afm-refactor/SKILL.md +3 -6
- package/plugin/opencode/skills/afm-reflect/SKILL.md +9 -15
- package/plugin/opencode/skills/afm-remediate/SKILL.md +5 -7
- package/plugin/opencode/skills/afm-restructure/SKILL.md +10 -12
- package/plugin/opencode/skills/afm-rule/SKILL.md +7 -4
- package/plugin/opencode/skills/afm-specify/SKILL.md +5 -7
- package/plugin/opencode/skills/afm-tasks/SKILL.md +6 -12
- package/plugin/opencode/skills/afm-update/SKILL.md +10 -4
- package/plugin/opencode/skills/afm-verify/SKILL.md +4 -2
package/bin/afm
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/bin/afm
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 83871736 bytes
|
|
4
|
+
sha256: 71a29eb24193f646325886838d459df116f78493950ad01c65035ae98a6eba54
|
package/content/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,28 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning [Se
|
|
|
7
7
|
> uncompressed. `ops/update.md` must read the archive too when the version range reaches
|
|
8
8
|
> back before `3.5.0`.
|
|
9
9
|
|
|
10
|
+
## [4.0.0-alpha.9] - 2026-10-15
|
|
11
|
+
|
|
12
|
+
The docs learn from use: what is used stays in evidence, what is not fades, and reflect reads every session of the project in every harness.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Cross-session reflect (ADR-0023).** `ops/reflect.md` and `ops/evolve.md` read the live session plus the project's sessions since the last cycle, through `afm sessions` and `afm sessions signals` (deterministic signals: corrections, tool-error groups, AFM injections, rereads, repeated prompts). A φ_b cites `session:<id>@<ts>`; the 2-occurrence gate counts across sessions; a covered session is marked with `afm sessions mark`; a cycle lists what it handled in `resolves:`, and a signal that comes back after it is `regressed`.
|
|
17
|
+
- **Repeated prompts become artifacts.** A prompt the owner retypes is a finding; a cluster of operational verbs (commit, push, deploy, release…) is flagged `[runbook?]` and becomes an `afm new procedure` proposal in the project where it repeats.
|
|
18
|
+
- **On-demand sections (ADR-0024).** An op declares `sections:` in its frontmatter; `afm read ops/<op>.md` prints the core with a one-line stub per on-demand section, and `--section <slug>` prints one. `ops/evolve.md` is the first op split this way (about 10 KB of core out of 36 KB).
|
|
19
|
+
- **Relevance tiers act at run time (ADR-0024).** `load:` decides what a hook delivers: a `hot` doc is listed at session start, a `cold` one reaches a write only through its file-shape trigger. `afm doctor` proposes tier changes (`tier-drift`) and tombstones for cold orphan docs nobody uses (`fade`), always through the gate.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Skills name the host's own tools.** A skill writes `{{host:<term>}}` and `afm render` writes each harness's wording (ADR-0022); the render also injects the op pointer and the principles and version footer, so the skills carry neither.
|
|
24
|
+
- **Skills are pointers to their op**: `evolve`, `deliver`, `tasks` and `generalize` keep only what the op lacks.
|
|
25
|
+
- **`ops/update.md` runs the language migration as one orchestrated batch on a light model**, with a light-model loss check and escalation of a flagged file only.
|
|
26
|
+
|
|
27
|
+
### Consumer migration
|
|
28
|
+
|
|
29
|
+
- **rules-canonical-sync-load-tiers.** A PLUGIN-<n> hard rule of docs/afm.md whose text an earlier release shipped takes the current canonical text (PLUGIN-39 now says what each load: tier does); an edited rule is held; a retired rule and a project rule are never touched. (ops: custom)
|
|
30
|
+
- **record-pristine-alpha9.** A docs file the codemods above brought to exactly what afm init writes today is recorded in the manifest as AFM's own. (ops: custom)
|
|
31
|
+
|
|
10
32
|
## [4.0.0-alpha.8] - 2026-10-13
|
|
11
33
|
|
|
12
34
|
Metadata lives only in the frontmatter, and what the model used to judge is data the CLI owns: the tasks of a feature, the artifact language and the hard rules.
|
package/content/core/afm.md
CHANGED
|
@@ -351,7 +351,7 @@ PLUGIN-39. **An indexed file carries the OKF contract, and an op declares what i
|
|
|
351
351
|
|
|
352
352
|
# Hard rule PLUGIN-39 — An indexed file carries the OKF contract, and an op declares what it writes and composes.
|
|
353
353
|
|
|
354
|
-
Every type has its own schema on top of the three keys that follow (`afm lint` judges it, ADR-0014). The common contract is three keys. `type:` is the one key OKF v0.2 requires. `description:` is one sentence, and the index prints it instead of opening the body. `load:` is `hot`, `warm` or `cold
|
|
354
|
+
Every type has its own schema on top of the three keys that follow (`afm lint` judges it, ADR-0014). The common contract is three keys. `type:` is the one key OKF v0.2 requires. `description:` is one sentence, and the index prints it instead of opening the body. `load:` is `hot`, `warm` or `cold`: a `hot` doc is listed at session start by headline and path, a `warm` one reaches a write by the path it names, a `cold` one only when its declared file-shape trigger matches, and `afm index --load <level>` lists one level. `afm index` reads frontmatter and nothing else. A file without it is invisible to the index.
|
|
355
355
|
|
|
356
356
|
The agent asks who writes `spec.md`, gets a list with that file missing, and receives no signal. Missing metadata does not look like an error. It looks like a shorter list. A `composes:` that names a dead op fails from the other side. The reader trusts it because the frontmatter is the cheap thing it read instead of the body.
|
|
357
357
|
|
package/content/ops/evolve.md
CHANGED
|
@@ -5,6 +5,31 @@ load: warm
|
|
|
5
5
|
writes: ["docs/evolution/*.md"]
|
|
6
6
|
composes: ["diagnose", "reflect", "generalize", "restructure", "update", "remediate"]
|
|
7
7
|
ancestors: the Reflect→Select→Improve→Evaluate→Commit loop from Autogenesis (arXiv 2604.15034), and the Weakness-Mining→Proposal→Validation loop from Self-Harness (arXiv 2606.09498).
|
|
8
|
+
sections:
|
|
9
|
+
- heading: 'Design notes (conductor, the name, Commit κ)'
|
|
10
|
+
read_when: 'you ask why evolve is a conductor, or change a Commit κ step'
|
|
11
|
+
- heading: 'What `evolve` is NOT'
|
|
12
|
+
read_when: 'tempted to run evolve as an atomic mechanism, optimizer, daemon or `[TBD]` resolver'
|
|
13
|
+
- heading: 'Cooldown criteria'
|
|
14
|
+
read_when: 'you need the new-signal definition, the window or the override'
|
|
15
|
+
- heading: 'Phase 1 procedure'
|
|
16
|
+
read_when: 'starting Phase 1'
|
|
17
|
+
- heading: 'Proposal discipline (shared)'
|
|
18
|
+
read_when: 'proposing any edit, before the gate'
|
|
19
|
+
- heading: 'Phase 2 procedure'
|
|
20
|
+
read_when: 'building the package or when A3 flags version drift'
|
|
21
|
+
- heading: 'Phase 3 procedure'
|
|
22
|
+
read_when: 'presenting the package at the gate'
|
|
23
|
+
- heading: 'Phase 4 procedure'
|
|
24
|
+
read_when: 'applying an approved item or running a postcondition'
|
|
25
|
+
- heading: 'Phase 5 procedure'
|
|
26
|
+
read_when: 'writing the evolution report'
|
|
27
|
+
- heading: 'Whitelist — evolvable vs. protected surfaces'
|
|
28
|
+
read_when: 'an item edits anything but gotchas, afm.md sections 3 and 1.3, other rubrics, ADR status or the doc-map bridge'
|
|
29
|
+
- heading: 'Suppression contract (the honest DRY guarantee)'
|
|
30
|
+
read_when: 'the cycle composes another op (diagnose, reflect, rule, update, remediate and so on)'
|
|
31
|
+
- heading: 'Conditional anti-patterns'
|
|
32
|
+
read_when: 'you compose an op, fix a non-restorable reference, or downgrade, renumber or re-propose a rule or item'
|
|
8
33
|
---
|
|
9
34
|
# Sub-flow: orchestrator for the AFM local documentation self-evolution cycle (`evolve`)
|
|
10
35
|
|
|
@@ -29,6 +54,8 @@ Triggers:
|
|
|
29
54
|
> - **To the plugin, only RECORDS:** if a lesson applies to **any** instance (not only this project), the cycle suggests `afm promote`. That op **records the finding** with `afm findings record`, in the project state, with mechanical evidence. No one applies it to the plugin from here. The boundary is absolute (#7). The maintainer applies it, in the plugin repo.
|
|
30
55
|
>
|
|
31
56
|
|
|
57
|
+
### Design notes (conductor, the name, Commit κ)
|
|
58
|
+
|
|
32
59
|
> **The name.** `evolve` is a codename (not descriptive of purpose) — chosen by the framework owner. Natural-language activation does **not** depend on the name: it lives in the skill's `when_to_use`. Renaming it is a **major** change (moves a file under `ops/` and `skills/`).
|
|
33
60
|
>
|
|
34
61
|
> **The `composes:` list has six entries and the cycle has five mechanisms. Both are right.**
|
|
@@ -75,6 +102,8 @@ design and not an omission:
|
|
|
75
102
|
- The last cycle **with `mechanism: evolve`** in `docs/evolution/` is **recent** (default under 14 days). Override this with `cooldown-days=` on the `<!-- evolve: ... -->` line of `docs/.afm-version`.
|
|
76
103
|
- **No new signal** appeared since then.
|
|
77
104
|
|
|
105
|
+
### Cooldown criteria
|
|
106
|
+
|
|
78
107
|
"New signal" means either:
|
|
79
108
|
- (a) a delta in the `diagnose` checks (Class A/A7) since the last cycle date. Verify this with the findings of `afm doctor --json` against the date of the newest report in `docs/evolution/`, **never** with self-written content. Pass `--signal` only when that delta is real.
|
|
80
109
|
- (b) the stated symptom from step 3 (`--symptom`).
|
|
@@ -87,12 +116,16 @@ design and not an omission:
|
|
|
87
116
|
|
|
88
117
|
## Phase 1 — Evidence collection (composes `diagnose` + `reflect`)
|
|
89
118
|
|
|
119
|
+
Run `diagnose` and `reflect` through the suppression contract and consolidate their bundles into one set of findings. An empty diagnosis is a valid result: report "100%" and stop. Exit: one consolidated set of findings.
|
|
120
|
+
|
|
121
|
+
### Phase 1 procedure
|
|
122
|
+
|
|
90
123
|
`evolve` **does not reimplement** the scan or the reflection. It runs them through the suppression contract and consolidates the bundles. This is gap-driven: the symptom from the pre-check sets the depth.
|
|
91
124
|
|
|
92
125
|
0. **Capture `T0=$(date +%s)`** before any read. This is the baseline for the boundary postcondition (Phase 4.3) when the content root is not a git repo. Without it, the no-git branch has nothing to compare against.
|
|
93
126
|
|
|
94
|
-
1. **Run `diagnose`** (**mechanical** evidence): `afm doctor --json` for A1-A6, staleness and dead gotchas, plus the A7 paired reading, as `diagnose.md` describes (Phase 0 scan of the 7 axes, plus Phase 1 φ/addressability/severity diagnosis). It returns the evidence bundle. (Run à la carte, `diagnose` prints the bundle. Here it feeds the cycle. `diagnose` does not write `docs/evolution/` — that is Phase 5.)
|
|
95
|
-
2. **Run `reflect`** (**behavioral** evidence). Follow `reflect.md` §§ 1-2 (collect the φ_b signatures seen in the session, plus the self-check "was it me, not the doc"). Suppress `reflect`'s own gate — it moves to the single gate. With no friction in the
|
|
127
|
+
1. **Run `diagnose`** (**mechanical** evidence): `afm doctor --json` for A1-A6, staleness and dead gotchas, plus the A7 paired reading, the `tier-drift` axis (docs and sections whose `load:` tier no longer matches their use) and the `fade` axis (cold orphan docs with no use), as `diagnose.md` describes (Phase 0 scan of the 7 axes, plus Phase 1 φ/addressability/severity diagnosis). It returns the evidence bundle. (Run à la carte, `diagnose` prints the bundle. Here it feeds the cycle. `diagnose` does not write `docs/evolution/` — that is Phase 5.)
|
|
128
|
+
2. **Run `reflect`** (**behavioral** evidence). Follow `reflect.md` §§ 1-2 (collect the φ_b signatures seen in the live session and in the project's sessions since the last evolve cycle, from `afm sessions --since evolve --json` and `afm sessions signals --since evolve --json`, plus the self-check "was it me, not the doc"), with the same weighting: the live session counts on one signal, a past-session signal only when it repeats across 2 or more sessions, is an explicit correction, or is `regressed` (and `regressed` first); a `repeatedPrompt` signal is a first-class finding (see `reflect.md` Pre-check 3). The evolve report also carries `resolves:` with the fingerprints the cycle handled, and every session record covered gets `reflection:` filled. Suppress `reflect`'s own gate — it moves to the single gate. With no friction in the whole window, the behavioral axis stays empty. That is a valid result.
|
|
96
129
|
3. **On-demand proposal mechanisms** (through suppression, own gate suppressed, gap-driven — with no signal, they do not run):
|
|
97
130
|
- `diagnose` axis A3 flags **version drift** (pinned instance ≠ plugin `VERSION`). This composes `update` — a delta-by-delta migration proposal for consumer-facing changes (see Phase 2.2).
|
|
98
131
|
- `diagnose` axis A6 flags **2 or more redundant gotchas** → composes `generalize` (merge proposal).
|
|
@@ -103,7 +136,7 @@ design and not an omission:
|
|
|
103
136
|
This is the cycle's "self-reflection on failures". `diagnose`/rule 19 **flag** the unfixed repeat failure. The cycle **resolves** it at the gate. `remediate`'s own gate is suppressed — it moves to the single gate. This is gated by #5 (negative filters — a transient failure does not get promoted).
|
|
104
137
|
|
|
105
138
|
3.5. **Guardrail axis — what is still caught by hand, and should be caught by a command**. This axis joins two sources that no one cross-checks today:
|
|
106
|
-
- the **guardrail candidates** from `reflect § 1.2` — a defect the agent fixed by hand 2 or more times in the
|
|
139
|
+
- the **guardrail candidates** from `reflect § 1.2` — a defect the agent fixed by hand 2 or more times in the window (`--since evolve`).
|
|
107
140
|
- the failures of `afm failures promotable` that the rubric classified as **mechanizable** — a precedence destination.
|
|
108
141
|
|
|
109
142
|
For each one, run the **surface discovery** from `remediate.md` step 3.5. Look at the linter, type check, CI, or git hooks the project **already** runs. Propose where the check should land.
|
|
@@ -176,7 +209,11 @@ For each **addressable** finding, before it reaches the gate:
|
|
|
176
209
|
|
|
177
210
|
## Phase 2 — Proposal (IMPROVER role, in staging)
|
|
178
211
|
|
|
179
|
-
Apply the
|
|
212
|
+
Apply the proposal discipline to each finding from Phase 1; the package asks at most 8 (b) questions per cycle. Exit: one consolidated package.
|
|
213
|
+
|
|
214
|
+
### Phase 2 procedure
|
|
215
|
+
|
|
216
|
+
Apply the **Proposal discipline (shared)** (the section of this file with that title) to each consolidated finding from Phase 1. The mechanisms that already propose changes (`reflect`/`generalize`/`restructure`) bring their proposals ready — they already passed the discipline. `evolve` adds the proposals for the purely mechanical `diagnose` findings — downgrade, archive, merge. This is the logic that **originates here**. `evolve` consolidates everything into one package.
|
|
180
217
|
|
|
181
218
|
1. **Package cap:** the cap counts **only (b) questions**. It is measured **per cycle** (8 (b) questions total, maximum). `afm evolve gate-check --critical <n> --high <n> --medium <n> --low <n>` computes it: it prints how many to ask now, in how many calls (for example `2 calls (4+4)`), and how many to stage. Present them in **at most 2 calls of at most 4 questions each** (NEVER more than 4 in one call). One **(b) item equals one `multiSelect` option** (including the A2 stance question and the A3 migration). Listed **(a) items do not use a slot**. They are seen, not asked — the user confirms the batch at the same gate.
|
|
182
219
|
- **5 to 8 (b) items are NOT an "overflow"**. They fit in up to 2 calls (4 plus the rest). Staging is required only **above 8**.
|
|
@@ -192,6 +229,10 @@ Apply the **Proposal discipline (shared)** above to each consolidated finding fr
|
|
|
192
229
|
|
|
193
230
|
## Phase 3 — Single gate (≈ Commit κ) — **always happens, never skippable**
|
|
194
231
|
|
|
232
|
+
The single gate always opens, even for an (a)-only package. Each (b) item is its own `afm ask evolve` scope, never a monolithic approve. Exit: a recorded decision per item.
|
|
233
|
+
|
|
234
|
+
### Phase 3 procedure
|
|
235
|
+
|
|
195
236
|
`evolve` **requires a gate under every protocol**. It is a first-class exception alongside the bright lines ([`core/protocol.md`](../core/protocol.md) § 4), not the absence of a flag.
|
|
196
237
|
|
|
197
238
|
The safety valve that makes "go" safe in `deliver` **does not exist here**. That valve halts on the first task that depends on an assumption. There is no execution phase in `evolve`. The doc edit *is* the effect. There is no future boundary where the human would catch drift. So the gate cannot be skipped.
|
|
@@ -211,6 +252,10 @@ Even a package with **only (a) items** opens the gate. The ceremony cost is the
|
|
|
211
252
|
|
|
212
253
|
## Phase 4 — Application + postconditions (≈ Commit κ applied)
|
|
213
254
|
|
|
255
|
+
Apply the approved items through the suppression contract, then run the two mechanical postconditions: step 4.2 (parseable format) and step 4.3 (the instance/plugin boundary). A format break rolls the edit back and is reported. Any dirt in the plugin content root means rollback plus a CRITICAL report. Exit: applied edits with both postconditions green.
|
|
256
|
+
|
|
257
|
+
### Phase 4 procedure
|
|
258
|
+
|
|
214
259
|
1. **Apply** the (a) items and the approved (b) items, through the **suppression contract**:
|
|
215
260
|
- A rule edit follows `rule.md`.
|
|
216
261
|
- A gotcha follows `gotcha.md`.
|
|
@@ -242,6 +287,10 @@ Even a package with **only (a) items** opens the gate. The ceremony cost is the
|
|
|
242
287
|
|
|
243
288
|
## Phase 5 — Record + promote (auditable lineage)
|
|
244
289
|
|
|
290
|
+
Write `docs/evolution/<date>-NNN.md` with `mechanism: evolve`, keep the rejected and reverted items, suggest `afm promote` for a finding that generalizes, and hand off to `reconcile`. Exit: the closed report.
|
|
291
|
+
|
|
292
|
+
### Phase 5 procedure
|
|
293
|
+
|
|
245
294
|
1. **Materialize or close** `<consumer>/docs/evolution/<date>-NNN.md` (`afm next-id evolution` prints the free NNN), with `afm new evolution-report --mechanism <...>` (fix findings with `afm lint --fix`). Include the φ findings (mechanical and behavioral), the buckets, and the audit records. Include the **rejected AND approved-then-reverted items** too — the attempt memory for future cycles. Include the before/after vital signs, and the date (`afm evolve gate-check` reads it for the cooldown). This is the Self-Harness h₀→h₁ lineage.
|
|
246
295
|
2. **Does it generalize?** If a finding applies to any instance ("every pre-rc.5 instance has this drift"), **suggest** `afm promote`. Never skip its own gate (#7) — `evolve` only suggests.
|
|
247
296
|
3. **Hand off to `reconcile`** to watch the effect of the changes in later sessions. This is AFM's possible form of "re-run". With no held-out set, real validation is observed future behavior.
|
|
@@ -298,17 +347,20 @@ Even a package with **only (a) items** opens the gate. The ceremony cost is the
|
|
|
298
347
|
## Anti-patterns
|
|
299
348
|
|
|
300
349
|
- ❌ **Running by ritual or calendar** — it runs by signal. A cycle with no new signal gets a cooldown refusal (Autogenesis: an adaptive trigger beats a fixed budget).
|
|
301
|
-
- ❌ **Reimplementing the scan or the reflection** — `evolve` composes `diagnose`/`reflect` through suppression. It does not duplicate their procedure.
|
|
302
350
|
- ❌ **Treating an empty diagnosis as a failure** — a healthy instance means the cycle reports "100%" and stops. It never invents a problem to justify the invocation.
|
|
303
|
-
- ❌ **Inventing the target for a non-restorable fix**. Examples: a dead reference with no proven rename, an ADR with no NNNN target, a trigger with no historical path. These go to the gate as options — archive, redirect, recreate. Never guess a path or ADR (#5).
|
|
304
351
|
- ❌ **Classifying a trigger/hook-path edit as (a)** — it is always (b). This is the agent reducing its own oversight.
|
|
305
352
|
- ❌ **Skipping the gate** — there is no "go" in `evolve`. Even a package with only (a) items opens the gate.
|
|
306
353
|
- ❌ **A monolithic plan-approve** — the gate is item by item, one `afm ask evolve` scope per (b) item (the edits are independent).
|
|
307
|
-
- ❌ **Downgrading a rule because it was violated** — a violation does not mean the rule is wrong. Downgrading needs proof the rule is *wrong* (a false positive, impossible to satisfy, or an intent proven obsolete by git). Consider "the agent was non-compliant" as the rival explanation first.
|
|
308
354
|
- ❌ **Deleting** — archive it instead, with a tombstone. Deletion is a bright line and gets its own gate item. A superseded ADR, a dead gotcha, or an old marker stay institutional memory until the human says otherwise.
|
|
309
|
-
- ❌ **Renumbering a rule** — a removed one becomes `*(removed — lives in §X)*`.
|
|
310
355
|
- ❌ **Materializing after the gate what the gate did not see**. ADRs and edits must be itemized in Phase 3, or they do not happen.
|
|
311
356
|
- ❌ **Editing the bundled content** — the Phase 4.3 boundary postcondition (two branches) catches this. Any dirt means rollback plus CRITICAL. A generalization is **recorded** through `promote`, never applied from here (#7).
|
|
312
|
-
- ❌ **Re-proposing a rejected or reverted item with no new evidence**. Attempt memory, plus the per-surface flip-flop flag, catch this.
|
|
313
357
|
- ❌ **Resolving `[TBD]` alone**. Age is a signal to ask if the stance still holds. It is not a reason to invent an answer (#4/#5).
|
|
358
|
+
|
|
359
|
+
### Conditional anti-patterns
|
|
360
|
+
|
|
361
|
+
- ❌ **Reimplementing the scan or the reflection** — `evolve` composes `diagnose`/`reflect` through suppression. It does not duplicate their procedure.
|
|
362
|
+
- ❌ **Inventing the target for a non-restorable fix**. Examples: a dead reference with no proven rename, an ADR with no NNNN target, a trigger with no historical path. These go to the gate as options — archive, redirect, recreate. Never guess a path or ADR (#5).
|
|
363
|
+
- ❌ **Downgrading a rule because it was violated** — a violation does not mean the rule is wrong. Downgrading needs proof the rule is *wrong* (a false positive, impossible to satisfy, or an intent proven obsolete by git). Consider "the agent was non-compliant" as the rival explanation first.
|
|
364
|
+
- ❌ **Renumbering a rule** — a removed one becomes `*(removed — lives in §X)*`.
|
|
365
|
+
- ❌ **Re-proposing a rejected or reverted item with no new evidence**. Attempt memory, plus the per-surface flip-flop flag, catch this.
|
|
314
366
|
- ❌ **Composing `reflect.md` past § 2 in Phase 1.2**. Reading further would reach the § 5 escalation step and let `reflect` propose `afm evolve` from inside the very cycle running it. The recursion guard depends on Phase 1.2 stopping at §§ 1-2 — see `§ Suppression contract`.
|
package/content/ops/reflect.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: op
|
|
3
|
-
description: Refines a doc that guided the agent wrong, using evidence from the session
|
|
3
|
+
description: Refines a doc that guided the agent wrong, using evidence from the live session and the project's sessions since the last cycle, and proposes the full cycle when that evidence outgrows one doc.
|
|
4
4
|
load: warm
|
|
5
5
|
writes: ["docs/evolution/*.md"]
|
|
6
6
|
composes: []
|
|
@@ -38,7 +38,7 @@ Triggers: `afm reflect`. Also natural language about a **doc that guided badly**
|
|
|
38
38
|
|
|
39
39
|
Examples: an ambiguous rule applied wrong, a doc that misled, a section that did not guide. Also a contradiction lived in practice, or the user correcting the agent against the doc.
|
|
40
40
|
|
|
41
|
-
The evidence is **the session's
|
|
41
|
+
The evidence is **the trajectory of the live session plus the project's sessions since the last cycle** — the agent stumbled. It is not the static artifact. It produces **(a)** proposals to make the doc **more assertive and clear**. This refines what already exists. It also produces **(b)** suggestions for the human in the loop.
|
|
42
42
|
|
|
43
43
|
**It is NOT:**
|
|
44
44
|
- `reconcile` (code→docs, **additive**: the agent learns a new fact, then proposes a new gotcha or rule). `reflect` is **docs→docs refinement**: an existing doc guided badly, so it proposes making that doc assertive. *It never adds knowledge. It only improves the instructiveness of what is already there.*
|
|
@@ -53,7 +53,11 @@ The evidence is **the session's trajectory** — the agent stumbled. It is not t
|
|
|
53
53
|
|
|
54
54
|
1. **Does `<consumer>/docs/.afm-version` exist?** If not, stop. Suggest `afm init` or `afm refactor` first.
|
|
55
55
|
2. **Does `afm preflight` exit 0?** A non-zero exit says why: the docs are not bootstrapped, the bundled content does not resolve, or the pin does not match. Report it to the user. Do not fall back silently.
|
|
56
|
-
3. **Capture the events lived in
|
|
56
|
+
3. **Capture the events lived in the evidence window: the live session plus the project's sessions since the last cycle.** The `reflect` trigger is in-session — see `interview/triggers.md` — but the evidence is wider. Run `afm sessions --since reflect --json` (it lists the project's sessions in every supported harness; `source` is `record`, `harness` or `both`) (pass the live session id with `--exclude <id>`) for the window, then `afm sessions signals --since reflect --json` for its deterministic signals: user turns, with a `correction` flag set by a fixed marker list, tool-error groups, AFM injection sizes and repeated reads. The signals are a heuristic that points at friction. You judge them. The command skips sessions whose record already names a `reflection:` (pass `--include-covered` to read them again), groups tool errors by tool and command, carries the repeated prompt rituals of the last 30 days under `repeatedPrompts` (`--repeat-window <N>d`; `--scope user` clusters them across every project of the user, listing the projects of each cluster), and gives every signal a `fingerprint` and a `status`: `new`, `resolved` (an evolution report listed its fingerprint in `resolves:`) or `regressed` (the signal recurs after that report, so the earlier fix did not hold).
|
|
57
|
+
- **Weight.** The live session is read directly, so one signal there is enough evidence. A signal from a past session counts only when it repeats across 2 or more sessions, is an explicit correction, or is `regressed`. A `resolved` signal is not a finding.
|
|
58
|
+
- **Order.** Take the `regressed` signals first: each one says an earlier fix did not hold, so revisit that report's change before proposing a new one.
|
|
59
|
+
- **Repeated prompts.** A `repeatedPrompt` signal is a first-class finding: the user types the same thing again and again. Propose the artifact that stops the retyping (a procedure, a preset in a skill, an op step, or a config default), citing the cluster sample and its sessions. A cluster that carries `suggests: procedure` (the `[runbook?]` marker in text mode) is a run of operational verbs, so propose it as an `afm new procedure` in the project where it repeats, with the steps in the order the user asks them.
|
|
60
|
+
- **Read-only bound.** Open a raw transcript only when a signal needs context, and read only the turns around its `ts`. Note which core docs the agent read or followed, and where they guided badly. With no lived event in the window, no signal, and no clear symptom, stop: there is no reflection to do. Report "no doc friction observed in the window", then **record the outcome**: run `afm cadence close --arm reflect --reason "no doc friction observed"`. That writes the durable record that resets the cadence counter, so the same task and deliverable counts do not block the next Stop again. Then end. Reflection with no behavioral evidence is the agent inventing a disease. Rule #5 forbids this.
|
|
57
61
|
|
|
58
62
|
> **If the operator would rather skip the reflection**, run `afm cadence skip --session <id> --reason "<text>"` (the id is the one the Stop message gives; `--session` is required). It records the skip as debt in the state store and does not reset the counter. Never edit the session store by hand.
|
|
59
63
|
|
|
@@ -61,21 +65,21 @@ The evidence is **the session's trajectory** — the agent stumbled. It is not t
|
|
|
61
65
|
|
|
62
66
|
## 1. Behavioral evidence collection (≈ *Reflect* — traces → hypotheses)
|
|
63
67
|
|
|
64
|
-
Core docs include `afm.md`, `ach.md`, `prd.md`, `ust.md`, the rules under `rules/`, the gotchas under `gotchas/`, and the rubrics. Find each point
|
|
68
|
+
Core docs include `afm.md`, `ach.md`, `prd.md`, `ust.md`, the rules under `rules/`, the gotchas under `gotchas/`, and the rubrics. Find each point in the window (the live session and the signals of the earlier sessions) where a core doc guided badly. Record a **behavioral signature** for it: `φ_b = (symptom-lived, causal-status-of-the-doc, mechanism)`.
|
|
65
69
|
|
|
66
70
|
- *symptom-lived* — what happened, with an anchor. Example one: the agent applied rule N of `afm.md § 3` wrong, and had to re-read it twice. The user then corrected the agent against it, in `<file>`. Example two: the agent followed `ach.md § 3.1`, and the part it named no longer existed. Example three: two docs gave opposite guidance on the same task.
|
|
67
71
|
- *causal-status-of-the-doc* — was **the doc** causally implicated? This slot is the *causal status*, not "who is to blame."
|
|
68
72
|
- *mechanism* — **why** the doc produced the stumble. Options include an ambiguous rule that reads two ways, or a rule with no executable trigger. Such a rule fails a 0/1 check. Other options: an outdated example, guidance buried where nobody finds it, or a contradiction with another doc.
|
|
69
73
|
|
|
70
|
-
**Golden rule:** every signature cites **the doc passage** (`file:section`). It also cites **the session event** — what the agent did, or what the user said. Without both sides, it is not evidence. It is only an impression.
|
|
74
|
+
**Golden rule:** every signature cites **the doc passage** (`file:section`). It also cites **the session event** as `session:<id>@<ts>` — what the agent did, or what the user said. The id and the timestamp come from the live session or from a signal of `afm sessions signals`. Without both sides, it is not evidence. It is only an impression.
|
|
71
75
|
|
|
72
76
|
### 1.2 — The second sweep: what I corrected by hand more than once
|
|
73
77
|
|
|
74
|
-
Beyond a doc that guided badly, `reflect` sweeps the
|
|
78
|
+
Beyond a doc that guided badly, `reflect` sweeps the window for **an error caught by non-mechanical review, and that came back**. Look for the same defect type fixed in two places. Or an ad-hoc `grep` run again, or a review repeated because no command did it for the agent.
|
|
75
79
|
|
|
76
|
-
Each occurrence becomes a **guardrail candidate**: `(the defect, how many times
|
|
80
|
+
Each occurrence becomes a **guardrail candidate**: `(the defect, how many times in the window, how the agent caught it by hand)`. The promotion gate is the rubric's, from `rubrics/failure-classification.md`. It needs 2 or more occurrences, counted across the sessions of the window, or one explicit user correction.
|
|
77
81
|
|
|
78
|
-
> **Why this lives in `reflect`, and not only in `remediate`.** `remediate` consumes the failure events of the state store (`afm failures promotable`). Those only record a failure recognized by a **terminal external signal** — a red test, a nonzero `tsc` result, a nonzero command result. An error the agent caught itself, while reading the diff, **never reaches those events**. It gets fixed before it becomes a signal. This is the most expensive class of error. Its cost is the agent's own context, invisible on the ledger. `reflect` is the only point in the cycle that sees it, because its evidence is the lived trajectory alone.
|
|
82
|
+
> **Why this lives in `reflect`, and not only in `remediate`.** `remediate` consumes the failure events of the state store (`afm failures promotable`). Those only record a failure recognized by a **terminal external signal** — a red test, a nonzero `tsc` result, a nonzero command result. An error the agent caught itself, while reading the diff, **never reaches those events**. It gets fixed before it becomes a signal. This is the most expensive class of error. Its cost is the agent's own context, invisible on the ledger. `reflect` is the only point in the cycle that sees it, because its evidence is the lived trajectory alone, across the project's sessions of the window.
|
|
79
83
|
|
|
80
84
|
Before proposing a candidate, run the same **surface discovery** as `ops/remediate.md` step 3.5. Check the linter, type-check, CI, and any git hooks the project already has. A candidate with no surface to land on stays an observation. It does not become a proposal.
|
|
81
85
|
|
|
@@ -107,8 +111,8 @@ For each addressable finding, follow the **shared proposal discipline** of the e
|
|
|
107
111
|
- **Add the executable trigger** that was missing. A rule with no `*Verification:*` 0/1 gains a trigger, or moves down to § 1.3 as a principle (rule #3).
|
|
108
112
|
- Disambiguate a contradiction, or itemize an ADR for it.
|
|
109
113
|
- Move buried guidance, or point to it from a clearer spot.
|
|
110
|
-
- **(c) Guardrail candidate** (from § 1.2) — the defect the agent corrected by hand 2 or more times
|
|
111
|
-
- **(b) Suggestion for the human** — for friction a text edit cannot fix, but that is still a real signal. Examples: "rule N cost you 3 corrections
|
|
114
|
+
- **(c) Guardrail candidate** (from § 1.2) — the defect the agent corrected by hand 2 or more times in the window. State the existing surface where the check would land and the estimated cost. This goes to the gate as an **installation proposal**. Installing writes outside `docs/`, so it is always bucket (b). It never auto-applies, and if approved, it materializes `docs/guardrails/<slug>.md` with `afm new guardrail`, with the mandatory `## What would refute this`. Then propose the config edit to the operator.
|
|
115
|
+
- **(b) Suggestion for the human** — for friction a text edit cannot fix, but that is still a real signal. Examples: "rule N cost you 3 corrections in the window. Worth rethinking the approach, not just the text." Or: "that old `[NEEDS CLARIFICATION:]` keeps blocking every session. Do you want to decide?" This goes to the report as a recommendation. It is not an edit.
|
|
112
116
|
|
|
113
117
|
An edit can touch a `*Verification:*` command in `afm.md § 3`. Or it can touch a path the hooks parse, like a gotcha's `trigger_path` key. Either edit is **always bucket (b), load-bearing**. It never auto-applies, for the same reason as `evolve`: narrowing your own oversight carries more weight than convenience.
|
|
114
118
|
|
|
@@ -128,7 +132,7 @@ After approval, apply the change through the writing ops — `rule.md` or `gotch
|
|
|
128
132
|
|
|
129
133
|
## 5. Record + session closing + handoff
|
|
130
134
|
|
|
131
|
-
1. **Materialize or append** the reflection bundle in `<consumer>/docs/evolution/<date>-NNN.md`. Create it with `afm new evolution-report --mechanism reflect` (fix findings with `afm lint --fix`). Include the φ_b signatures, and what got self-critiqued as "it was me" (anti-oscillation memory). Also include the refinements approved or rejected, and the suggestions for the human. À-la-carte, `reflect` generates or closes this report on its own. Under `evolve`, it feeds the cycle's report instead.
|
|
135
|
+
1. **Materialize or append** the reflection bundle in `<consumer>/docs/evolution/<date>-NNN.md`. Create it with `afm new evolution-report --mechanism reflect` (fix findings with `afm lint --fix`). Include the φ_b signatures (each with its `session:<id>@<ts>` cite), list in `resolves:` the fingerprints of the signals this cycle handled (an applied or approved refinement; the next window reads it to tell `resolved` from `regressed`), and what got self-critiqued as "it was me" (anti-oscillation memory). Also include the refinements approved or rejected, and the suggestions for the human. À-la-carte, `reflect` generates or closes this report on its own. Under `evolve`, it feeds the cycle's report instead.
|
|
132
136
|
|
|
133
137
|
> **The report name is `YYYY-MM-DD-NNN.md` and its frontmatter MUST carry `mechanism: reflect`.**
|
|
134
138
|
> Three mechanisms write into `docs/evolution/`, and each one's cadence window is "since MY last
|
|
@@ -143,7 +147,7 @@ After approval, apply the change through the writing ops — `rule.md` or `gotch
|
|
|
143
147
|
- **`## what was asked`** — the agent's own reading of the user's request, including where that reading changed mid-session. This is not a transcript. It is the interpretation that guided the work.
|
|
144
148
|
- **`## how it was executed`** — how AFM was used: which ops ran, which rules fired, and where the harness helped. Also note where it got in the way. This is the data no other artifact has. Git records what changed, not how the agent used the method.
|
|
145
149
|
- **`## afm_findings`** — what generalizes to the plugin, in the format of `ops/promote.md` step 4, with `evidence:`. An explicit empty result is a valid result.
|
|
146
|
-
- **`reflection:`** — the link to the `docs/evolution/<date>-NNN` file from step 1. This field replaces a `docs_findings` field. What `reflect` found **and fixed** in the local docs already lives there. Duplicating it would be the inflation `reflect` itself forbids.
|
|
150
|
+
- **`reflection:`** — the link to the `docs/evolution/<date>-NNN` file from step 1. Fill it for **every session record the window covered**, not only the live one, with `afm sessions mark <id…> --reflection docs/evolution/<file>.md` (never by editing the store; a covered record is skipped by the next `afm sessions signals`), so the next window starts after them. This field replaces a `docs_findings` field. What `reflect` found **and fixed** in the local docs already lives there. Duplicating it would be the inflation `reflect` itself forbids.
|
|
147
151
|
|
|
148
152
|
**No session with real work means no record**, because the hook writes nothing. In that case, this step is a no-op. It is not a reason to create one. The handoff block (`state:`, `open_questions`, `next_steps`) stays episodic. `state: consumed` marks **the handoff** as read, not the record itself as dead. See `rubrics/episodic-vs-semantic-boundary.md` for this dual-tier rule.
|
|
149
153
|
2. **Does it generalize?** If the friction fits any instance, record it through `afm promote`. For example, every instance might share the same ambiguous rule. Attach evidence. Never apply it directly (rule #7). The destination is the `afm_findings` field of the session record from step 1.5. It is the same place, not two.
|
|
@@ -164,7 +168,7 @@ There, the signal is the task's own test or `tsc` result. The "re-run" is litera
|
|
|
164
168
|
|
|
165
169
|
## Anti-patterns
|
|
166
170
|
|
|
167
|
-
- ❌ **Reflecting with no lived event** — for example "this rule seems ambiguous" with no actual stumble
|
|
171
|
+
- ❌ **Reflecting with no lived event** — for example "this rule seems ambiguous" with no actual stumble in the window. That is an impression, not evidence (rule #5). No friction observed: report "no friction" only when the whole window has no signal, then run `afm cadence close --arm reflect --reason "no doc friction observed"` and stop.
|
|
168
172
|
- ❌ **Weakening a rule that embarrassed me**. A violated rule is not a wrong rule. The "it was me" hypothesis is mandatory, and it kills the refinement whenever the doc was clear.
|
|
169
173
|
- ❌ **Adding new knowledge** — that is the job of `reconcile`, `gotcha`, or `rule`. `reflect` only refines the instructiveness of what already exists. Output (c) is not an exception. It converts repeated manual analysis into a check. It adds no new knowledge, because the knowledge was already in the manual correction.
|
|
170
174
|
- ❌ **Proposing a guardrail from a single occurrence**. The same rubric gate applies here: 2 or more times, or one user correction. A gate born from a single case becomes a dead constraint (rule #5).
|
|
@@ -173,5 +177,6 @@ There, the signal is the task's own test or `tsc` result. The "re-run" is litera
|
|
|
173
177
|
- ❌ **Editing the bundled content** — absolute boundary #7. Generalization gets **recorded** through `promote`. It never gets applied. See the boundary postcondition in `evolve.md § Phase 4.3`.
|
|
174
178
|
- ❌ **Transcribing the session** in the session record — the transcript already exists, and `session_ref` (harness and id) points to it. The two timeline sections hold **interpretation** — what the agent understood, how it used AFM — not a log. Transcribing adds inflation and a reading cost.
|
|
175
179
|
- ❌ **Pasting a credential into the narrative**. Quoting the command run is the common leak path. Write the command with the secret redacted. Hard rule 13 covers it.
|
|
180
|
+
- ❌ **Reading a raw transcript when the signals suffice**, or **quoting text that did not pass the redaction**. `afm sessions signals` already extracts and redacts what the cycle needs. A raw read costs context and risks a secret. Quote only signal text. If a signal is not enough, say so in the report instead of opening the transcript.
|
|
176
181
|
- ❌ **Confusing this with `diagnose`** — `reflect` does not run the static 7-axis scan. Its evidence is behavioral. For the mechanical sweep of the instance, use `afm diagnose` instead.
|
|
177
182
|
- ❌ **Reaching § 5 step 3 while running under `evolve`** — the recursion guard. `evolve` Phase 1.2 composes only `reflect.md §§ 1-2`. The escalation step is scoped out of that composition on purpose. Escalating from inside the cycle that is already running `reflect` would be `reflect` calling back into its own caller.
|
|
@@ -40,7 +40,7 @@ Triggers: `afm restructure`, or natural language about **structure/staleness** (
|
|
|
40
40
|
1. **Staleness** — a doc references code that changed. The doc was not updated.
|
|
41
41
|
2. **Findability** — guidance exists but sits in the wrong layer or place. Retrieval failed even though the content was present.
|
|
42
42
|
3. **Partition by temperature** — what is always-read vs. deep on-demand reference. This is an opt-in loading-strategy proposal.
|
|
43
|
-
4. **Dead-gotcha pruning** — a gotcha whose last-bite date is old and whose count has stopped. A dry incidence is a tombstone candidate.
|
|
43
|
+
4. **Dead-gotcha pruning** — a gotcha whose last-bite date is old and whose count has stopped. A dry incidence is a tombstone candidate. The `fade` axis of `afm doctor` generalizes this: a cold orphan doc with no inject, read or edit in the window and no recent bite is a tombstone candidate too.
|
|
44
44
|
|
|
45
45
|
**It is not:**
|
|
46
46
|
- `diagnose` axis A1 (**dead reference** = the path does not exist). `restructure` staleness means the path **still exists but changed** while the doc did not. The two do not overlap.
|
|
@@ -94,7 +94,7 @@ Apply this only when a doc has **actually grown too large** (a `diagnose` A6 sig
|
|
|
94
94
|
|
|
95
95
|
- Propose a **loading strategy** mark. *Hot-always* content is needed every turn — conventions, commands, § 3 rules. *On-demand* content is deep subsystem reference. It becomes an appendix, read only when needed. The paper's split is hot / per-task / on-demand.
|
|
96
96
|
- The change is **an ADR proposal** (a doc architecture decision), **not** an automatic cut. Moving content to an on-demand appendix keeps 100% of the content (only re-partitions it) and follows the minimal-change discipline.
|
|
97
|
-
- **Opt-in:** without a real inflated doc, **do not propose** tiering. Small docs do not need it (YAGNI), and forced tiering is ceremony. This is the only `restructure` axis that can have zero findings in a healthy instance.
|
|
97
|
+
- **Opt-in:** without a real inflated doc, **do not propose** tiering. Small docs do not need it (YAGNI), and forced tiering is ceremony. This is the only `restructure` axis that can have zero findings in a healthy instance. The evidence for a tier change is the `tier-drift` axis of `afm doctor` (a cold doc used often, an idle hot or warm doc, an on-demand section read in most runs of its op). It stays a proposal at the gate: nothing changes `load:` on its own.
|
|
98
98
|
|
|
99
99
|
---
|
|
100
100
|
|
package/content/ops/update.md
CHANGED
|
@@ -163,8 +163,32 @@ noticing during the work, and that is the branch that damages a product.
|
|
|
163
163
|
validates the tag and edits `.afm/config.toml` in place. Never write that key by hand. A language agent task the
|
|
164
164
|
update prints (`artifact-language:*`) names the exact command; run it, then its 0/1 check.
|
|
165
165
|
5. **On migrate, fan out over the artifacts outside the excluded scope**: the local `docs/`, the code
|
|
166
|
-
comments, the test names. Each file gets a rewrite
|
|
167
|
-
path, marker or caveat disappeared. The checker reports; it
|
|
166
|
+
comments, the test names. Each file gets a rewrite of its language and writing style. Then an
|
|
167
|
+
adversarial check asks what fact, number, path, marker or caveat disappeared. The checker reports; it
|
|
168
|
+
never rewrites.
|
|
169
|
+
|
|
170
|
+
**Run the fan-out as one orchestrated batch, never file by file in the main session.** A file-by-file
|
|
171
|
+
rewrite in the session context spends the capable model on mechanical volume and fills the context
|
|
172
|
+
with text it reads once. Use the orchestration primitive of the harness: a workflow script (an
|
|
173
|
+
ultracode run, where the harness has one) or, failing that, its batch of parallel subagents. Build
|
|
174
|
+
the file list from step 3 BEFORE the batch starts, and pass it to the batch as data. A file the list does not name is never touched.
|
|
175
|
+
|
|
176
|
+
**The model tier follows the task tier** (`afm.md` § 1, the fan-out principle). Translation and
|
|
177
|
+
style rewrite under a fixed contract is mechanical, high-volume work:
|
|
178
|
+
- **Rewrite: the light tier** (a Haiku-class model, Haiku 5.5 today). Set the model on each
|
|
179
|
+
agent call, never once for the whole run. Give each agent a chunk of files, not one file, so the
|
|
180
|
+
concurrency stays inside `MAX_PARALLEL_SUBAGENTS`.
|
|
181
|
+
- **Check: the light tier too.** Its contract is a comparison, not a judgment: list the facts,
|
|
182
|
+
numbers, paths, markers (`[TBD]`, `[NEEDS CLARIFICATION:]`), code spans and caveats of the original,
|
|
183
|
+
and report each one the rewrite lost. Escalate ONLY a file the check flags to a capable model, for
|
|
184
|
+
one more rewrite of that file.
|
|
185
|
+
- **The orchestrator keeps the judgment**: the excluded scope, the final gate and the report to the
|
|
186
|
+
operator. Those stay on the session model.
|
|
187
|
+
|
|
188
|
+
Each rewrite brief carries the same contract: translate the prose, keep every code span, path,
|
|
189
|
+
identifier, frontmatter key and marker byte for byte, keep the headings structure, and never shorten
|
|
190
|
+
(hard rule 17). After the batch, `afm lang` reports the language of each file: a file still in the
|
|
191
|
+
old language goes back into the batch once, then to the operator.
|
|
168
192
|
6. **Never touch the excluded scope.** Not the UI strings, not the user-facing error messages, not the
|
|
169
193
|
email copy, not the seed data a user reads. An ambiguous file stays.
|
|
170
194
|
|
|
@@ -3,7 +3,7 @@ role: explorer
|
|
|
3
3
|
description: Read-only investigator. Answers one question from the code, the docs or the web, cites what it read, and changes nothing; dispatched with a brief.
|
|
4
4
|
steps: 60
|
|
5
5
|
capabilities: read, search, web
|
|
6
|
-
mcpTools: approve, config, detect, doctor, failures_promotable, feature_lint, feature_status, gate, index, lang, next_id, path, policy, preflight, version
|
|
6
|
+
mcpTools: approve, config, detect, doctor, failures_promotable, feature_lint, feature_status, gate, index, lang, next_id, path, policy, preflight, read, sessions, sessions_signals, version
|
|
7
7
|
cliDoor: false
|
|
8
8
|
---
|
|
9
9
|
You are an explorer. The message that dispatched you is your brief: follow it.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
role: reviewer
|
|
3
3
|
description: Blind auditor. Checks one piece of work it did not write against its sources and rules, and returns a verdict with evidence; dispatched with a brief.
|
|
4
4
|
capabilities: read, search, web
|
|
5
|
-
mcpTools: approve, config, detect, doctor, failures_promotable, feature_lint, feature_status, gate, index, lang, next_id, path, policy, preflight, version
|
|
5
|
+
mcpTools: approve, config, detect, doctor, failures_promotable, feature_lint, feature_status, gate, index, lang, next_id, path, policy, preflight, read, sessions, sessions_signals, version
|
|
6
6
|
cliDoor: false
|
|
7
7
|
---
|
|
8
8
|
You are a reviewer. The message that dispatched you is your brief: follow it.
|
package/content/skills/adr.md
CHANGED
|
@@ -7,8 +7,8 @@ description: |
|
|
|
7
7
|
|
|
8
8
|
# AFM — ADR
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
The CLI owns the number, the template, the frontmatter, the supersede link and the index. This skill keeps
|
|
11
|
+
only the judgment.
|
|
12
12
|
|
|
13
13
|
## When NOT to activate
|
|
14
14
|
|
|
@@ -35,7 +35,7 @@ project (signal: `afm.md` § 3.1 forward-only exists). A greenfield project forb
|
|
|
35
35
|
|
|
36
36
|
## Invariant principles
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Additional #9 (a retroactive ADR is
|
|
39
39
|
load-bearing-only) applies ONLY in a refactored project.
|
|
40
40
|
|
|
41
41
|
Passive mode (`afm reconcile`) is always on and can propose `afm adr` when it detects a "novel structural
|
|
@@ -7,8 +7,6 @@ description: |
|
|
|
7
7
|
|
|
8
8
|
# AFM — Analyze
|
|
9
9
|
|
|
10
|
-
An atomic skill. The procedure lives in the op: read it with `afm path ops/analyze.md`, end to end, and follow it exactly.
|
|
11
|
-
|
|
12
10
|
## When NOT to activate
|
|
13
11
|
|
|
14
12
|
Use `afm clarify` to resolve markers interactively. Use `afm deliver` for end-to-end delivery: it runs analyze underneath, in gating mode. Use `afm diagnose` for the health of the whole doc set.
|
|
@@ -23,12 +21,8 @@ Start from the mechanical findings: `afm feature lint <NNN> --json` covers the p
|
|
|
23
21
|
|
|
24
22
|
## Invariant principles
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Most relevant here: #2 (detection is an autonomous scan, not a question), #5 (no finding without evidence) and #6 (analyze is read-only: it reports in chat, writes no file, and remediates only on request).
|
|
27
25
|
|
|
28
26
|
## Continuous doctrine
|
|
29
27
|
|
|
30
|
-
Passive mode is
|
|
31
|
-
|
|
32
|
-
## Version
|
|
33
|
-
|
|
34
|
-
`afm version`. History: `afm path CHANGELOG.md`.
|
|
28
|
+
Passive mode (`afm reconcile`) is always on. This skill covers only active auditing.
|
|
@@ -7,8 +7,6 @@ description: |
|
|
|
7
7
|
|
|
8
8
|
# AFM — Clarify
|
|
9
9
|
|
|
10
|
-
An atomic skill. The procedure lives in the op: read it with `afm path ops/clarify.md`, end to end, and follow it literally.
|
|
11
|
-
|
|
12
10
|
## When NOT to activate
|
|
13
11
|
|
|
14
12
|
Use `afm analyze` for a read-only, multi-artifact validation that does not resolve markers. Use `afm deliver` for end-to-end delivery: it calls clarify underneath when needed.
|
|
@@ -23,12 +21,8 @@ Judgment only: a 9-category scan of the spec, a prioritized queue (at most 5 que
|
|
|
23
21
|
|
|
24
22
|
## Invariant principles
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Most relevant here: #2 is discover-first: resolve each question yourself through the scan or the docs, then ask. #4 says `[TBD]` beats invention, and a recommendation is a rejectable hypothesis, not a guess. #6 is autonomy-first: write the integration into spec § 7 and report. #8 is recommendation-first questions.
|
|
27
25
|
|
|
28
26
|
## Continuous doctrine
|
|
29
27
|
|
|
30
|
-
Passive mode is
|
|
31
|
-
|
|
32
|
-
## Version
|
|
33
|
-
|
|
34
|
-
`afm version`. History: `afm path CHANGELOG.md`.
|
|
28
|
+
Passive mode (`afm reconcile`) is always on. This skill covers only the active resolution of ambiguity.
|
|
@@ -7,7 +7,7 @@ description: |
|
|
|
7
7
|
|
|
8
8
|
# AFM — Deliver (orchestrated autonomous delivery)
|
|
9
9
|
|
|
10
|
-
The **orchestrator** of the delivery loop. One request takes "build feature X" from discovery to a delivered feature.
|
|
10
|
+
The **orchestrator** of the delivery loop. One request takes "build feature X" from discovery to a delivered feature. It does not duplicate the sub-steps: it reads and follows `afm specify`, `afm plan`, `afm tasks`, `afm clarify`, `afm analyze` and `afm reconcile` through a suppression contract. External unknowns go through {{host:nasca-research}}, or {{host:nasca-campaign}} for a deep study; ask the operator if nasca is missing.
|
|
11
11
|
|
|
12
12
|
## When NOT to activate
|
|
13
13
|
|
|
@@ -17,26 +17,10 @@ An isolated step ("just open the spec", "just generate the tasks") is the matchi
|
|
|
17
17
|
|
|
18
18
|
Run `afm preflight`. Exit 0 continues. Exit 3 means no `docs/.afm-version`: stop and suggest `afm init` (greenfield) or `afm refactor` (brownfield). Exit 4 or 5: report the line it printed. Do not fall back silently.
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## Most relevant here
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- **Discovery:** scan scoped to the feature, external unknowns through the nasca research flow (`nasca-research`, or `nasca-campaign` for a deep study; ask the operator if nasca is missing), unknowns sorted into resolved-by-scan, researchable and irreducible. One batched, recommendation-first round, capped by the protocol (`afm protocol`).
|
|
25
|
-
- **Draft:** spec, plan and tasks, verified with `afm feature lint <NNN>` plus the judgment passes of `analyze`.
|
|
26
|
-
- **Gate:** the earned questions plus the `outcome` question (`afm ask deliver`), then `afm approve <NNN>`. An explicit "go" skips the questions, never the record.
|
|
27
|
-
- **Execute:** the tasks of the `tasks:` list run in order (`core/afm.md` § 2: a red task, the green task that closes it, an optional refactor), each checked with `afm gate --staged`, then closed with `afm task done <NNN> <Txxx>`. Tasks are added with `afm task add`, never by hand. Halt on the failure of a task that is not `parallel` after the capped retry.
|
|
28
|
-
- **Reconcile:** § 8.5 plus a passive sweep.
|
|
29
|
-
|
|
30
|
-
If artifacts already exist, resume from the correct phase, including "tasks already exist, run from the first task that is not done".
|
|
31
|
-
|
|
32
|
-
## Invariant principles
|
|
33
|
-
|
|
34
|
-
Single canonical source: `afm path PRINCIPLES.md`. Universals §1-8 apply. The backbone is **#2** (discover-first: resolve unknowns by scan and research, ask only the irreducible part, never guess product or criteria) and **#6** (autonomy-first: approval at checkpoint granularity, the consolidated plan IS the proposal).
|
|
22
|
+
**#2** (discover-first: resolve unknowns by scan and research, ask only the irreducible part, never guess product or criteria) and **#6** (autonomy-first: approval at checkpoint granularity, the consolidated plan IS the proposal).
|
|
35
23
|
|
|
36
24
|
## Continuous doctrine
|
|
37
25
|
|
|
38
|
-
Passive mode is
|
|
39
|
-
|
|
40
|
-
## Version
|
|
41
|
-
|
|
42
|
-
`afm version`. History: `afm path CHANGELOG.md`.
|
|
26
|
+
Passive mode (`afm reconcile`) is always on. It runs in parallel with `afm deliver` and takes the closing turn of Phase 4 (`core/afm.md` § 8.5 plus a passive sweep).
|
|
@@ -8,9 +8,7 @@ description: |
|
|
|
8
8
|
|
|
9
9
|
# AFM — Diagnose (mechanical weakness-mining, read-only)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
> **Carve-out (does not overlap existing ops):** `analyze` audits **one feature**. `diagnose` audits the **whole instance** of `/docs/`. `reflect` uses **behavioral** evidence, where the agent stumbled. `diagnose` is **static**, based on filesystem and git. `evolve` is the **orchestrator**. It combines `diagnose` (mechanical evidence) with `reflect` (behavioral evidence) into one proposal and one gate. `diagnose` is **read-only**. It never proposes an edit or opens a gate.
|
|
11
|
+
> **Carve-out (does not overlap existing ops):** `afm analyze` audits **one feature**. `diagnose` audits the **whole instance** of `/docs/`. `afm reflect` uses **behavioral** evidence, where the agent stumbled. `diagnose` is **static**, based on filesystem and git. `afm evolve` is the **orchestrator**. It combines `diagnose` (mechanical evidence) with `afm reflect` (behavioral evidence) into one proposal and one gate. `diagnose` is **read-only**. It never proposes an edit or opens a gate.
|
|
14
12
|
|
|
15
13
|
## When NOT to activate
|
|
16
14
|
|
|
@@ -25,8 +23,6 @@ Validation of ONE feature is `afm analyze`. Behavioral friction, where a doc mis
|
|
|
25
23
|
|
|
26
24
|
## Procedure
|
|
27
25
|
|
|
28
|
-
Read the op (`afm path ops/diagnose.md`) end to end. Follow it literally.
|
|
29
|
-
|
|
30
26
|
The procedure has two phases. **Phase 0 — Scan** is gap-driven. Run `afm doctor --json`: it checks A1-A6, staleness and dead gotchas mechanically, and every finding carries a command plus `file:line`. You add A7 yourself. All 7 axes are checked, every time.
|
|
31
27
|
|
|
32
28
|
Axis A7, cross-doc contradiction, uses a paired read. That read applies an anti-false-positive layer test. An axis that cannot be covered becomes "not-covered: <reason>".
|
|
@@ -35,16 +31,12 @@ Axis A7, cross-doc contradiction, uses a paired read. That read applies an anti-
|
|
|
35
31
|
|
|
36
32
|
Phase 1 requires rival mechanisms, for example "agent non-compliant" versus "target legitimately removed". It applies an addressability filter and a self-sufficient severity matrix.
|
|
37
33
|
|
|
38
|
-
**Output** is an evidence bundle ordered by severity. Run à la carte, the skill prints the report to chat. It does not write to disk. It opens no gate. Under `evolve`, it feeds the proposal instead.
|
|
34
|
+
**Output** is an evidence bundle ordered by severity. Run à la carte, the skill prints the report to chat. It does not write to disk. It opens no gate. Under `afm evolve`, it feeds the proposal instead.
|
|
39
35
|
|
|
40
36
|
This scan has no cooldown. It is read-only and cheap. The cycle's cooldown belongs to the orchestrator.
|
|
41
37
|
|
|
42
38
|
## Invariant principles
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
Most relevant here: #2 (discover-first — diagnose with evidence before any proposal). Also #3 (mechanize-or-demote — the checks must pass the test they audit). Also #5 (no finding without evidence external to the text).
|
|
45
41
|
|
|
46
42
|
**No new principle here.** `diagnose` is a composed materialization. The doctrine lives in the op file.
|
|
47
|
-
|
|
48
|
-
## Version
|
|
49
|
-
|
|
50
|
-
Content version: `afm version` prints it.
|