@tenkara/afm-linux-arm64 4.0.0-alpha.6 → 4.0.0-alpha.8
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 +28 -0
- package/content/PRINCIPLES.md +0 -2
- package/content/README-light.md +0 -2
- package/content/README.md +0 -2
- package/content/core/ach.md +0 -5
- package/content/core/afm.md +23 -5
- package/content/core/prd.md +0 -2
- package/content/core/protocol.md +1 -3
- package/content/hooks/README.md +0 -2
- package/content/interview/bootstrap.md +4 -2
- package/content/interview/promotion.md +0 -2
- package/content/interview/refactor.md +0 -2
- package/content/interview/triggers.md +0 -2
- package/content/modules/vireya-ui/ach.patch.md +1 -1
- package/content/ops/analyze.md +8 -7
- package/content/ops/deliver.md +23 -25
- package/content/ops/diagnose.md +1 -4
- package/content/ops/evolve.md +1 -4
- package/content/ops/export-template.md +1 -1
- package/content/ops/generalize.md +1 -4
- package/content/ops/policy.md +0 -2
- package/content/ops/reflect.md +1 -4
- package/content/ops/remediate.md +1 -4
- package/content/ops/restructure.md +1 -4
- package/content/ops/rule.md +0 -2
- package/content/ops/tasks.md +18 -18
- package/content/ops/update.md +3 -2
- package/content/ops/verify.md +0 -2
- package/content/questions/init.questions.yaml +13 -0
- package/content/rubrics/failure-classification.md +0 -2
- package/content/rubrics/solid-triggers.md +0 -2
- package/content/skills/analyze.md +1 -1
- package/content/skills/deliver.md +2 -2
- package/content/skills/tasks.md +3 -3
- package/content/templates/adr.template.md +1 -1
- package/content/templates/evolution-report.template.md +0 -2
- package/content/templates/feature-plan.template.md +0 -2
- package/content/templates/feature-research.template.md +1 -2
- package/content/templates/feature-spec.template.md +1 -1
- package/content/templates/feature-tasks.induced.template.md +58 -34
- package/content/templates/feature-tasks.template.md +56 -34
- package/content/templates/protocols/p1.md +1 -1
- package/content/templates/protocols/p2.md +1 -1
- package/content/templates/protocols/p3.md +1 -1
- package/package.json +1 -1
- package/plugin/agy/plugin.json +1 -1
- package/plugin/agy/skills/afm-analyze/SKILL.md +1 -1
- package/plugin/agy/skills/afm-deliver/SKILL.md +2 -2
- package/plugin/agy/skills/afm-tasks/SKILL.md +3 -3
- package/plugin/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugin/claude-code/skills/analyze/SKILL.md +1 -1
- package/plugin/claude-code/skills/deliver/SKILL.md +2 -2
- package/plugin/claude-code/skills/tasks/SKILL.md +3 -3
- package/plugin/opencode/afm/index.js +245 -0
- package/plugin/opencode/afm/tui.js +21 -0
- package/plugin/opencode/agents/afm-executor.md +22 -14
- package/plugin/opencode/agents/afm-explorer.md +64 -28
- package/plugin/opencode/agents/afm-reviewer.md +64 -28
- package/plugin/opencode/skills/afm-analyze/SKILL.md +1 -1
- package/plugin/opencode/skills/afm-deliver/SKILL.md +2 -2
- package/plugin/opencode/skills/afm-tasks/SKILL.md +3 -3
- package/plugin/opencode/afm.js +0 -173
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: 83806200 bytes
|
|
4
|
+
sha256: a8043486f6b175685cb69dac8fdc4783eb798abeae5444bec2998a49c9b7bb77
|
package/content/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,34 @@ 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.8] - 2026-10-13
|
|
11
|
+
|
|
12
|
+
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.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **No table of contents.** `> **In this file:**` is gone from every doc; the headings say it. `core/ach.md` also loses `Author` and `Related docs`.
|
|
17
|
+
- **Feature templates.** `feature-plan` drops `Inferred stack` (it lives in `ach.md` § 1), `feature-research` writes its trigger as the frontmatter `context:`, and the guidance callouts of `feature-spec` and `feature-tasks` are plain prose.
|
|
18
|
+
- **Ancestors in the frontmatter.** The ops and the induced tasks template carry `ancestors:` instead of a body line. The protocols and the Vireya module lose their `For:` and `Context:` labels.
|
|
19
|
+
- **A feature's tasks are a frontmatter list (ADR-0020).** `tasks.md` holds `tasks:` (`kind` red, green, refactor, setup or reconcile; `scenario`, `closes`, `files`, `refs`, `validates`, `parallel`, `done`) and no checklist. The ops tell the agent to write it with `afm task add`, `afm task set` and `afm task remove` and close a task with `afm task done`, never by hand; `core/afm.md` § 2 says one TDD cycle is a red task, the green task that closes it and an optional refactor.
|
|
20
|
+
- **The artifact language is a config key.** `core/afm.md` points at `[language] artifacts` in `.afm/config.toml`, recorded with `afm config set language.artifacts <tag>`; the init questions ask it (`artifact-language`), and `ops/update.md` and the bootstrap interview leave nothing to judge.
|
|
21
|
+
- **PLUGIN-41 and PLUGIN-42 are declared in `core/afm.md` § 3** (ADR-0021), each scoped by `.afm/config.toml` (`architecture.features.roots`, `architecture.limits.folder_include`); undeclared scope means the rule skips with the reason stated.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **The ADR template carries no open marker.** The `decided_by` comment names `[TBD]` in a code span, so `afm doctor` no longer reports the template as an open marker.
|
|
26
|
+
- **The ask scope of `ops/deliver.md` is the feature folder name** (`NNN-slug`), which `afm ask --scope` now accepts verbatim.
|
|
27
|
+
|
|
28
|
+
### Consumer migration
|
|
29
|
+
|
|
30
|
+
- **tasks-frontmatter-list.** Every docs/features/NNN-slug/tasks.md moves its checklist into the frontmatter tasks: list (ADR-0020), mapped against the spec.md and plan.md next to it; a checklist with no single mapping is left unchanged and handed to the agent. (ops: custom)
|
|
31
|
+
- **artifact-language-to-config.** An artifact language declared in docs/afm.md moves to [language] artifacts in .afm/config.toml; a declaration it cannot move (not a language tag, inside a sentence, against another configured tag), or Portuguese docs with none, is handed to the agent with afm config set. (ops: custom)
|
|
32
|
+
- **rules-canonical-sync.** A PLUGIN-<n> hard rule of docs/afm.md whose text an earlier release shipped takes the current canonical text; an edited rule is held (afm update --refresh docs/afm.md#PLUGIN-<n>); a retired rule and a project rule are never touched. (ops: custom)
|
|
33
|
+
- **rules-add-missing.** A builtin PLUGIN-<n> rule that § 3 of docs/afm.md lacks entirely (PLUGIN-41 and PLUGIN-42 before this release) is added with the canonical text at its numeric position; a retired rule is never resurrected. (ops: custom)
|
|
34
|
+
- **afm-md-task-cycle.** docs/afm.md § 2 says a TDD cycle in a feature folder is a red task, the green task that closes it and an optional refactor of the tasks: list, closed with afm task done. (ops: insert x2, replace)
|
|
35
|
+
- **repair-wrapped-trigger.** A gotcha whose fires_when the old lift cut mid-sentence gets the wrapped Trigger lines back from the body. (ops: custom)
|
|
36
|
+
- **record-pristine.** 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)
|
|
37
|
+
|
|
10
38
|
## [4.0.0-alpha.5] - 2026-10-08
|
|
11
39
|
|
|
12
40
|
A shipped copy of the framework whose provenance is proven untouched is brought up to date by the update.
|
package/content/PRINCIPLES.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# AFM invariant principles
|
|
2
2
|
|
|
3
|
-
> **In this file:** Universals (apply in init AND refactor) — §1 to §8 · Extra, refactor only (brownfield) — §9 · How to reference this file
|
|
4
|
-
|
|
5
3
|
> **Single canonical source**. Other plugin docs (skill SKILL.md files, README, bootstrap.md, refactor.md, ops/*) link to this file. They do not copy it. A change here changes it everywhere.
|
|
6
4
|
|
|
7
5
|
> **Philosophy — declared autonomy**. The agent is the engine. It discovers everything it can discover (code, `/docs/`, the web) and applies changes inside the approved scope. The human enters only where it matters: **product intent** that exists only in the human's head.
|
package/content/README-light.md
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
> Zero to a populated `docs/` in about 30 min (greenfield) or retroactive on an existing project (brownfield).
|
|
4
4
|
> Prerequisite: `@tenkara/afm` installed, and one harness wired (Claude Code, OpenCode or agy), or none: the git hooks and the terminal prompt work with no AI.
|
|
5
5
|
|
|
6
|
-
> **In this file:** Prerequisite · Path A — NEW project · Path B — EXISTING project · After bootstrap — on-demand skills · Passive mode · No harness wired? · Learn more · Troubleshooting
|
|
7
|
-
|
|
8
6
|
|
|
9
7
|
---
|
|
10
8
|
|
package/content/README.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
> Version: see [`VERSION`](./VERSION). History: [`CHANGELOG.md`](./CHANGELOG.md).
|
|
4
4
|
|
|
5
|
-
> **In this file:** What it is · Invariant principles · Structure · How it reaches a project · New project · Existing project · Architectural template · Versioning · How to contribute · Distribution · Philosophy
|
|
6
|
-
|
|
7
5
|
## What it is
|
|
8
6
|
|
|
9
7
|
`content/` is the **versioned meta-framework** of AFM (Agent Flow Methodology). It guides how you build and evolve the docs of any project that adopts AFM. It is plain Markdown and YAML, with no tie to one AI harness: the `afm` CLI owns the mechanical work, and each harness adapter renders the skills and roles for its host.
|
package/content/core/ach.md
CHANGED
|
@@ -8,13 +8,8 @@ materializes_to: 'docs/ach.md'
|
|
|
8
8
|
# ACH — Architecture Guide
|
|
9
9
|
|
|
10
10
|
> Live architecture guide for {{nome do projeto}}.
|
|
11
|
-
> **Author:** owner of the architecture. Changes go through review before merge.
|
|
12
11
|
>
|
|
13
12
|
> This document answers: "Where do I put this logic?", "How do I structure this new module?", "How much testing does this change need?".
|
|
14
|
-
>
|
|
15
|
-
> **Related docs:** [`/docs/afm.md`](./afm.md) (process + hard rules), [`/docs/gotchas/`](./gotchas/) (counterintuitive surprises), [`/docs/adr/`](./adr/) (versioned decisions).
|
|
16
|
-
|
|
17
|
-
> **In this file:** 1. Macro Architecture · 2. Folder Architecture · 3. Components · 4. Test Strategy · 5. Cross-cutting Principles · 6. Code Conventions
|
|
18
13
|
|
|
19
14
|
|
|
20
15
|
---
|
package/content/core/afm.md
CHANGED
|
@@ -12,8 +12,6 @@ materializes_to: 'docs/afm.md'
|
|
|
12
12
|
>
|
|
13
13
|
> This is the **canonical source** for how to do tasks here. If `CLAUDE.md` and this doc disagree, this doc wins.
|
|
14
14
|
|
|
15
|
-
> **In this file:** 1. Principles · 2. Task flow · 2.1 When a feature needs its own folder · 2.2 Autonomous delivery mode · 3. Hard rules · 4. Guidelines by change type · 5. Signs you are off-track · 6. Definition of Done
|
|
16
|
-
|
|
17
15
|
|
|
18
16
|
---
|
|
19
17
|
|
|
@@ -83,6 +81,8 @@ materializes_to: 'docs/afm.md'
|
|
|
83
81
|
8.5 RECONCILE
|
|
84
82
|
```
|
|
85
83
|
|
|
84
|
+
In a feature folder (§ 2.1) one TDD cycle is two or three tasks of the frontmatter `tasks:` list of `tasks.md` (ADR-0020): a **red** task (step 4, `scenario: N` of the spec), then a **green** task that closes it (step 5, `closes:` the red), then an optional **refactor** (step 6). Step 8.5 is the one **reconcile** task, the last of the list. The agent adds a task with `afm task add` and closes it with `afm task done`, never by editing the list; `afm feature lint` checks the order.
|
|
85
|
+
|
|
86
86
|
### 1. READ
|
|
87
87
|
|
|
88
88
|
- `/docs/prd.md` for product context (which RF the task serves).
|
|
@@ -153,6 +153,8 @@ A failure that **crossed the terminal** becomes a failure record in the state st
|
|
|
153
153
|
|
|
154
154
|
### 8.5 RECONCILE
|
|
155
155
|
|
|
156
|
+
In a feature folder this step is the reconcile task, the last of the `tasks:` list: `afm task done` refuses it while another task is open.
|
|
157
|
+
|
|
156
158
|
Before you close the task, ask:
|
|
157
159
|
|
|
158
160
|
- **Did I learn something another dev without this session needs, to avoid breaking things?** If yes, update `/docs/`:
|
|
@@ -197,7 +199,7 @@ The user can ask to **deliver** a feature: "build feature X", "implement X", "de
|
|
|
197
199
|
1. **Gap-triggered discovery** (principle #2) — identify what is missing for delivery. Route each gap by source, and skip the scan if no gap is discoverable. (a) Code or `docs/` can answer: scan it (`grep`/glob/`Read`/Explore). (b) The web can answer (library or tech): run the nasca research flow (`nasca-research` skill, or `nasca-campaign` for a deep multi-front study) and cite its stored sources; if nasca is not installed, ask the operator instead of searching the web ad hoc. (c) No source can answer, or it is a product decision: ask (≤4 questions per call, ≤2 rounds). The loop converges: it doubles down on answers, and digs deeper only where a gap remains.
|
|
198
200
|
2. **Synthesis plus self-verification** — materialize spec and plan from the discovery. Never ask in the blind for what the code or `ach.md` already implies. Then run an **adversarial self-critique** on them (principle #6 — the verification corollary). Partition the findings into (a) self-correct with evidence, (b) irreducible and load-bearing, or (c) cosmetic. Escalate (b) to the gate, and mark (c) as `[TBD]`. *Produce → self-verify → report.*
|
|
199
201
|
3. **Single gate = the verification residue.** The gate is not a plain approve-the-plan question. It is the **bucket (b)**: the earned questions verification did not close. Each one carries evidence, a recommendation, and a note on what breaks if it is wrong. Answering it **is** approval (`afm approve` records it with the sha256 of the plan, after `afm ask deliver` collected the answers). With no residue (b) and no CRITICAL finding, there is no gate. An explicit `Go` then skips it (principle #6, the checkpoint corollary).
|
|
200
|
-
4. **Execute to completion** —
|
|
202
|
+
4. **Execute to completion** — build the `tasks:` list of `tasks.md` with `afm task add`. Run the tasks in list order: each red task, the green task that closes it, an optional refactor, then COMMIT (§ 2), and close each one with `afm task done`. Halt only on three things: a failed task that is not `parallel`, an architectural surprise (hard rule 11), or the push boundary. § 6.1 says never push alone.
|
|
201
203
|
5. **Reconcile** (§ 8.5) and close with a summary.
|
|
202
204
|
6. **Post-delivery self-reflection for large deliveries (under "go"):** two conditions apply together for this step. The delivery is **large**, which means it hits the feature-folder heuristic. It also ran under **autonomous planning**: `plan=auto`, protocol P1/P3, or you said "go". Then run `afm reflect`.
|
|
203
205
|
|
|
@@ -306,7 +308,7 @@ PLUGIN-35. **A hard rule with a 0/1 trigger needs a versioned runner in the gate
|
|
|
306
308
|
|
|
307
309
|
A trigger written only as prose in the doc works only as long as someone remembers to run it. The agent forgets exactly when context gets tight. A rule that promises verification with no runner is a **phantom gate**. It is worse than no gate, because it buys trust it cannot back up.
|
|
308
310
|
|
|
309
|
-
*Verification (pre-commit):* `afm gate` (builtin runner `PLUGIN-35`) runs the same audit as `afm gate --audit`. This cross-checks `afm.md § 3` against the builtin runners and `docs/tools/gate/rules/` **in both directions**. A rule with `pre-commit`/`ci` surface and no runner fails. A runner with no matching rule fails too. A rule with `agente` (agent) surface — a judgment call, like rule 11 — is not covered.
|
|
311
|
+
*Verification (pre-commit):* `afm gate` (builtin runner `PLUGIN-35`) runs the same audit as `afm gate --audit`. This cross-checks `afm.md § 3` against the builtin runners and `docs/tools/gate/rules/` **in both directions**. A rule with `pre-commit`/`ci` surface and no runner fails. A runner with no matching rule fails too, a builtin included: the rule of every builtin ships in this section, so an up-to-date project declares it. A rule with `agente` (agent) surface — a judgment call, like rule 11 — is not covered.
|
|
310
312
|
|
|
311
313
|
PLUGIN-36. **A doc under `docs/` carries no FILESYSTEM absolute path**.
|
|
312
314
|
|
|
@@ -329,7 +331,7 @@ PLUGIN-37. **The prose of an artifact is English**.
|
|
|
329
331
|
|
|
330
332
|
The **end-user-facing strings of a consumer app are the exception to both**. The app language is a product decision that lives in that project's `prd.md`, and it is never forced.
|
|
331
333
|
|
|
332
|
-
A project whose docs are not English
|
|
334
|
+
A project whose docs are not English records it with `afm config set language.artifacts <tag>`. The gate then skips PLUGIN-37 (prose) and PLUGIN-38 (Portuguese literal in a script) for it. With no declaration the default is English. Code, test and comment (rule 21) stay English whatever is declared.
|
|
333
335
|
|
|
334
336
|
*Verification (two moments, one measurement):* the threshold lives in `afm lang` and nowhere else (rule 34). The `PreToolUse` hook (`afm hook`) runs it on the text about to be written and names the tier. The verdict arrives while the text is still a proposal. `afm gate` (builtin runner `PLUGIN-37`) runs the same measure at commit. Two copies of a measured threshold drift. The commit gate would then contradict the hook that had just approved the write. The signal is the **density** of Portuguese function words in prose, not their presence. Presence is a guaranteed false positive: every doc here quotes `**Gatilho:**`, `agente` and `### Migração de consumer` — literals the gates need to stay Portuguese. **The threshold is measured, not chosen** (§ 1.3, "a number that enters a decision carries its provenance"). The English population (n=117) peaks at **0.69**, and the Portuguese population (n=29) bottoms at **1.52**. So **1.0** falls in the gap between them. `MIN_HITS=3` removes the two 2-hit outliers at the top of the English population. **One structural exclusion:** `CHANGELOG-archive.md` — frozen historical record, not a live artifact. It is counter-proved: remove it from the runner and the archive is reported. Put it back, and it goes silent.
|
|
335
337
|
|
|
@@ -401,6 +403,22 @@ PLUGIN-40. **A normative doc cites no path that does not exist**.
|
|
|
401
403
|
|
|
402
404
|
*Verification (pre-commit):* `afm gate` (builtin runner `PLUGIN-40`) checks every backticked path in a normative doc. It runs `test -e` from the repository root and from the citing file's directory. Then a `git ls-files` fallback runs. **The fallback matches by SUFFIX**. A path written relative to a component root is accepted, even while the tracked file sits further up the tree. That is deliberate: a doc naming a path relative to a component root is not lying. But the rule only proves the file EXISTS somewhere, not that the label leads a reader to it. Seven labels passed this way on the day the rule was written, and were made explicit by hand. Exit 1 on any finding. The aggregator then decides against the ratchet.
|
|
403
405
|
|
|
406
|
+
PLUGIN-41. **No import cycle between features**.
|
|
407
|
+
|
|
408
|
+
# Hard rule PLUGIN-41 — No import cycle between features.
|
|
409
|
+
|
|
410
|
+
The directed graph "feature A imports feature B" has no cycle. A feature is a directory that one glob of `architecture.features.roots` matches (for example `src/features/*`, `src/shared/*`, `src/app`). A shared need moves to a shared folder, never into a mutual import. An import inside one feature is not an edge, and a test file is not a node.
|
|
411
|
+
|
|
412
|
+
*Verification (pre-commit):* `afm gate` (builtin runner `PLUGIN-41`) builds the import graph of the `.ts` files under the declared roots and reports each strongly connected component of more than one feature. Set `roots` in `.afm/config.toml`, under `[architecture.features]`. With no `roots` declared the runner skips and says why; it never fails a project that did not opt in.
|
|
413
|
+
|
|
414
|
+
PLUGIN-42. **A source folder holds at most `architecture.limits.folder_files` files**.
|
|
415
|
+
|
|
416
|
+
# Hard rule PLUGIN-42 — A source folder holds at most `architecture.limits.folder_files` files.
|
|
417
|
+
|
|
418
|
+
A folder that directly holds a non-generated `.ts` file counts the files directly inside it (tests and data included, not recursive). More than the limit (30 by default) is a finding: group the files in themed subfolders of the feature. A folder of data files only is not judged.
|
|
419
|
+
|
|
420
|
+
*Verification (pre-commit):* `afm gate` (builtin runner `PLUGIN-42`). Set `folder_include`, the repo-relative Bun.Glob patterns of the paths to count, under `[architecture.limits]` in `.afm/config.toml`, together with `folder_files`. With no `folder_include` the runner skips and says why. `[architecture.limits.folder_ignore]` says what else is left out: `detectors`, a subset of `generated` (generated paths) and `fixtures` (a directory named `fixtures`), both by default, and `globs`, none by default.
|
|
421
|
+
|
|
404
422
|
> **Two namespaces, and no reserved number range (3.20.0).** A rule the plugin ships is
|
|
405
423
|
> `PLUGIN-<n>` — it is the contract of the `docs/` that AFM materializes, and it arrives with
|
|
406
424
|
> its runner built into `afm gate`. A rule THIS project writes about its own code is
|
package/content/core/prd.md
CHANGED
|
@@ -10,8 +10,6 @@ materializes_to: 'docs/prd.md'
|
|
|
10
10
|
> Product Requirements Document. This is a living document. Edit it in place.
|
|
11
11
|
> Scope changes must pass through the product owner before merge.
|
|
12
12
|
|
|
13
|
-
> **In this file:** 1. Summary · 2. Problem & Opportunity · 3. Target User & Jobs-to-be-done · 4. Functional Requirements · 5. Non-Functional Requirements · 6. Goals by Stage · 7. Metrics & North Stars [PROPOSAL — confir… · 8. Risks & Mitigations [PROPOSAL — confirm] · 9. Out of Scope · 10. Glossary · 11. Naming — product vs technical identif…
|
|
14
|
-
|
|
15
13
|
|
|
16
14
|
## 1. Summary
|
|
17
15
|
|
package/content/core/protocol.md
CHANGED
|
@@ -7,8 +7,6 @@ materializes_to: 'docs/protocols/'
|
|
|
7
7
|
|
|
8
8
|
# Protocol — the autonomy posture, declared per job
|
|
9
9
|
|
|
10
|
-
> **In this file:** 1. The fields · 2. The parameters · 3. The three presets · 4. What the protocol does NOT govern · 5. Subagent: delegation ceiling, not inheritance · 6. Hard, counted, and soft · 7. Current protocol
|
|
11
|
-
|
|
12
10
|
|
|
13
11
|
A **protocol** declares how the agent and the human split decisions in a delivery. Before v4, this posture was global and implicit. It was the same for a throwaway POC and for a production refactor, with one on/off switch (`"go"`).
|
|
14
12
|
|
|
@@ -61,7 +59,7 @@ Each row is a literal that used to live scattered, and now has a name. **The `de
|
|
|
61
59
|
>
|
|
62
60
|
> **The unit is the deliverable**, not the task. It is what the ledger already counts (`afm-capture.sh` appends a `deliverable` event), and it is the granularity the operator stated — *"reflect at the end of each protocol, evolve every N protocols"*. `REFLECT_EVERY = 1` is literally that.
|
|
63
61
|
>
|
|
64
|
-
> **`REFLECT_TASKS` exists because `deliverable` alone would be a dead trigger.** The `deliverable` event fires only when a `docs/features/*/tasks.md`
|
|
62
|
+
> **`REFLECT_TASKS` exists because `deliverable` alone would be a dead trigger.** The `deliverable` event fires only when every task of the `tasks:` list of a `docs/features/*/tasks.md` is done. Work that never opens a feature folder — most work, per `§ 2.1` — never emits it. Measured in the plugin's own repo while building this feature: **25 `task` events, zero `deliverable` events**, over two months of real work. A gate anchored only on the first counter would never fire. It would be indistinguishable from a working gate, which is the worst property a gate can have.
|
|
65
63
|
>
|
|
66
64
|
> So the condition is a **disjunction**: `NDEL >= REFLECT_EVERY` **OR** `NTASK >= REFLECT_TASKS`. The first catches work that went through the delivery loop. The second catches the rest.
|
|
67
65
|
|
package/content/hooks/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# AFM hooks — shared contract
|
|
2
2
|
|
|
3
|
-
> **In this file:** Contract · Events · The Stop carve-out and the pre-commit carve-out · Where state lives · Changing a hook
|
|
4
|
-
|
|
5
3
|
The hooks of AFM 4.0 are one command, `afm hook <Event>`, not a set of scripts. Each harness adapter
|
|
6
4
|
(claude-code, opencode, agy) wires its own native events to that command and translates the payload
|
|
7
5
|
in and the decision out. The logic is TypeScript in `packages/core/src/features/hook/domain/`, so it is
|
|
@@ -10,8 +10,6 @@ load: cold
|
|
|
10
10
|
> equivalent, like "set up the project doc"). The CLI materializes everything a repository can answer; this
|
|
11
11
|
> script runs the interview for what only the operator knows, a 7-step one, and fills the result into `docs/`.
|
|
12
12
|
|
|
13
|
-
> **In this file:** Invariant principles · Initial setup · Alternate branch — from-template · Step 0 — Problem context · Step 1 — Tech stack · Step 2 — Core data model · Step 3 — Critical flows · Step 4 — Mapping to the meta-framework · Step 5 — Inherited and new rules · Step 6 — Validation rituals · Step 7 — Gotchas and ADRs · Closing · Interview anti-patterns · Interview success criteria
|
|
14
|
-
|
|
15
13
|
---
|
|
16
14
|
|
|
17
15
|
## Invariant principles (do not violate)
|
|
@@ -56,6 +54,10 @@ here. In particular:
|
|
|
56
54
|
rule: it goes to `prd.md § 11.1`, is declared and never enforced, and is what makes the english-first
|
|
57
55
|
exception mechanical. Without it, a later language migration (`afm update`) cannot tell an artifact
|
|
58
56
|
from a string the user reads, and it would translate the UI. `Decide later` records `[TBD]`.
|
|
57
|
+
The same `afm ask init` asks the artifact language (`en`, `pt-BR`, `es`, `other`), and
|
|
58
|
+
`afm init --mechanical` records a tag itself through `afm config set language.artifacts <tag>` (the
|
|
59
|
+
CLI validates the tag and edits `.afm/config.toml`). On `other` it prints that command: run it with the
|
|
60
|
+
tag the owner names. Never write the key by hand.
|
|
59
61
|
4. **Materialize:** `afm init --mechanical` (add `--dry-run` first to preview). It creates, and never
|
|
60
62
|
overwrites a file the operator already has:
|
|
61
63
|
- `docs/{prd,ach,afm,ust}.md` from the shipped skeletons, the project name from the manifest and every
|
|
@@ -8,8 +8,6 @@ load: cold
|
|
|
8
8
|
|
|
9
9
|
> This doc gives instructions **to Claude**. It detects a promotion candidate and proposes a PR.
|
|
10
10
|
|
|
11
|
-
> **In this file:** Principle · Decision table · Promotion flow · Criterion for "valid for any project" · Anti-patterns · Concrete example
|
|
12
|
-
|
|
13
11
|
|
|
14
12
|
---
|
|
15
13
|
|
|
@@ -15,8 +15,6 @@ load: cold
|
|
|
15
15
|
> project. Refactor scans existing code, proposes drafts, and asks only what the code cannot reveal
|
|
16
16
|
> (persona, pain, intentional decisions).
|
|
17
17
|
|
|
18
|
-
> **In this file:** Invariant principles · Pre-check · Part A — Code archaeology · Part B — Draft materialization + presentation · Part C — Short gap interview · Part D — Forward-only rules · 3.1 Forward-only rules · Closing · Anti-patterns · Refactor success criteria
|
|
19
|
-
|
|
20
18
|
---
|
|
21
19
|
|
|
22
20
|
## Invariant principles (do not violate)
|
|
@@ -6,8 +6,6 @@ load: cold
|
|
|
6
6
|
|
|
7
7
|
# Triggers — Signals for Doc Evolution
|
|
8
8
|
|
|
9
|
-
> **In this file:** the single principle · the trigger table · concrete examples · anti-patterns · when NOT to propose.
|
|
10
|
-
|
|
11
9
|
> This doc gives instructions to the agent. The agent reads it every session, detects a signal and proposes an edit. The agent does not apply the edit alone.
|
|
12
10
|
|
|
13
11
|
---
|
|
@@ -12,7 +12,7 @@ detect: |
|
|
|
12
12
|
|
|
13
13
|
> Applies to `/docs/ach.md`. It adds conventions for UI primitives, tokens, packages, and providers.
|
|
14
14
|
>
|
|
15
|
-
>
|
|
15
|
+
> Vireya is a token-first design system in React 19. It ships as a pnpm monorepo. It replaces shadcn-style primitives. It does not use `components.json` or `npx shadcn add`. It uses the private Gitea registry (`@vireya:registry`).
|
|
16
16
|
|
|
17
17
|
## §3.2 — UI primitives via Vireya
|
|
18
18
|
|
package/content/ops/analyze.md
CHANGED
|
@@ -44,7 +44,7 @@ Procedure (advisory mode; gating mode reuses steps 2 to 5 and replaces 6 to 8 wi
|
|
|
44
44
|
2. **Progressive load** (token-efficient, read only what is needed):
|
|
45
45
|
- `docs/features/NNN-feature/spec.md`: § 1, § 2, § 3, § 5, § 6 and, if present, § 7 Clarifications.
|
|
46
46
|
- `docs/features/NNN-feature/plan.md`: § 1, § 2, § 4, § 5, § 6 and § 7 (validation against the invariants).
|
|
47
|
-
- `docs/features/NNN-feature/tasks.md`: the
|
|
47
|
+
- `docs/features/NNN-feature/tasks.md`: the frontmatter `tasks:` list (id, kind, scenario, closes, files, refs, parallel, done) and the prose of the body.
|
|
48
48
|
- `docs/prd.md`: § 3 persona and § 4 RFs (only the sections relevant to the linked US).
|
|
49
49
|
- `docs/ust.md`: the US row linked to the feature.
|
|
50
50
|
- `docs/ach.md`: § 1 stack and § 3.1 component-type mapping.
|
|
@@ -55,13 +55,13 @@ Procedure (advisory mode; gating mode reuses steps 2 to 5 and replaces 6 to 8 wi
|
|
|
55
55
|
- **Requirements inventory:** each Gherkin scenario of spec § 3 gets an id `S1`, `S2`, ...; each success-criterion checkbox of § 2 becomes `C1`, `C2`, ...
|
|
56
56
|
- **Component inventory:** each row of plan § 2 with its file path.
|
|
57
57
|
- **Boundary inventory:** each boundary of plan § 5.
|
|
58
|
-
- **Task coverage map:** each task `T0NN` maps to a scenario (
|
|
58
|
+
- **Task coverage map:** each task `T0NN` maps to a scenario (its `scenario:`), a component (a path of its `files:` in § 2) or a hard rule (§ 7).
|
|
59
59
|
- **Constitution rule set:** the universal invariants (`PRINCIPLES.md` § 1 to 8) plus the hard rules (`afm.md` § 3) marked in `plan.md` § 7.
|
|
60
60
|
|
|
61
61
|
4. **Detection passes** (limit: **50 findings in total**; group the excess in an "overflow summary"). `afm feature lint` already produced A, C, D, E and T. You add B and F, and what is semantic in C and D.
|
|
62
62
|
|
|
63
|
-
- **A. Coverage gaps** (HIGH by default): a scenario with no
|
|
64
|
-
- **B. Constitution violation** (CRITICAL by default): the plan chose a stack that diverges from `ach.md § 1` (#5, do not invent); the spec invented a § 2 criterion not derivable from the linked US (#5); a task skips
|
|
63
|
+
- **A. Coverage gaps** (HIGH by default): a scenario with no red task and a later green task that closes it; a new component no task lists in `files:`; an applicable hard rule with no task that adds the check (rule 16 needs a Zod schema at the boundary); a missing reconcile task, the last of the list (ach update, ADR, US status, the `status` frontmatter key of the three files set to `done`); an external boundary with no input-validation task (one whose `validates:` is the boundary name; `afm feature lint` checks it) plus a procedure task that consumes it.
|
|
64
|
+
- **B. Constitution violation** (CRITICAL by default): the plan chose a stack that diverges from `ach.md § 1` (#5, do not invent); the spec invented a § 2 criterion not derivable from the linked US (#5); a task skips the red (rule 1, TDD: a green task whose `closes:` names no earlier red task); a plan § 4 decision with no rejected alternative and reason; a plan § 6 item with no rejected simpler alternative; a #6 bright line crossed with no confirmation (a destructive operation with no diff, an automatic push, a plugin edit with no confirmation). Check the session history when you can infer it. *Applying autonomously inside the scope of an invoked op is NOT a violation: #6 expects it.*
|
|
65
65
|
- **C. Inconsistency** (HIGH or MEDIUM): terminology drift (an entity with different names across spec, plan and ust); a plan § 2 component type not mapped in `ach.md § 3.1`; tasks citing a `US-NNN` missing from `ust.md`; a plan § 7 rule marked `[x]` applicable but contradicted by the content (rule 16 marked, but § 5 has no Zod); a spec § 3 scenario citing an entity field absent from the `ach.md` mini-ER.
|
|
66
66
|
- **D. Ambiguity** (LOW or MEDIUM): vague adjectives with no measurable criterion (`fast`, `scalable`, `secure`, `intuitive`, `robust`) in § 2; unresolved placeholders (`TODO`, `TKTK`, `???`, `{{x}}`) in required sections; open `[NEEDS CLARIFICATION:]` markers (a strong signal for `afm clarify`).
|
|
67
67
|
- **E. Underspecification** (HIGH or MEDIUM): a scenario with no observable `Then` ("Then it works correctly"); a task with no `US-NNN` or `RF-NN`; a § 2 criterion with no testable `[ ]`; a plan § 5 boundary with no `errors` codes.
|
|
@@ -86,7 +86,7 @@ Procedure (advisory mode; gating mode reuses steps 2 to 5 and replaces 6 to 8 wi
|
|
|
86
86
|
|
|
87
87
|
| ID | Category | Severity | Location(s) | Summary | Recommendation |
|
|
88
88
|
|---|---|---|---|---|---|
|
|
89
|
-
| F01 | Coverage Gap | HIGH | tasks.md (no T for scenario S2) | Scenario "<name>" has no
|
|
89
|
+
| F01 | Coverage Gap | HIGH | tasks.md (no T for scenario S2) | Scenario "<name>" has no red and green task | `afm task add NNN --kind red --scenario 2 ...`, then `--kind green --closes <its id>` |
|
|
90
90
|
| F02 | Constitution | CRITICAL | plan.md § 7 + § 5 | Rule 16 marked [x] but Zod missing from § 5 contracts | Add the Zod schema to § 5 boundary <name> |
|
|
91
91
|
| F03 | Ambiguity | MEDIUM | spec.md § 2 | "Works fast" with no measurable criterion | Replace with "p95 < Xms" or similar |
|
|
92
92
|
|
|
@@ -94,7 +94,7 @@ Procedure (advisory mode; gating mode reuses steps 2 to 5 and replaces 6 to 8 wi
|
|
|
94
94
|
|
|
95
95
|
| Scenario/Component/Rule | Has task? | Task IDs | Notes |
|
|
96
96
|
|---|---|---|---|
|
|
97
|
-
| S1 (happy path) | yes | T004 (
|
|
97
|
+
| S1 (happy path) | yes | T004 (red), T005 (green) | |
|
|
98
98
|
| S2 (error) | no | — | F01 |
|
|
99
99
|
| Component: `src/features/<feature>/domain/x.ts` (new) | yes | T001, T004, T005 | |
|
|
100
100
|
| Component: `src/lib/storage/presigned.ts` (new) | partial | T009, T010 | no retry test task |
|
|
@@ -114,13 +114,14 @@ Procedure (advisory mode; gating mode reuses steps 2 to 5 and replaces 6 to 8 wi
|
|
|
114
114
|
- Only **MEDIUM** or **LOW**: "OK to proceed. Optional suggestions are in the tables above."
|
|
115
115
|
- A **HIGH** with no CRITICAL: "Consider resolving before T001: coverage gaps tend to surface as production bugs."
|
|
116
116
|
|
|
117
|
-
8. **Offer remediation:** ask the question `remediation` (`afm ask analyze --scope <slug>`). `top-5` applies the 5 edits in severity order and reports what changed with the paths (#6: "yes" is the approval; review with `git diff`). `top-10` does the same with 10. `report-only` closes with "Report complete. Addressing manually." Edits to `spec.md`, `plan.md` or `tasks.md` invalidate a recorded delivery approval (`afm approve --check <NNN>`); the next gate asks again.
|
|
117
|
+
8. **Offer remediation:** ask the question `remediation` (`afm ask analyze --scope <slug>`). `top-5` applies the 5 edits in severity order and reports what changed with the paths (#6: "yes" is the approval; review with `git diff`). `top-10` does the same with 10. `report-only` closes with "Report complete. Addressing manually." A task is added with `afm task add` and closed with `afm task done`, never by editing the `tasks:` list by hand. Edits to `spec.md`, `plan.md` or `tasks.md` invalidate a recorded delivery approval (`afm approve --check <NNN>`); the next gate asks again.
|
|
118
118
|
|
|
119
119
|
## Anti-patterns
|
|
120
120
|
|
|
121
121
|
- ❌ **Advisory mode:** applying fixes the operator did NOT ask for. The report is read-only; remediation runs only on `top-5` or `top-10` (then #6 authorizes applying and reporting). *(In gating mode it is the opposite: bucket (a) auto-corrects with no question, because the `deliver` gate is the approval.)*
|
|
122
122
|
- ❌ **Advisory mode:** writing the report to a file. It is chat-only: a visual audit, not a versioned artifact. *(In gating mode there is no chat report: the sorted result goes back to the caller.)*
|
|
123
123
|
- ❌ Recomputing by hand what `afm feature lint` already reported. Start from its findings.
|
|
124
|
+
- ❌ Remediating `tasks.md` by hand: a missing task goes in with `afm task add`, and a task is closed only with `afm task done`.
|
|
124
125
|
- ❌ Exceeding 50 findings. Group the overflow at the end of the report.
|
|
125
126
|
- ❌ Inventing a finding with no evidence (#5). List only what is visible in the files read.
|
|
126
127
|
- ❌ **Advisory mode:** blocking T001. Analyze is a suggestion and the operator decides. *(In gating mode the loop until zero CRITICAL and HIGH before proceeding is the point.)*
|
package/content/ops/deliver.md
CHANGED
|
@@ -7,8 +7,6 @@ composes: ["specify", "plan", "tasks", "clarify", "analyze", "reconcile"]
|
|
|
7
7
|
---
|
|
8
8
|
# Sub-flow: autonomous feature delivery (`deliver`)
|
|
9
9
|
|
|
10
|
-
> **In this file:** Conventions · Pre-check · The loop · Phase 0 — Discovery · Phase 1 — Draft spec, plan, tasks · Phase 2 — Single gate · Phase 3 — Execute · Phase 4 — Reconcile · Suppression contract · Anti-patterns
|
|
11
|
-
|
|
12
10
|
> **Form** — effect: spec/plan/tasks + commits · trigger: `afm deliver`, delivery NL · precondition: `.afm-version` · composed of: — (orchestrator) · **degree of freedom: medium**
|
|
13
11
|
|
|
14
12
|
Triggers: `afm deliver [<feature-desc|slug>]`, or natural language for **delivery**: "build feature X", "implement X end to end", "deliver X", "the tasks already exist, run them", "continue the delivery of feature N".
|
|
@@ -20,7 +18,7 @@ Triggers: `afm deliver [<feature-desc|slug>]`, or natural language for **deliver
|
|
|
20
18
|
## Conventions
|
|
21
19
|
|
|
22
20
|
- **The CLI owns the state.** Phase, next task, blockers, ids, task marks, the approval record and the gate are `afm` commands. The files on disk are the only delivery state: nothing is kept in memory across a halt.
|
|
23
|
-
- **Ask = question data.** The fixed decisions of this op are in `questions/deliver.questions.yaml`. Run `afm ask deliver --scope <slug>` (a harness renders it natively; a terminal prompts; with no terminal pass `--answers <file>`, and an open question exits 2). Record one answer with `afm answer deliver <id> <label> --scope <slug>`. The scope is the feature slug, so each feature asks afresh.
|
|
21
|
+
- **Ask = question data.** The fixed decisions of this op are in `questions/deliver.questions.yaml`. Run `afm ask deliver --scope <NNN-slug>` (a harness renders it natively; a terminal prompts; with no terminal pass `--answers <file>`, and an open question exits 2). Record one answer with `afm answer deliver <id> <label> --scope <NNN-slug>`. The scope is the feature folder name (`NNN-slug`), so each feature asks afresh.
|
|
24
22
|
- **Dynamic question.** A question whose text comes from this feature (a product decision found in discovery) cannot live in a file. Put it to the operator through whatever question facility the host offers, in the same shape as a question-file entry: a header of at most 12 characters, 2 to 4 options, the recommended option first with its reason, and the evidence. With no such facility, ask in plain chat. Record the answer in `spec.md § 7`.
|
|
25
23
|
- **Roles.** Dispatch an `explorer` (read-only) for scans of the code. External research goes to nasca, never to a role. Delegation follows the protocol's delegation ceiling. If the host cannot spawn a role, run the work inline.
|
|
26
24
|
- **Capabilities.** Write files with `fs.write`, run commands with `shell.exec`, read pages with `web.read`, and keep the live checklist with `task.track`. `task.track` is a view for the operator, never the state: the state is `tasks.md`.
|
|
@@ -43,7 +41,7 @@ The artifacts on disk are the state. After each step run:
|
|
|
43
41
|
afm feature status <NNN> --json # {phase, status, next_task, blockers}; status is the fm value of spec.md
|
|
44
42
|
```
|
|
45
43
|
|
|
46
|
-
and jump to the phase it names. `<NNN>` is the folder number (or the full `NNN-slug`). A halt leaves `
|
|
44
|
+
and jump to the phase it names. `<NNN>` is the folder number (or the full `NNN-slug`). A halt leaves `done: true` on the done tasks and `done: false` on the one that failed, so re-invoking `deliver` resumes exactly there. This also covers an operator who ran `afm specify` or `afm plan` by hand and then said "now deliver it".
|
|
47
45
|
|
|
48
46
|
| `phase` | Meaning | Go to |
|
|
49
47
|
| --- | --- | --- |
|
|
@@ -52,8 +50,8 @@ and jump to the phase it names. `<NNN>` is the folder number (or the full `NNN-s
|
|
|
52
50
|
| `spec` | folder with no `spec.md` | Phase 1.B |
|
|
53
51
|
| `plan` | `spec.md`, no `plan.md`, no open marker | Phase 1.C |
|
|
54
52
|
| `tasks` | `plan.md`, no `tasks.md`, no open marker | Phase 1.D |
|
|
55
|
-
| `execute` | `tasks.md` has
|
|
56
|
-
| `reconcile` | every task is
|
|
53
|
+
| `execute` | the `tasks:` list of `tasks.md` has a task with `done: false`; `next_task` is the first one | Phase 2 (when no valid approval), else Phase 3 |
|
|
54
|
+
| `reconcile` | every task is done | Phase 4 |
|
|
57
55
|
|
|
58
56
|
When `blockers` is non-empty in `execute`, the next task depends on an unconfirmed assumption (see 2.C): halt there.
|
|
59
57
|
|
|
@@ -99,7 +97,7 @@ If 0.A0 found a similar feature, ADR or gotcha, the spec and plan **compose from
|
|
|
99
97
|
- **1.A — Trigger heuristic, from the scan, no question.** Reuse `afm specify` step 2 and `afm.md § 2.1`: does it hit `>1 day OR >200 lines OR >3 files OR new layer/component OR new external boundary OR >2 unknowns`? **No**: a trivial change. Say "this is small, going straight to the § 2 loop", skip the feature folder and run the `core/afm.md § 2` cycle once. **Yes**: continue.
|
|
100
98
|
- **1.B — `spec.md`.** Follow `afm specify` steps 3 to 9. Suppress its step 2 (computed in 1.A) and its per-artifact diff. Irreducible items from the force-exit become the spec's `[NEEDS CLARIFICATION:]` entries. Answers resolved in 0.E go into `§ 7 Clarifications` (the integration of `afm clarify`).
|
|
101
99
|
- **1.C — `plan.md`.** Follow `afm plan` steps 4 to 10, 12. Read `ach.md` for the stack and never reopen it. Fill § 2, § 4, § 5, § 6 and § 7 (binary validation against `afm.md § 3`). The steps that ask in standalone mode (the components, the decisions, the contracts) are **filled from the discovery model** here. Suppress its step 3 (Phase 0 already tried the markers) and its diff.
|
|
102
|
-
- **1.D — `tasks.md`.** Follow `afm tasks` steps 4 to 7. The
|
|
100
|
+
- **1.D — `tasks.md`.** Follow `afm tasks` steps 4 to 7: add every task with `afm task add`, never by hand. The `tasks:` list covers setup, a red task and the green task that closes it per scenario, the boundary, and one reconcile task, last, with `parallel` where it applies and a US or RF on every task. Suppress its step 2 for markers already resolved or deferred as cosmetic; a load-bearing marker adopted under "go" (see 2.C) stays on the task that depends on it. The reconcile task (it sets the `status:` keys to `done`) runs last, because it edits the hashed documents; `afm task done` refuses it while another task is open.
|
|
103
101
|
- **1.E — Verification (`afm analyze`, gating mode).** Run `afm feature lint <NNN>` (`--json` for machines): it does the mechanical passes A, C, D, E and the structure of `tasks.md`, and exits 1 on CRITICAL or HIGH. Add the judgment passes of `afm analyze` (constitution, duplication, severity) on top. **Sort** every finding into the three buckets of the verification corollary (#6 in [`../PRINCIPLES.md`](../PRINCIPLES.md)):
|
|
104
102
|
- **(a) resolvable by evidence**: the fix comes from the scan or the research. Correct the draft and note it in the digest.
|
|
105
103
|
- **(b) load-bearing and not resolvable**: it becomes an **earned question** (evidence, a recommendation, "what breaks if this is wrong") carried to the gate.
|
|
@@ -113,15 +111,15 @@ If 0.A0 found a similar feature, ADR or gotcha, the spec and plan **compose from
|
|
|
113
111
|
|
|
114
112
|
`deliver` collapses four sequential approvals (spec, plan, tasks, T001) into **one** gate. It carries exactly bucket (b) of 1.E: the load-bearing residue that self-critique did not close. Answering those earned questions IS the approval. The criterion does not depend on the host or its modes; the host only changes how the approval is shown.
|
|
115
113
|
|
|
116
|
-
The approval is a record, not a chat message: `afm approve <NNN>` stores the sha256 of `plan.md`, `spec.md` and `tasks.md` (
|
|
114
|
+
The approval is a record, not a chat message: `afm approve <NNN>` stores the sha256 of `plan.md`, `spec.md` and `tasks.md` (`done: true` reads as `done: false`, so progress is not an edit). `afm approve --check <NNN>` exits 0 only while those hashes still match. **Any edit to a hashed document after approval invalidates it and sends the delivery back to this gate.**
|
|
117
115
|
|
|
118
116
|
- **2.A — Bucket (b) empty and no CRITICAL.** There is no residue to decide.
|
|
119
117
|
- `plan=auto`: skip the question. Print one line ("Plan: N tasks, M components, K boundaries. Verification is clean, you said go, proceeding.") and record the approval (2.D).
|
|
120
118
|
- `plan=assisted`: the gate is a light approval with no earned questions (2.C).
|
|
121
|
-
- **2.B — Build ONE consolidated proposal.** The approach in three sentences (plan § 1), the component table (§ 2), the boundaries (§ 5), a summary of the tasks (count per
|
|
119
|
+
- **2.B — Build ONE consolidated proposal.** The approach in three sentences (plan § 1), the component table (§ 2), the boundaries (§ 5), a summary of the tasks (count per kind, total, parallel), the earned questions of bucket (b) each with evidence, a recommendation and "what breaks if this is wrong", and a verification digest ("self-corrected X (a). These N decisions need you (b). Y became `[TBD]` (c). Scanned and researched Z."). **Every quantitative number in the proposal carries its provenance: "(measured | estimated, how)".** An unlabelled estimate reads as a measurement. Evidence: a plan said "~37% fewer tokens" with no label, and the later measurement was -3.3%.
|
|
122
120
|
- **2.C — Present it.**
|
|
123
121
|
- **There are (b) questions**: ask them as dynamic questions, at most `QUESTION_CAP` per call and respecting the `ROUND_CAP` of #8. Answering resolves the residue **and** approves. Fold the answers into spec and plan.
|
|
124
|
-
- **Then the outcome**: `afm ask deliver --scope <slug>` puts the question `outcome`: `run-to-completion` (recommended), `pause-per-phase` (sets `HALT_PER_PHASE`), `materialize-only`, `adjust-or-cancel`. With no (b) questions it is the only question of the gate.
|
|
122
|
+
- **Then the outcome**: `afm ask deliver --scope <NNN-slug>` puts the question `outcome`: `run-to-completion` (recommended), `pause-per-phase` (sets `HALT_PER_PHASE`), `materialize-only`, `adjust-or-cancel`. With no (b) questions it is the only question of the gate.
|
|
125
123
|
- **`plan=auto` with bucket (b) non-empty and no CRITICAL**: the operator said "go". Adopt your own recommendation for each (b) item as the default and log it as a `[NEEDS CLARIFICATION:]` assumption in the spec, so it is documented and not guessed in silence. Every (b) item changes the structural inventory, by the #6 test, so **the tasks that depend on it are born tagged with the marker** and `afm feature status` reports them in `blockers`. The Phase 3 driver halts on the first one and reports the assumption before building on it. Tasks that do not depend on it continue.
|
|
126
124
|
- **A (b) item that is CRITICAL** (it changes the inventory of the whole plan): ask even with "go". Autonomy is not recklessness (rule 11).
|
|
127
125
|
- `materialize-only` ends here with the drafts on disk. `adjust-or-cancel` means no approval: take the change the operator asks for, edit the drafts, re-run 1.E and return to 2.B, or stop.
|
|
@@ -131,20 +129,20 @@ The approval is a record, not a chat message: `afm approve <NNN>` stores the sha
|
|
|
131
129
|
|
|
132
130
|
## Phase 3 — Execute to the end
|
|
133
131
|
|
|
134
|
-
|
|
132
|
+
The tasks run in list order, as [`core/afm.md § 2`](../core/afm.md) sets the cycle: a red task, the green task that closes it, an optional refactor, then COMMIT. The loop lives there and is not restated here (rule 34). This driver changes two things: READ is already warm from discovery, and a green task that fails runs the capped reflect-retry of `core/afm.md § 5.1` **before** any halt, grounded in the test or type-checker output.
|
|
135
133
|
|
|
136
134
|
Drive it with the loop of this op. Repeat until `phase` is `reconcile`:
|
|
137
135
|
|
|
138
136
|
1. `afm feature status <NNN> --json`. `phase` is `execute` and `next_task` is `T`. A non-empty `blockers` halts here (an adopted assumption): report it and stop, resumable.
|
|
139
137
|
2. `afm approve --check <NNN>`. Non-zero means a hashed document changed: go back to Phase 2.
|
|
140
138
|
3. Mirror `T` in `task.track` and run the cycle. Run `afm gate --staged` before the commit and fix what it reports; the commit-time hook runs the same gate. Commit with a reference to a US or RF.
|
|
141
|
-
4. On success run `afm task done <NNN> T
|
|
142
|
-
5. **A
|
|
143
|
-
6. **A `
|
|
144
|
-
7. **Phase boundary** with `HALT_PER_PHASE` on: summarize the phase and ask the fixed question `phase-continue` (`afm ask deliver --scope <slug>`). Otherwise continue silently.
|
|
139
|
+
4. On success run `afm task done <NNN> T`, never an edit of the list. This is the source of truth for resumability. When `T` is the reconcile task, run Phase 4.A first: `afm task done` refuses it while another task is open.
|
|
140
|
+
5. **A task that is not `parallel` fails**: run the capped reflect-retry, at most `RETRY_CAP` retries (default 2). The same failure twice is an oscillation: stop at once. If it still fails, **HALT**: report which task, what failed, the error, what the retries tried and a suggested fix. Leave the task `done: false`; re-invoking `deliver` resumes from it.
|
|
141
|
+
6. **A `parallel` task fails**: once the retry is exhausted, continue the sibling parallel tasks, collect the failure and report it at the end of the phase.
|
|
142
|
+
7. **Phase boundary** with `HALT_PER_PHASE` on: summarize the phase and ask the fixed question `phase-continue` (`afm ask deliver --scope <NNN-slug>`). Otherwise continue silently.
|
|
145
143
|
|
|
146
144
|
> **Scope: `tasks.md` is the ceiling, not the floor.** Autonomy (#6) is permission to execute without asking *inside* the approved scope, not to widen it.
|
|
147
|
-
> -
|
|
145
|
+
> - A refactor task applies to the code the task touched, not to code that happened to be nearby. Do not invent an abstraction for a hypothetical requirement and do not add a `try/catch` for a scenario that cannot happen (rule 16 puts validation at the boundary).
|
|
148
146
|
> - Not narrowing matters too. "Done" with half the task finished is the mirror failure. If something is stuck, do the rest, say plainly what is left and why. A declared partial is a result; a silent partial is debt.
|
|
149
147
|
> - If you conclude the task is wrong, or a better path exists, say so in one sentence and continue with the task as approved. Resizing the work is the operator's decision. An architectural divergence already falls under rule 11: stop and ask.
|
|
150
148
|
|
|
@@ -154,27 +152,27 @@ Drive it with the loop of this op. Repeat until `phase` is `reconcile`:
|
|
|
154
152
|
|
|
155
153
|
| Situation | What `deliver` does |
|
|
156
154
|
| --- | --- |
|
|
157
|
-
| Task (
|
|
158
|
-
| A
|
|
155
|
+
| Task (parallel or not) passes | `afm task done`, continue |
|
|
156
|
+
| A task that is not `parallel` fails | Capped reflect-retry; if it still fails, **HALT** with the report. The task stays `done: false`. Resumable |
|
|
159
157
|
| Same failure twice (oscillation) | **HALT** at once |
|
|
160
|
-
| A `
|
|
158
|
+
| A `parallel` task fails | Retry runs out, continue the siblings, report at the end of the phase |
|
|
161
159
|
| `afm approve --check` fails | Back to the Phase 2 gate: a hashed document changed |
|
|
162
160
|
| Phase boundary + `HALT_PER_PHASE` | Pause, summarize, ask `phase-continue` |
|
|
163
161
|
| Architectural surprise (rule 11: new layer, first-class component, cross-module contract, folder refactor) | **STOP and ask**. Applies even with `plan=auto` |
|
|
164
162
|
| `blockers` names an adopted assumption | **HALT** on the first dependent task and report it |
|
|
165
|
-
| Every task
|
|
163
|
+
| Every task done | Phase 4 and a final summary |
|
|
166
164
|
| Ready to push | **Never push on your own.** Print the § 6.1 reminder and stop |
|
|
167
165
|
|
|
168
|
-
**Bright line.** Inside an approved plan `deliver` is autonomous. It stops for the operator at five boundaries: (1) the single gate, unless "go" was said, (2) a
|
|
166
|
+
**Bright line.** Inside an approved plan `deliver` is autonomous. It stops for the operator at five boundaries: (1) the single gate, unless "go" was said, (2) a failure of a task that is not `parallel` that persists after the capped retry, (3) a rule-11 surprise, (4) the push, (5) a task that depends on an unconfirmed adopted assumption.
|
|
169
167
|
|
|
170
168
|
---
|
|
171
169
|
|
|
172
170
|
## Phase 4 — Reconcile
|
|
173
171
|
|
|
174
|
-
- **4.A** The
|
|
172
|
+
- **4.A** The reconcile task runs inside the Phase 3 loop, as the last task: `ach.md § 3` for a new component, an ADR (`afm adr new <slug>`) for an architectural decision, the US status set to done. It also sets the `status:` frontmatter of `spec.md`, `plan.md` and `tasks.md` to `done` (never a body Status line), which makes the approval stale by design: nothing runs after it.
|
|
175
173
|
- **4.B** Hand the closing turn to `afm reconcile` (always-on): a gotcha that bit twice, a rule the operator corrected, a learning that generalizes to the template. It **proposes**; `deliver` does not reimplement it.
|
|
176
174
|
- **4.C — Final output.** The feature path, tasks done over total, the files touched, the commits made, the `[NEEDS CLARIFICATION:]` and `[TBD]` entries that remain, and reconcile's proposals. Add the **§ 6.1 pre-push reminder**: "run the ritual before you push, I did not push on my own".
|
|
177
|
-
- **4.D — Post-delivery self-reflection (composes `afm reflect`).** This step does not decide the cadence. `REFLECT_EVERY` does (`core/protocol.md § 2`), enforced by the session-stop hook. What remains here is the context note: under `plan=auto` the operator reviewed less inline, so a reflection tends to yield more. When the cadence calls for it, run `afm reflect` after 4.C. It keeps its own gate and never self-applies (#6); with no friction observed in the session it reports that and stops. A session that ends before 4.D does not fire it later on its own: re-invoking `deliver` on a feature
|
|
175
|
+
- **4.D — Post-delivery self-reflection (composes `afm reflect`).** This step does not decide the cadence. `REFLECT_EVERY` does (`core/protocol.md § 2`), enforced by the session-stop hook. What remains here is the context note: under `plan=auto` the operator reviewed less inline, so a reflection tends to yield more. When the cadence calls for it, run `afm reflect` after 4.C. It keeps its own gate and never self-applies (#6); with no friction observed in the session it reports that and stops. A session that ends before 4.D does not fire it later on its own: re-invoking `deliver` on a feature whose tasks are all done lands in Phase 4 and re-evaluates.
|
|
178
176
|
|
|
179
177
|
---
|
|
180
178
|
|
|
@@ -203,9 +201,9 @@ Drive it with the loop of this op. Repeat until `phase` is `reconcile`:
|
|
|
203
201
|
- ❌ Duplicating procedure from specify, plan, tasks and the rest. Read the op and follow it. Suppress only through the contract above.
|
|
204
202
|
- ❌ More than `MAX_DISCOVERY_ROUNDS` rounds, or more than `QUESTION_CAP` questions per round. The anti-interrogation cap is hard.
|
|
205
203
|
- ❌ Executing a task before `afm approve` recorded the approval, or past a failing `afm approve --check`.
|
|
206
|
-
- ❌ Editing `spec.md`, `plan.md` or `tasks.md` during Phase 3 to make a task pass
|
|
204
|
+
- ❌ Editing `spec.md`, `plan.md` or `tasks.md` during Phase 3 to make a task pass, or closing a task by editing the `tasks:` list instead of `afm task done`. An edit invalidates the approval; if the plan is wrong, go back to the gate.
|
|
207
205
|
- ❌ Pushing on your own, or crossing the rule-11 boundary without asking. Both apply even with `plan=auto`.
|
|
208
|
-
- ❌ Continuing after a
|
|
206
|
+
- ❌ Continuing after the failure of a task that is not `parallel`. Halt, report, stay resumable. The capped retry **precedes** the halt; what is forbidden is going *past* the cap, or halting flat when the signal is cheap to re-run.
|
|
209
207
|
- ❌ Stealing the intent of a standalone step. "Just generate the tasks" or "just open the spec" belongs to the atomic op, not to `deliver`.
|
|
210
208
|
- ❌ Delivering without self-verification. 1.E is mandatory: *produce, self-verify, report*.
|
|
211
209
|
- ❌ Putting into the gate what verification could self-correct (a) or defer (c). The gate carries only bucket (b), each with an articulable "what breaks if this is wrong" (#8 earned).
|
package/content/ops/diagnose.md
CHANGED
|
@@ -4,11 +4,10 @@ description: Scans the instance mechanically for weakness and reports what it me
|
|
|
4
4
|
load: warm
|
|
5
5
|
writes: []
|
|
6
6
|
composes: []
|
|
7
|
+
ancestors: the *Weakness Mining* stage of Self-Harness (arXiv 2606.09498).
|
|
7
8
|
---
|
|
8
9
|
# Sub-flow: mechanical weakness-mining of the methodology (`diagnose`)
|
|
9
10
|
|
|
10
|
-
> **In this file:** What diagnose is / is not · Pre-check · Phase 0 — Scan · Phase 1 — Diagnosis (≈ Reflect ρ) — role… · Output — evidence bundle · Anti-patterns
|
|
11
|
-
|
|
12
11
|
|
|
13
12
|
> **Form** — effect: **read-only** (evidence bundle) · trigger: `afm diagnose`, composition · precondition: `.afm-version`, git · composed by: `evolve` 1.1 · **degree of freedom: low**
|
|
14
13
|
|
|
@@ -18,8 +17,6 @@ Triggers: `afm diagnose`. Also natural language for a **health scan**: "diagnose
|
|
|
18
17
|
>
|
|
19
18
|
> **Read-only mechanism, not a conductor.** `diagnose` is the mechanism-skill that runs the **mechanical scan** of the instance's health and returns an **evidence bundle** — no edit proposal, no gate, no mutation. The `evolve` orchestrator composes it (together with `reflect`) to feed the cycle. À la carte, it is a **health report**.
|
|
20
19
|
>
|
|
21
|
-
> **Ancestor:** the *Weakness Mining* stage of Self-Harness (arXiv 2606.09498).
|
|
22
|
-
>
|
|
23
20
|
> WeaknessMining(traces, verifier):
|
|
24
21
|
> 1. ANALYZER := the role that only finds # "you are an ANALYZER, not a solver"
|
|
25
22
|
> — it proposes no edit and picks no fix
|
package/content/ops/evolve.md
CHANGED
|
@@ -4,11 +4,10 @@ description: 'Runs the self-evolution cycle: five mechanisms plus update, under
|
|
|
4
4
|
load: warm
|
|
5
5
|
writes: ["docs/evolution/*.md"]
|
|
6
6
|
composes: ["diagnose", "reflect", "generalize", "restructure", "update", "remediate"]
|
|
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).
|
|
7
8
|
---
|
|
8
9
|
# Sub-flow: orchestrator for the AFM local documentation self-evolution cycle (`evolve`)
|
|
9
10
|
|
|
10
|
-
> **In this file:** What `evolve` is / is not · Pre-check · Phase 1 — Evidence collection · Proposal discipline · Phase 2 — Proposal · Phase 3 — Single gate (≈ Commit κ) — always ha… · Phase 4 — Application + postconditions · Phase 5 — Record + promote · Whitelist — evolvable vs. protect… · Suppression contract · Anti-patterns
|
|
11
|
-
|
|
12
11
|
|
|
13
12
|
> **Form** — effect: `docs/evolution/<date>-NNN` · trigger: `afm evolve`, **cadence** · precondition: `.afm-version`, cooldown 14d · composed of: — (orchestrator) · **degree of freedom: medium**
|
|
14
13
|
|
|
@@ -41,8 +40,6 @@ Triggers:
|
|
|
41
40
|
>
|
|
42
41
|
> This materializes, with no new principle, the combination of invariants #2 (discover-first: diagnose with evidence before proposing), #3 (mechanize-or-downgrade: the invocation signals themselves pass the test that evolve audits in others), #6 (autonomy-first with self-check: *produce → self-check → report*, with the gate as the load-bearing residue), and #8 (earned question, recommendation-first). See [`../PRINCIPLES.md`](../PRINCIPLES.md).
|
|
43
42
|
>
|
|
44
|
-
> **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).
|
|
45
|
-
>
|
|
46
43
|
> Commit(proposal):
|
|
47
44
|
> 1. ε := Evaluate(proposal) # measured, per the Autogenesis order: ε before κ
|
|
48
45
|
> 2. HeldOutSet := a re-runnable set that scores ε empirically
|
|
@@ -62,7 +62,7 @@ what to keep, the task-template induction and the final confirmation.
|
|
|
62
62
|
the selection.
|
|
63
63
|
5. **Induce a task template before `features/` goes (AWM, from a green trajectory).** Run this step only
|
|
64
64
|
when the dry run lists `docs/features/`. Take the **most recent** `docs/features/NNN-*/tasks.md` with
|
|
65
|
-
**ALL tasks
|
|
65
|
+
**ALL tasks `done: true`** in its `tasks:` list, and never induce from incomplete work. The dry run
|
|
66
66
|
names the feature, or says there is none, in which case skip the step. Turn concrete values into named
|
|
67
67
|
variables (product, entity, procedure, domain become `{product-name}`, `{entity}`,
|
|
68
68
|
`{boundary-procedure}`, `{domain}`), following `afm path templates/feature-tasks.induced.template`, and
|
|
@@ -4,11 +4,10 @@ description: Merges several gotchas that repeat into one abstract rule.
|
|
|
4
4
|
load: warm
|
|
5
5
|
writes: ["docs/gotchas/*.md", "docs/rules/*.md", "docs/afm.md", "docs/evolution/*.md"]
|
|
6
6
|
composes: []
|
|
7
|
+
ancestors: the *MetaReflect* step of MetaReflection (arXiv 2405.13009).
|
|
7
8
|
---
|
|
8
9
|
# Sub-flow: semantic consolidation of gotchas into an abstract rule (`generalize`)
|
|
9
10
|
|
|
10
|
-
> **In this file:** What `generalize` is / is not · Pre-check · 1. Identify the batch (clustering, ≥2) · 2. MetaReflect: propose the abstract rule (follow the shared discipline) · 3. ShowsImprovement + backtracking (validation before the gate) · 4. Own gate (à la carte) — suppressed under `evolve` · 5. Registration + handoff · Suppression contract (back-pointer) · Anti-patterns
|
|
11
|
-
|
|
12
11
|
> **Form** — effect: rule + tombstones · trigger: `afm generalize`, composition · precondition: ≥2 similar gotchas · composed by: `evolve` 1.3 · **degree of freedom: medium**
|
|
13
12
|
|
|
14
13
|
Triggers: `afm generalize`. Also natural-language **consolidation** requests. Examples: "these gotchas are all the same thing", "merge these rules". Also: "this became a pattern — generalize it", "I have 3 gotchas that say the same thing".
|
|
@@ -17,8 +16,6 @@ Triggers: `afm generalize`. Also natural-language **consolidation** requests. Ex
|
|
|
17
16
|
>
|
|
18
17
|
> **Mechanism, not conductor.** `generalize` is the mechanism-skill that **merges a batch of similar gotchas/reflections into one abstract rule** (episodic memory → semantic memory). It runs **à la carte** (its own gate) OR inside the `evolve` cycle (which composes it when `diagnose` flags inflation from redundant gotchas, and its own gate is suppressed).
|
|
19
18
|
>
|
|
20
|
-
> **Ancestor:** the *MetaReflect* step of MetaReflection (arXiv 2405.13009).
|
|
21
|
-
>
|
|
22
19
|
> Generalize(gotchas, batch):
|
|
23
20
|
> 1. read the current gotchas and the batch # |batch| >= 2
|
|
24
21
|
> 2. emit one abstract rule that covers the batch — ADD it, and MERGE the batch into tombstones
|
package/content/ops/policy.md
CHANGED
|
@@ -7,8 +7,6 @@ composes: []
|
|
|
7
7
|
---
|
|
8
8
|
# Sub-flow: report the organisation policy (`policy`)
|
|
9
9
|
|
|
10
|
-
> **In this file:** What policy is / is not · Procedure · What it must never do · Invariants
|
|
11
|
-
|
|
12
10
|
> **Form** — effect: a report in chat, no file written · trigger: `afm policy` · precondition: `.afm-version` · **degree of freedom: low**
|
|
13
11
|
|
|
14
12
|
Triggers: `afm policy`. Also natural language about the organisation layer. Examples: "what does the
|