@tenkara/afm-linux-arm64 0.0.0-stage → 4.0.0-alpha.6
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 +4 -0
- package/content/.coupling-baseline.tsv +1 -0
- package/content/.pending-commands.txt +2 -0
- package/content/CHANGELOG-archive.md +806 -0
- package/content/CHANGELOG.md +4256 -0
- package/content/PRINCIPLES.md +121 -0
- package/content/README-light.md +160 -0
- package/content/README.md +152 -0
- package/content/code-style/_any/file-size.md +62 -0
- package/content/code-style/_any/imports.md +68 -0
- package/content/code-style/_any/naming.md +72 -0
- package/content/code-style/_any/test-placement.md +57 -0
- package/content/code-style/nextjs-app-router/imports.md +50 -0
- package/content/code-style/nextjs-app-router/naming.md +50 -0
- package/content/code-style/prisma-postgres/error-boundary.md +55 -0
- package/content/code-style/prisma-postgres/imports.md +61 -0
- package/content/code-style/shadcn-ui/naming.md +48 -0
- package/content/code-style/stripe-billing/naming.md +76 -0
- package/content/code-style/trigger-dev-v4/imports.md +58 -0
- package/content/code-style/trigger-dev-v4/naming.md +49 -0
- package/content/code-style/trigger-dev-v4/test-placement.md +61 -0
- package/content/code-style/trpc-v11/error-boundary.md +51 -0
- package/content/code-style/trpc-v11/file-size.md +44 -0
- package/content/code-style/trpc-v11/naming.md +60 -0
- package/content/code-style/trpc-v11/test-placement.md +52 -0
- package/content/core/ach.md +265 -0
- package/content/core/afm.md +496 -0
- package/content/core/gotchas.md +18 -0
- package/content/core/prd.md +143 -0
- package/content/core/protocol.md +160 -0
- package/content/core/ust.md +65 -0
- package/content/guardrails/README.md +55 -0
- package/content/guardrails/dsl-com-ordem-obrigatoria.md +47 -0
- package/content/guardrails/exaustividade-de-union.md +48 -0
- package/content/guardrails/fronteira-de-import.md +57 -0
- package/content/hooks/README.md +72 -0
- package/content/interview/bootstrap.md +415 -0
- package/content/interview/promotion.md +117 -0
- package/content/interview/refactor.md +381 -0
- package/content/interview/triggers.md +109 -0
- package/content/modules/nextjs-app-router/ach.patch.md +44 -0
- package/content/modules/nextjs-app-router/gotchas.seed.md +78 -0
- package/content/modules/nextjs-app-router/rules.patch.md +35 -0
- package/content/modules/prisma-postgres/ach.patch.md +65 -0
- package/content/modules/prisma-postgres/rules.patch.md +28 -0
- package/content/modules/shadcn-ui/ach.patch.md +42 -0
- package/content/modules/stripe-billing/ach.patch.md +46 -0
- package/content/modules/stripe-billing/gotchas.seed.md +73 -0
- package/content/modules/stripe-billing/rules.patch.md +30 -0
- package/content/modules/trigger-dev-v4/ach.patch.md +64 -0
- package/content/modules/trigger-dev-v4/gotchas.seed.md +53 -0
- package/content/modules/trigger-dev-v4/rules.patch.md +35 -0
- package/content/modules/trpc-v11/ach.patch.md +56 -0
- package/content/modules/trpc-v11/rules.patch.md +34 -0
- package/content/modules/vireya-ui/ach.patch.md +85 -0
- package/content/modules/vireya-ui/gotchas.seed.md +98 -0
- package/content/modules/vireya-ui/rules.patch.md +36 -0
- package/content/ops/adr.md +54 -0
- package/content/ops/analyze.md +129 -0
- package/content/ops/clarify.md +86 -0
- package/content/ops/deliver.md +211 -0
- package/content/ops/diagnose.md +146 -0
- package/content/ops/evolve.md +317 -0
- package/content/ops/export-template.md +97 -0
- package/content/ops/generalize.md +120 -0
- package/content/ops/gotcha.md +46 -0
- package/content/ops/plan.md +61 -0
- package/content/ops/policy.md +63 -0
- package/content/ops/promote.md +72 -0
- package/content/ops/protocol.md +51 -0
- package/content/ops/reconcile.md +44 -0
- package/content/ops/reflect.md +180 -0
- package/content/ops/remediate.md +146 -0
- package/content/ops/restructure.md +145 -0
- package/content/ops/rule.md +165 -0
- package/content/ops/specify.md +62 -0
- package/content/ops/tasks.md +67 -0
- package/content/ops/update.md +223 -0
- package/content/ops/verify.md +69 -0
- package/content/patterns/adapter.md +46 -0
- package/content/patterns/facade.md +47 -0
- package/content/patterns/factory.md +46 -0
- package/content/patterns/null-object.md +55 -0
- package/content/patterns/result-vs-exception.md +52 -0
- package/content/patterns/strategy.md +45 -0
- package/content/patterns/template-method-vs-composition.md +50 -0
- package/content/questions/adr.questions.yaml +14 -0
- package/content/questions/analyze.questions.yaml +12 -0
- package/content/questions/bootstrap-mapping.questions.yaml +14 -0
- package/content/questions/bootstrap-rules.questions.yaml +10 -0
- package/content/questions/bootstrap-stack.questions.yaml +23 -0
- package/content/questions/clarify.questions.yaml +10 -0
- package/content/questions/code-style.questions.yaml +12 -0
- package/content/questions/confirm.questions.yaml +12 -0
- package/content/questions/deliver.questions.yaml +23 -0
- package/content/questions/evolve.questions.yaml +15 -0
- package/content/questions/export-template-apply.questions.yaml +11 -0
- package/content/questions/export-template.questions.yaml +23 -0
- package/content/questions/gates.questions.yaml +27 -0
- package/content/questions/generalize.questions.yaml +13 -0
- package/content/questions/gotcha.questions.yaml +11 -0
- package/content/questions/init-template.questions.yaml +10 -0
- package/content/questions/init.questions.yaml +28 -0
- package/content/questions/plan.questions.yaml +14 -0
- package/content/questions/refactor.questions.yaml +23 -0
- package/content/questions/reflect.questions.yaml +13 -0
- package/content/questions/remediate.questions.yaml +27 -0
- package/content/questions/restructure.questions.yaml +15 -0
- package/content/questions/rf-mapping.questions.yaml +12 -0
- package/content/questions/rule-scope.questions.yaml +12 -0
- package/content/questions/rule.questions.yaml +12 -0
- package/content/questions/specify.questions.yaml +23 -0
- package/content/questions/update-artifacts.questions.yaml +10 -0
- package/content/questions/update-strings.questions.yaml +14 -0
- package/content/questions/update.questions.yaml +10 -0
- package/content/questions/verify.questions.yaml +9 -0
- package/content/roles/executor.md +18 -0
- package/content/roles/explorer.md +22 -0
- package/content/roles/reviewer.md +23 -0
- package/content/rubrics/enum-vs-union-vs-branded.md +40 -0
- package/content/rubrics/episodic-vs-semantic-boundary.md +37 -0
- package/content/rubrics/error-classification.md +98 -0
- package/content/rubrics/failure-classification.md +113 -0
- package/content/rubrics/negative-filters.md +38 -0
- package/content/rubrics/solid-triggers.md +121 -0
- package/content/rubrics/template-vs-streaming-precedence.md +34 -0
- package/content/rubrics/validation-boundary.md +94 -0
- package/content/rubrics/when-to-create-dsl.md +65 -0
- package/content/rubrics/when-to-create-lib.md +49 -0
- package/content/rubrics/when-to-create-module.md +39 -0
- package/content/rubrics/when-to-evolve-methodology.md +62 -0
- package/content/skills/adr.md +42 -0
- package/content/skills/analyze.md +34 -0
- package/content/skills/clarify.md +34 -0
- package/content/skills/deliver.md +42 -0
- package/content/skills/diagnose.md +50 -0
- package/content/skills/evolve.md +67 -0
- package/content/skills/export-template.md +40 -0
- package/content/skills/generalize.md +47 -0
- package/content/skills/gotcha.md +40 -0
- package/content/skills/init.md +82 -0
- package/content/skills/plan.md +34 -0
- package/content/skills/policy.md +31 -0
- package/content/skills/promote.md +41 -0
- package/content/skills/protocol.md +42 -0
- package/content/skills/reconcile.md +49 -0
- package/content/skills/refactor.md +84 -0
- package/content/skills/reflect.md +53 -0
- package/content/skills/remediate.md +39 -0
- package/content/skills/restructure.md +52 -0
- package/content/skills/rule.md +44 -0
- package/content/skills/specify.md +34 -0
- package/content/skills/tasks.md +34 -0
- package/content/skills/update.md +56 -0
- package/content/skills/verify.md +31 -0
- package/content/templates/adr.template.md +51 -0
- package/content/templates/evolution-report.template.md +129 -0
- package/content/templates/feature-plan.template.md +86 -0
- package/content/templates/feature-research.template.md +57 -0
- package/content/templates/feature-spec.template.md +86 -0
- package/content/templates/feature-tasks.induced.template.md +67 -0
- package/content/templates/feature-tasks.template.md +60 -0
- package/content/templates/focus.template.md +30 -0
- package/content/templates/gotcha.template.md +31 -0
- package/content/templates/guardrail-runner.template.md +81 -0
- package/content/templates/guardrail.template.md +63 -0
- package/content/templates/learning.template.md +40 -0
- package/content/templates/procedure.template.md +47 -0
- package/content/templates/protocols/p1.md +29 -0
- package/content/templates/protocols/p2.md +28 -0
- package/content/templates/protocols/p3.md +47 -0
- package/content/templates/research.template.md +50 -0
- package/content/templates/session-handoff.template.md +58 -0
- package/content/templates/us.template.md +39 -0
- package/content/tools/gate/core-rules/PLUGIN-13-secrets.sh +36 -0
- package/content/tools/gate/core-rules/PLUGIN-21-code-language.sh +27 -0
- package/content/tools/gate/core-rules/PLUGIN-35-gate-complete.sh +19 -0
- package/content/tools/gate/core-rules/PLUGIN-36-absolute-path.sh +38 -0
- package/content/tools/gate/core-rules/PLUGIN-37-prose-language.sh +56 -0
- package/content/tools/gate/core-rules/PLUGIN-38-parser-marker.sh +82 -0
- package/content/tools/gate/core-rules/PLUGIN-39-frontmatter-ops.sh +325 -0
- package/content/tools/gate/core-rules/PLUGIN-40-dead-reference.sh +74 -0
- package/content/tools/gate/core-rules/README.md +55 -0
- package/content/tools/gate/guardrails.sh +740 -0
- package/content/tools/gate/lib/ratchet.sh +119 -0
- package/content/tools/gate/lib/scope.sh +85 -0
- package/content/tools/gate/ratchet.seed.tsv +1 -0
- package/content/tools/gate/rules/README.md +50 -0
- package/package.json +19 -5
- package/plugin/agy/hooks.json +29 -0
- package/plugin/agy/mcp_config.json +7 -0
- package/plugin/agy/plugin.json +6 -0
- package/plugin/agy/skills/afm-adr/SKILL.md +44 -0
- package/plugin/agy/skills/afm-analyze/SKILL.md +36 -0
- package/plugin/agy/skills/afm-clarify/SKILL.md +36 -0
- package/plugin/agy/skills/afm-deliver/SKILL.md +44 -0
- package/plugin/agy/skills/afm-diagnose/SKILL.md +50 -0
- package/plugin/agy/skills/afm-evolve/SKILL.md +69 -0
- package/plugin/agy/skills/afm-export-template/SKILL.md +42 -0
- package/plugin/agy/skills/afm-generalize/SKILL.md +49 -0
- package/plugin/agy/skills/afm-gotcha/SKILL.md +42 -0
- package/plugin/agy/skills/afm-init/SKILL.md +84 -0
- package/plugin/agy/skills/afm-plan/SKILL.md +36 -0
- package/plugin/agy/skills/afm-policy/SKILL.md +31 -0
- package/plugin/agy/skills/afm-promote/SKILL.md +41 -0
- package/plugin/agy/skills/afm-protocol/SKILL.md +42 -0
- package/plugin/agy/skills/afm-reconcile/SKILL.md +49 -0
- package/plugin/agy/skills/afm-refactor/SKILL.md +86 -0
- package/plugin/agy/skills/afm-reflect/SKILL.md +55 -0
- package/plugin/agy/skills/afm-remediate/SKILL.md +41 -0
- package/plugin/agy/skills/afm-restructure/SKILL.md +54 -0
- package/plugin/agy/skills/afm-rule/SKILL.md +46 -0
- package/plugin/agy/skills/afm-specify/SKILL.md +36 -0
- package/plugin/agy/skills/afm-tasks/SKILL.md +34 -0
- package/plugin/agy/skills/afm-update/SKILL.md +58 -0
- package/plugin/agy/skills/afm-verify/SKILL.md +33 -0
- package/plugin/claude-code/.claude-plugin/marketplace.json +15 -0
- package/plugin/claude-code/.claude-plugin/plugin.json +9 -0
- package/plugin/claude-code/.mcp.json +7 -0
- package/plugin/claude-code/agents/afm-executor.md +18 -0
- package/plugin/claude-code/agents/afm-explorer.md +20 -0
- package/plugin/claude-code/agents/afm-reviewer.md +21 -0
- package/plugin/claude-code/hooks/hooks.json +85 -0
- package/plugin/claude-code/skills/adr/SKILL.md +44 -0
- package/plugin/claude-code/skills/analyze/SKILL.md +36 -0
- package/plugin/claude-code/skills/clarify/SKILL.md +36 -0
- package/plugin/claude-code/skills/deliver/SKILL.md +44 -0
- package/plugin/claude-code/skills/diagnose/SKILL.md +50 -0
- package/plugin/claude-code/skills/evolve/SKILL.md +69 -0
- package/plugin/claude-code/skills/export-template/SKILL.md +42 -0
- package/plugin/claude-code/skills/generalize/SKILL.md +49 -0
- package/plugin/claude-code/skills/gotcha/SKILL.md +42 -0
- package/plugin/claude-code/skills/init/SKILL.md +84 -0
- package/plugin/claude-code/skills/plan/SKILL.md +36 -0
- package/plugin/claude-code/skills/policy/SKILL.md +31 -0
- package/plugin/claude-code/skills/promote/SKILL.md +41 -0
- package/plugin/claude-code/skills/protocol/SKILL.md +42 -0
- package/plugin/claude-code/skills/reconcile/SKILL.md +49 -0
- package/plugin/claude-code/skills/refactor/SKILL.md +86 -0
- package/plugin/claude-code/skills/reflect/SKILL.md +55 -0
- package/plugin/claude-code/skills/remediate/SKILL.md +41 -0
- package/plugin/claude-code/skills/restructure/SKILL.md +54 -0
- package/plugin/claude-code/skills/rule/SKILL.md +46 -0
- package/plugin/claude-code/skills/specify/SKILL.md +36 -0
- package/plugin/claude-code/skills/tasks/SKILL.md +34 -0
- package/plugin/claude-code/skills/update/SKILL.md +58 -0
- package/plugin/claude-code/skills/verify/SKILL.md +33 -0
- package/plugin/opencode/afm.js +173 -0
- package/plugin/opencode/agents/afm-executor.md +31 -0
- package/plugin/opencode/agents/afm-explorer.md +47 -0
- package/plugin/opencode/agents/afm-reviewer.md +48 -0
- package/plugin/opencode/skills/afm-adr/SKILL.md +44 -0
- package/plugin/opencode/skills/afm-analyze/SKILL.md +36 -0
- package/plugin/opencode/skills/afm-clarify/SKILL.md +36 -0
- package/plugin/opencode/skills/afm-deliver/SKILL.md +44 -0
- package/plugin/opencode/skills/afm-diagnose/SKILL.md +50 -0
- package/plugin/opencode/skills/afm-evolve/SKILL.md +69 -0
- package/plugin/opencode/skills/afm-export-template/SKILL.md +42 -0
- package/plugin/opencode/skills/afm-generalize/SKILL.md +49 -0
- package/plugin/opencode/skills/afm-gotcha/SKILL.md +42 -0
- package/plugin/opencode/skills/afm-init/SKILL.md +84 -0
- package/plugin/opencode/skills/afm-plan/SKILL.md +36 -0
- package/plugin/opencode/skills/afm-policy/SKILL.md +31 -0
- package/plugin/opencode/skills/afm-promote/SKILL.md +41 -0
- package/plugin/opencode/skills/afm-protocol/SKILL.md +42 -0
- package/plugin/opencode/skills/afm-reconcile/SKILL.md +49 -0
- package/plugin/opencode/skills/afm-refactor/SKILL.md +86 -0
- package/plugin/opencode/skills/afm-reflect/SKILL.md +55 -0
- package/plugin/opencode/skills/afm-remediate/SKILL.md +41 -0
- package/plugin/opencode/skills/afm-restructure/SKILL.md +54 -0
- package/plugin/opencode/skills/afm-rule/SKILL.md +46 -0
- package/plugin/opencode/skills/afm-specify/SKILL.md +36 -0
- package/plugin/opencode/skills/afm-tasks/SKILL.md +34 -0
- package/plugin/opencode/skills/afm-update/SKILL.md +58 -0
- package/plugin/opencode/skills/afm-verify/SKILL.md +33 -0
- package/README.md +0 -3
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# AFM invariant principles
|
|
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
|
+
> **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
|
+
|
|
7
|
+
> **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.
|
|
8
|
+
>
|
|
9
|
+
> **What v4 changed:** v3 fixed *one* posture for all work, with a single on/off switch (`"go"`). Now the **degree** of autonomy is declared per job, in a protocol ([`core/protocol.md`](core/protocol.md)). Principle #6 now defines the **form** — the agent materializes and reports, and review comes after. It also defines the **bright lines**, which stay fixed. A project with no declared protocol runs the defaults, the pre-v4 behavior.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Universals (apply in init AND refactor) — §1 to §8
|
|
14
|
+
|
|
15
|
+
1. **Project knowledge lives in `/docs/`, not in the agent's memory**. One hard test decides it. Would another dev, or an agent without my memory, need this to avoid a break? Then it is a doc. That second case is why this file exists.
|
|
16
|
+
|
|
17
|
+
- `<consumer>/docs/` holds rules, decisions, gotchas, architecture, persona, flows, and cross-module contracts.
|
|
18
|
+
- Claude's memory holds the user's communication style (terse or verbose, no emoji). It also holds durable preferences (small PRs against large bundles) and personal context (role, years of experience, current focus).
|
|
19
|
+
|
|
20
|
+
**Corollary:** `/docs/` is not frozen at bootstrap. It evolves every session through passive reconcile — see `interview/triggers.md` and `ops/reconcile.md`.
|
|
21
|
+
|
|
22
|
+
2. **Discover-first: discover before you ask**. A gap triggers discovery, not a mandatory sweep. This is the backbone of AFM, the default law for **every** op. The agent works as usual. When it lacks **information** to decide or build something, it judges the gap first, **in this order**:
|
|
23
|
+
1. **Does the code or `/docs/` answer it**? Signals include current state, affected components, library contracts, the matching US, the stack, an applicable rule, and a size heuristic. If yes, the agent starts **local discovery**: `grep`/glob/read, or a read-only `explorer` sub-agent.
|
|
24
|
+
2. **Does the web answer it**? Signals include an unknown about an external library or SDK, a best practice, or a comparison of approaches. If yes, the agent starts **research** through nasca: 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. A fake URL is poison.
|
|
25
|
+
3. **Neither path resolves it, or the gap is product intent**. Product intent means persona, pain point, "why now", scope cut, or a business rule. It also means an acceptance criterion the PRD does not fix — what exists only in the user's head. Only then does the agent use **`afm ask`** (#8).
|
|
26
|
+
|
|
27
|
+
**Discovery is conditional**. With no discoverable gap, there is no discovery step. The agent does not scan what it already knows, and it does not research what it does not need. Asking is not the first resort either. It comes only after (1) and (2) fail, or when the gap is clearly product intent.
|
|
28
|
+
|
|
29
|
+
This is the active side of #1, the same test, reversed. The rule reads: "if the code, the docs, or a search can answer, the agent answers". Only what nobody can discover goes to the user. Do not ask `"where is X?"`, `"what is the state of X?"`, `"which components?"`, or `"which stack?"` before you search.
|
|
30
|
+
|
|
31
|
+
**This does not weaken #4/#5**. Discovery backed by evidence — reading a schema, reading SDK docs, running `grep` — is not invention. A guess with no evidence still becomes `[TBD]`.
|
|
32
|
+
|
|
33
|
+
3. **Every hard rule has an executable trigger**. The agent runs the trigger at the keyboard (`grep`, `wc -l`, `git diff`, `tsc` — a command that returns 0 or 1). "Code review", "PR template", and "manual review" are **not** triggers. They are human processes that do not exist in an agent session.
|
|
34
|
+
|
|
35
|
+
No executable trigger means the rule is a principle instead, in `core/afm.md` § 1.3 (or the consumer's equivalent). Hard rules go to § 3 instead. Modules follow the same split: mechanical rules go to § 3, and the rest goes to § 1.3.
|
|
36
|
+
|
|
37
|
+
**Corollary (CRITIC, arXiv:2305.11738) — why a trigger, not paperwork**. LLM self-critique degrades without an external tool: measured deltas turn negative, and the critique becomes noise or poison. The executable trigger is the only critique that does not degrade, because a tool anchors it. The command reads evidence outside the doc's own text.
|
|
38
|
+
|
|
39
|
+
Self-verification under #6 is valid only when a command anchors it (`grep`, `tsc`, `git diff`, a test). It is never valid when the agent just "rereads the doc and it looks fine". That is the "CRITIC without a tool" case, which the paper measures as degrading.
|
|
40
|
+
|
|
41
|
+
**Corollary (STOP, arXiv:2310.02304) — a trigger must resist gaming**. A trigger can be *reward-hacked*: it can pass without measuring what matters. When you write a rule (see `ops/rule.md`), ask one question. Does a diff exist that passes the trigger but breaks the rule's spirit? If yes, rewrite the rule, or move it down to § 1.3.
|
|
42
|
+
|
|
43
|
+
4. **A doc with `[TBD]` beats a doc with invention**. Bootstrap never guesses a user's answer. Refactor never infers persona, pain point, "why now", or the reasoning behind a decision from code alone. Code alone does not show that. A gap stays explicit as `[TBD]` until the user fills it in.
|
|
44
|
+
|
|
45
|
+
5. **Do not invent an entity, module, rule, or gotcha with no real case behind it**. Content grows only on demand. Refactor does not create an entity that is not in the schema. Init does not create a requirement "because every project needs one". Neither op creates a module or gotcha ahead of need.
|
|
46
|
+
|
|
47
|
+
6. **Autonomy-first: the agent applies changes inside the approved scope**. The human reviews the change. The human does not authorize every write. An approved scope is an op the user invoked, or a feature approved at the `deliver` gate. Running `afm plan` **is** the approval to produce the plan.
|
|
48
|
+
|
|
49
|
+
Inside that scope, the agent **materializes and reports**. It writes to `/docs/` and shows a summary plus the paths to review, through `git diff`. Invoking the op **is** the consent to produce the artifact. Review happens after, at a git checkpoint, not on every line.
|
|
50
|
+
|
|
51
|
+
**The DEGREE is a parameter, but the FORM and the bright lines stay fixed**. How much the agent decides alone comes from the current protocol (`RETRY_CAP`, `ROUND_CAP`, `SUPPRESS_SUBGATES`, `HALT_PER_PHASE`, `PLAN_THRESHOLD` — [`core/protocol.md`](core/protocol.md) § 2). Four things do not change: materialize-and-report as the form, the bright lines below, the load-bearing test, and the self-evolution gate. Under an assisted posture, the phrase "invoking the op **is** the approval" **does not apply**. The op keeps its own gate instead. That phrase used to be a side door: it let any assisted posture leak through, since not even `"go"` governed it.
|
|
52
|
+
|
|
53
|
+
**Bright lines — these ALWAYS stop and confirm first, even inside "approved scope":**
|
|
54
|
+
- (a) **a destructive or irreversible operation** — deleting or overwriting files (`export-template`), `rm`, a destructive migration, `git reset --hard`, force-overwrite. This applies even when a task in approved `tasks.md` calls for it — approved scope is not a license to destroy.
|
|
55
|
+
- (b) **an edit inside the canonical plugin** (the bundled content `afm path` resolves). This bright line does not stop and ask through `afm ask` — no path leads there at all. No AFM op writes to the plugin, not even with the user's approval in this session. A learning that generalizes gets **recorded** by `promote` (`afm findings record`, in the project state). The maintainer applies it, in the plugin's own repo — see #7.
|
|
56
|
+
- (c) **push** — never automatic (`afm.md § 6.1`).
|
|
57
|
+
- (d) **a mid-flight architectural surprise** (hard rule 11): a new first-class directory, layer, cross-module contract, or folder refactor. The agent must detect it in the **working tree**, not in a PR.
|
|
58
|
+
|
|
59
|
+
**Corollary (deliver)**. Under `plan=auto`, approval happens ONCE, at the checkpoint. The consolidated plan (the plan `afm approve` hashes, or a summary) **is** the proposal. Spec, plan, and tasks materialize together right after approval.
|
|
60
|
+
|
|
61
|
+
Under `plan=assisted`, the gate does not collapse — each op keeps its own gate. An explicit `Go` from the user is an **ephemeral override**: it forces `plan=auto` for this delivery only, without changing the project's protocol. It skips the **review gate**. It does **not** skip the bright lines above, or a CRITICAL (b) residue from verification. This matches the pattern `interview/refactor.md` already uses for the 5 bootstrap docs.
|
|
62
|
+
|
|
63
|
+
**Corollary (verification — the gate is the residue, not a ceremony)**. Autonomy-first means *produce → **self-verify** → report*, not *produce → report*. Before it delivers an artifact (discovery, spec, plan, tasks), the agent runs an **adversarial self-critique** on its own output. It runs a self-check: what is wrong, missing, contradicts §1-8, or is an unverifiable load-bearing guess? It then sorts each finding into 3 buckets:
|
|
64
|
+
- (a) **resolvable with evidence** (code, `/docs/`, the web) → the agent self-corrects and reports it in the summary. **This extends to bounded re-execution**. The agent retries only when the task gives a cheap re-runnable signal, such as a test or `tsc`. It conditions each retry on the stated failure. The cap is **2 retries plus anti-oscillation**: the same failure twice means stop and escalate. The agent then halts for the human gate — the in-task Reflexion loop (Reflexion arXiv:2303.11366 + Self-Refine arXiv:2303.17651), see `core/afm.md § 5.1`.
|
|
65
|
+
- (b) **load-bearing and not resolvable alone** → it becomes the gate question (raised through #8).
|
|
66
|
+
- (c) **not load-bearing and not resolvable** → it becomes `[TBD]`/`[NEEDS CLARIFICATION:]` for reconcile.
|
|
67
|
+
|
|
68
|
+
**The "load-bearing" test** picks what sorts into bucket (b). It is structural, not a "feeling of risk". A finding belongs in bucket (b) **only if** a wrong choice would change *which components, boundaries, or tasks get created*. That is the artifact's **structural inventory**.
|
|
69
|
+
|
|
70
|
+
A change might affect only **content** — a component or task that would exist anyway — or be cosmetic. Either case goes to bucket (a), which self-corrects, or to bucket (c) as `[TBD]`. It **never** to the gate.
|
|
71
|
+
|
|
72
|
+
**CRITICAL** means it changes the structural inventory of the *whole plan* — a new layer, module, or cross-module contract. **HIGH** means it changes the inventory of one isolated feature or task instead.
|
|
73
|
+
|
|
74
|
+
The **gate** for a delivery flow is not a process question ("do you want to review this?"). It is exactly bucket (b). With no bucket (b) residue and no CRITICAL, there is no gate, and the "go" path applies. This does not undo the bias fixed in #2. The question does not return because "asking is safer". It returns because verification **proved** it is irreducible and it changes structure.
|
|
75
|
+
|
|
76
|
+
7. **The plugin is the canonical source of the methodology. `<consumer>/docs/` is the materialized instance**. No content is duplicated. A methodology change is a PR here, in the plugin. A project-specific change is an edit in `/docs/` there. `<consumer>/docs/.afm-version` records which plugin version generated the instance.
|
|
77
|
+
|
|
78
|
+
**Corollary — who edits the plugin (an absolute boundary, bright line (b) of #6)**. The plugin **does not modify itself**. From inside an adopting project, AFM operates only on `<consumer>/docs/` and nothing else. A learning that generalizes gets **recorded** (`promote` → `afm findings record`), never applied.
|
|
79
|
+
|
|
80
|
+
The maintainer applies it, with the plugin's own repo open. *This is not only discipline.* The path an adopting session can reach (what `afm path <logical-id>` prints) resolves to the **installed package**. The next upgrade discards that copy, so writing there loses the work in silence.
|
|
81
|
+
|
|
82
|
+
8. **Structured questions go through `afm ask`, recommendation-first**. The agent asks only for the irreducible part left after #2. Every question that fits 2-4 options, including Yes/No/Adjust and `multiSelect` picks, is a question written as data in `questions/<op>.questions.yaml`, which each harness renders with its native picker (or a terminal prompt, or an answers file when headless). The first option is the recommendation, marked `(Recommended)`, with 1-2 sentences on why. An automatic "Other" option covers an unseen case — do not invent a "Free text" option.
|
|
83
|
+
|
|
84
|
+
**Use free text only for genuinely open questions**. Examples:
|
|
85
|
+
- describing a product, pain point, or persona
|
|
86
|
+
- listing entities, or describing a flow
|
|
87
|
+
- justifying an N/A
|
|
88
|
+
- capturing a free-form identifier, such as a US or feature name
|
|
89
|
+
- filling a descriptive field in a spec, plan, decision, or complexity doc
|
|
90
|
+
|
|
91
|
+
Items can exceed 4 — 16 rules, N ADRs, K gotchas, for example. Batch them into at most 4 `multiSelect` questions in the same call, with up to 4 items in each question. Combine independent questions in the same call, and keep a sequence only when one answer feeds the next. Cap questions inside a delivery flow at 2 rounds maximum. An unknown left over becomes `[NEEDS CLARIFICATION:]`, not another question.
|
|
92
|
+
|
|
93
|
+
**A gate question must be *earned***. Only what survives three filters reaches `afm ask`:
|
|
94
|
+
1. discover-first (#2) — not discoverable
|
|
95
|
+
2. self-critique (#6) — not self-resolvable
|
|
96
|
+
3. load-bearing (#6) — it changes the artifact's **structural inventory**: which components, boundaries, or tasks get created, not just their content
|
|
97
|
+
|
|
98
|
+
Every gate question carries three things, in the same call:
|
|
99
|
+
1. the **evidence** the agent already gathered
|
|
100
|
+
2. the **recommendation** (`(Recommended)` plus why)
|
|
101
|
+
3. **what changes structurally if the answer is wrong** — the consequence that makes it load-bearing
|
|
102
|
+
|
|
103
|
+
A question with no stated structural consequence is not a gate. It is `[TBD]`. The cap above applies as a whole. Discovery (#2) and verification (#6) share the same question budget: 4 per call, 2 rounds total across the flow.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Extra, refactor only (brownfield) — §9
|
|
108
|
+
|
|
109
|
+
9. **A retroactive ADR is load-bearing-only**. A decision inferred from code becomes an ADR **only if** changing or removing that decision today would break something visible. Take a dead decision — for example, a library adopted and never questioned, with no switching cost. It becomes a note in `ach.md`, not an ADR. This is what sets refactor apart from bootstrap, which **forbids** retroactive ADRs. Greenfield writes an ADR only for a real decision with a present symptom.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## How to reference this file
|
|
114
|
+
|
|
115
|
+
In other plugin docs, use:
|
|
116
|
+
|
|
117
|
+
```md
|
|
118
|
+
> Invariant principles: see [`PRINCIPLES.md`](caminho/relativo/PRINCIPLES.md). Universals §1-8 apply in init AND refactor. #9 (retroactive ADR) applies to refactor only.
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Do not copy the content. Link directly.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# README-light — quickstart
|
|
2
|
+
|
|
3
|
+
> Zero to a populated `docs/` in about 30 min (greenfield) or retroactive on an existing project (brownfield).
|
|
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
|
+
|
|
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
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Prerequisite (once per machine)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @tenkara/afm
|
|
15
|
+
afm --version
|
|
16
|
+
afm install <harness> # claude-code | opencode | agy | git
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The install wires the hooks and writes the skills in the spelling of your harness. The skills share one content tree. The entry points are `init` (greenfield bootstrap), `refactor` (brownfield adoption), `deliver` (autonomous end-to-end feature delivery) and `reconcile` (always-on passive mode).
|
|
20
|
+
|
|
21
|
+
It also has point skills: `gotcha`/`adr`/`rule`/`remediate`/`promote`/`specify`/`plan`/`tasks`/`clarify`/`analyze`/`export-template`.
|
|
22
|
+
|
|
23
|
+
`protocol` declares how much the agent decides alone. With no argument it reports the current posture. With an argument it materializes the preset and writes `protocol:` to `docs/_focus.md`.
|
|
24
|
+
|
|
25
|
+
This set includes the CRITIC loop `remediate`. It recognizes a failure from an external signal (`afm failures promotable`), then writes a procedure or a learning.
|
|
26
|
+
|
|
27
|
+
The set also includes the version sync `update`. It brings the instance to the current AFM version. This is the correct path for an instance that is already bootstrapped. `refactor` refuses a project with `.afm-version`.
|
|
28
|
+
|
|
29
|
+
Last, the set includes the self-evolution family for the **project's local documentation**. This is the built instance of the methodology in `docs/`, not AFM itself (`evolve` orchestrator plus the `diagnose`/`reflect`/`generalize`/`restructure` mechanisms). You do not need to copy anything into the project repo.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Path A — NEW project (greenfield)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd /path/to/empty-repo
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Open your harness there and run the `init` skill. With no harness, run `afm init --mechanical` and answer in the terminal.
|
|
40
|
+
|
|
41
|
+
The agent runs a **7-step interview**. Every confirmation or selection goes through `afm ask init` — you pick from the options in your harness's native picker, or in the terminal. Free text is only for genuinely open questions (describe the product, pain, or persona, list entities, describe a flow).
|
|
42
|
+
|
|
43
|
+
| Step | Question | Writes to |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| 0 | Product, pain, persona, success metric | `prd.md` §1, §2, §3, §6 |
|
|
46
|
+
| 1 | Tech stack (4 layers: web, API, DB+ORM, tasks) | `ach.md` §1, §2 + matching `modules/<stack>/` + opt-in `code-style/<stack\|_any>/` conventions offered item by item (accepted ones land in `ach.md`/`afm.md`; declined ones are never written) |
|
|
47
|
+
| 2 | 3-5 core entities + relation | `prd.md` §10, `ach.md` §1 |
|
|
48
|
+
| 3 | Main flow + error flow | `ust.md` US-001/US-002 + `prd.md` §4 (RFs) |
|
|
49
|
+
| 4 | Component-type-to-stack-tool mapping | `ach.md` §3.1 |
|
|
50
|
+
| 5 | Inherited rules (universals) + team rules | `afm.md` §3 |
|
|
51
|
+
| 6 | Validation rituals (DoD + pre-push) | `afm.md` §6, §6.1 |
|
|
52
|
+
| 7 | Gotchas/ADRs start empty | `gotchas/`, `adr/` |
|
|
53
|
+
|
|
54
|
+
At the end, the agent lists every open `[TBD]` item. You choose which ones to fill in now, and which to defer. Final structure:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
your-repo/
|
|
58
|
+
├── AGENTS.md # canonical instruction file (stubs for harnesses that need one)
|
|
59
|
+
└── docs/
|
|
60
|
+
├── .afm-version # AFM version in use
|
|
61
|
+
├── prd.md # ✅ product
|
|
62
|
+
├── ach.md # ✅ architecture of your stack
|
|
63
|
+
├── afm.md # ✅ hard rules + DoD + pre-push
|
|
64
|
+
├── ust.md # ✅ US-001 and US-002
|
|
65
|
+
├── gotchas/ # empty (discover, do not invent)
|
|
66
|
+
└── adr/
|
|
67
|
+
└── 0000-template.md # template for the next ADRs
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Commit, then continue.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Path B — EXISTING project (brownfield)
|
|
75
|
+
|
|
76
|
+
The codebase already has code, a manifest, and git history, but no docs in the AFM format.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd /path/to/existing-repo
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Open your harness there and run the `refactor` skill (or `afm refactor --mechanical` with no harness). The agent runs a 4-part flow:
|
|
83
|
+
|
|
84
|
+
- **Part A (autonomous, about 2-5 min):** code archaeology. It scans the stack from the manifest, the folder tree, and entities from the schema. It reads the README plus the git log, and audits the hard rules.
|
|
85
|
+
- **Part B:** writes draft PRD/ACH/AFM/UST/gotchas files with `[TBD]` in the gaps. Shows a single diff.
|
|
86
|
+
- **Part C (5 questions, `afm ask refactor`):** persona, pain, confirms the README summary, load-bearing-only retroactive ADRs, confirmed gotchas.
|
|
87
|
+
- **Part D:** writes `afm.md` §3.1 with forward-only rules based on the audit, creates `docs/.afm-version`, and updates the instruction files.
|
|
88
|
+
|
|
89
|
+
**Differences from greenfield:**
|
|
90
|
+
- Refactor **never guesses**: persona, pain, and intentional decisions stay `[TBD]` when the code does not reveal them.
|
|
91
|
+
- Refactor **allows retroactive ADRs**, with a guardrail: the decision must still be load-bearing today (invariant principle #9 — see `PRINCIPLES.md`).
|
|
92
|
+
- Inherited hard rules start **forward-only by default** (`afm.md` §3.1) — legacy code does not block them.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## After bootstrap — on-demand skills
|
|
97
|
+
|
|
98
|
+
In a bootstrapped project (`docs/.afm-version` exists), each op is its own skill. You invoke it directly, in the spelling of your harness.
|
|
99
|
+
|
|
100
|
+
**Need to deliver a feature? Use `deliver` — it is the end-to-end front door.** It scans the code and researches libraries through nasca. It asks you only what it cannot infer. It drafts a plan for one approval (`afm approve`), then executes task by task to the end. The `specify`/`plan`/`tasks` steps stay available on their own, to run one step in isolation.
|
|
101
|
+
|
|
102
|
+
| I want to... | Skill |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| **Deliver a feature end to end** | **`deliver <feature>`** |
|
|
105
|
+
| Open a complex feature (spec only) | `specify <slug>` |
|
|
106
|
+
| Plan a feature (after `specify`) | `plan` |
|
|
107
|
+
| Break a feature into TDD tasks (after `plan`) | `tasks` |
|
|
108
|
+
| Resolve ambiguities / `[NEEDS CLARIFICATION:]` | `clarify [<feature>]` |
|
|
109
|
+
| Run a read-only cross-artifact check | `analyze [<feature>]` |
|
|
110
|
+
| Research a technical unknown | the nasca research flow (`nasca-research`), not AFM |
|
|
111
|
+
| Log a surprise that blocked a dev twice | `gotcha` |
|
|
112
|
+
| Log a new architectural decision | `adr` |
|
|
113
|
+
| Adopt a new hard rule (with a mechanical trigger) | `rule` |
|
|
114
|
+
| Log a finding that applies to every AFM project (a finding, not an edit) | `promote` |
|
|
115
|
+
| Convert a project into an architectural template | `export-template` |
|
|
116
|
+
| Check the health of the docs (read only) | `diagnose` (or `afm doctor`) |
|
|
117
|
+
| Run the self-evolution cycle | `evolve` |
|
|
118
|
+
|
|
119
|
+
**When to open a feature folder (`specify`/`plan`/`tasks`) versus go straight to work?** The mechanical rule is in `core/afm.md § 2.1`. It applies to a feature over 1 day, over 200 lines, or over 3 files. It also applies to a new layer, a new component, a new external boundary, or more than 2 unknowns. Otherwise, the change goes straight to the task loop in `core/afm.md § 2`. `deliver` applies this rule on its own.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Passive mode (always on, no command needed)
|
|
124
|
+
|
|
125
|
+
In **any session** — even during normal code work — the `reconcile` skill watches for the signals in `interview/triggers.md`. Examples: a new architectural decision, a runtime surprise twice, a correction with a reusable rule. Other examples: a new component, or a scale change past a threshold. It **proposes an edit** to the matching `docs/` file at the end of the turn. You approve or decline it. It never applies on its own.
|
|
126
|
+
|
|
127
|
+
The single rule for deciding where something goes (invariant principle #1):
|
|
128
|
+
|
|
129
|
+
> *"If another developer — or another agent without my memory — needs to know this to avoid breaking things, it belongs in a doc, not in memory."*
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## No harness wired?
|
|
134
|
+
|
|
135
|
+
It still works from the terminal. `afm` owns the mechanical work (`afm preflight`, `afm gate`, `afm feature status`, `afm doctor`), `afm ask <op>` asks the questions in a prompt, and `afm install git` installs the git hooks that run the gate on every commit, with no AI. In a harness you have not wired, say in natural language:
|
|
136
|
+
|
|
137
|
+
> "Read the bootstrap interview (`afm path interview/bootstrap.md`) and run the 7-step interview with me."
|
|
138
|
+
|
|
139
|
+
Skills are UX sugar. All the knowledge lives in the content files (`interview/*`, `ops/*`, `core/*`). Invariant principle #7 — the content is the single canonical source.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Learn more
|
|
144
|
+
|
|
145
|
+
- `README.md` — full overview of the meta-framework plus its structure.
|
|
146
|
+
- `PRINCIPLES.md` — universal invariants (§1-8, the backbone is #2 discover-first plus #6 autonomy-first) plus the refactor addition (§9).
|
|
147
|
+
- `CHANGELOG.md` — what changed in each version.
|
|
148
|
+
- `hooks/README.md` — the shared hook contract.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Troubleshooting
|
|
153
|
+
|
|
154
|
+
**The agent invented something I did not say.** Say: "Remove X, I did not say that. Mark it `[TBD]`." (Invariant principles #4 and #5 — `[TBD]` beats invention.)
|
|
155
|
+
|
|
156
|
+
**The agent skipped an interview question.** Say: "Go back to step N — you did not ask me Y."
|
|
157
|
+
|
|
158
|
+
**A skill does not show up in my harness.** Run `afm install <harness>` again, then reopen the harness. `afm render --check` reports a generated file that drifted.
|
|
159
|
+
|
|
160
|
+
**I want to update to the new AFM version.** Run `afm self-update`, then the `update` skill. The CHANGELOG documents the changes between versions; `afm update` applies the consumer migrations and moves `docs/.afm-version` last.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# AFM content — the meta-framework
|
|
2
|
+
|
|
3
|
+
> Version: see [`VERSION`](./VERSION). History: [`CHANGELOG.md`](./CHANGELOG.md).
|
|
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
|
+
## What it is
|
|
8
|
+
|
|
9
|
+
`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.
|
|
10
|
+
|
|
11
|
+
**Difference from `docs/`:**
|
|
12
|
+
- `docs/` = the project's **instance**. It evolves in place. It holds the rules, ADRs, gotchas and stories of that specific project.
|
|
13
|
+
- `content/` = **meta** (generic, reusable). It does not name entities or names from any project. A new project copies from here (`afm init`) and starts at the same quality level from day 1.
|
|
14
|
+
|
|
15
|
+
## Invariant principles
|
|
16
|
+
|
|
17
|
+
Single canonical source: [`PRINCIPLES.md`](./PRINCIPLES.md). 8 universals (§1-8) apply everywhere. The backbone is #2 (discover-first) and #6 (autonomy-first). #9 (retroactive ADR, load-bearing) applies only to refactor. Do not duplicate content here: a direct link keeps the docs DRY.
|
|
18
|
+
|
|
19
|
+
## Structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
content/
|
|
23
|
+
├── VERSION CONSUMER_VERSION CHANGELOG.md README.md PRINCIPLES.md
|
|
24
|
+
├── core/ # universal, stack-agnostic seeds of docs/
|
|
25
|
+
│ ├── afm.md # hard rules + principles + DoD + flow
|
|
26
|
+
│ ├── ach.md prd.md ust.md gotchas.md
|
|
27
|
+
│ └── protocol.md # the autonomy presets P1-P3 (data, not a skill)
|
|
28
|
+
├── ops/ # canonical procedures: the judgment a skill exercises, calling the CLI
|
|
29
|
+
├── skills/ # thin skills, one per op: when to activate, then "follow the op"
|
|
30
|
+
├── roles/ # neutral sub-agent roles: explorer, executor, reviewer
|
|
31
|
+
├── questions/ # <op>.questions.yaml: every operator question, as data (`afm ask <op>`)
|
|
32
|
+
├── interview/ # scripts for init/refactor, and the triggers reconcile watches
|
|
33
|
+
├── rubrics/ # runnable decision tables
|
|
34
|
+
├── templates/ # doc templates, and the protocol presets (templates/protocols/)
|
|
35
|
+
├── guardrails/ # worked examples of a guardrail record
|
|
36
|
+
├── patterns/ # design patterns keyed by code smell: proposes, never imposes
|
|
37
|
+
├── code-style/ # house-style conventions, opt-in item by item at bootstrap
|
|
38
|
+
├── modules/ # opt-in per stack: facts about the stack, never house style
|
|
39
|
+
├── hooks/README.md # the contract of `afm hook <Event>`
|
|
40
|
+
└── tools/gate/ # the frozen 3.x bash gate: the baseline `afm migrate` compares a project's copy against
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`afm index --type <type>` lists every file of a family from its frontmatter, so the counts are never written here.
|
|
44
|
+
|
|
45
|
+
## How it reaches a project
|
|
46
|
+
|
|
47
|
+
An op is a Markdown procedure. A skill is the harness-facing entry that says when the op applies and tells the agent to follow it. Neither hard-codes a path or a tool of one harness:
|
|
48
|
+
|
|
49
|
+
- **Paths** are logical ids. `afm path ops/plan.md` prints the real location in the installed package.
|
|
50
|
+
- **Mechanical steps** are CLI calls (`afm doctor`, `afm gate`, `afm feature status`, `afm task done`). The op keeps only the judgment.
|
|
51
|
+
- **Questions** are data in `questions/<op>.questions.yaml`. `afm ask <op>` renders them natively in the harness, in a terminal prompt, or from an answers file when headless.
|
|
52
|
+
- **Plan approval** is `afm approve <feature>`: the sha256 of the plan is recorded, and a later edit invalidates it.
|
|
53
|
+
- **Sub-agents** are neutral roles (`explorer`, `executor`, `reviewer`). Config maps each role to a model; with no sub-agent support the work runs inline.
|
|
54
|
+
|
|
55
|
+
`afm render` generates the per-harness skill and agent files from `skills/` and `roles/`. Project and session state never goes into the repository: it lives under `AFM_HOME` (default `~/.afm`). The consumer keeps only `docs/` and its markers, such as `docs/.afm-version`.
|
|
56
|
+
|
|
57
|
+
**When a rule or gotcha emerges:** the agent detects it from `interview/triggers.md` and proposes an edit in `docs/`. The user approves.
|
|
58
|
+
|
|
59
|
+
**When a learning generalizes:** the agent proposes, through `interview/promotion.md`, that it become a patch to this content. That is a change to AFM itself, made in its own repository: the version bumps, and the changelog gets an entry.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## How to use it in a NEW project (greenfield)
|
|
64
|
+
|
|
65
|
+
1. Install AFM (`npm install -g @tenkara/afm`), then wire your harness with `afm install <harness>`.
|
|
66
|
+
2. In the new project, run the `init` skill (or ask "set up the project docs"). `afm init --mechanical` does the mechanical part: docs from content, measured rule constants, and the instruction files.
|
|
67
|
+
3. The agent runs the 7-step interview from `interview/bootstrap.md`. Every question comes from `questions/init.questions.yaml`.
|
|
68
|
+
4. In about 30 minutes, `docs/prd.md`, `ach.md`, `afm.md`, `ust.md` and `gotchas/` hold the chosen stack and the applicable opt-in modules. `docs/.afm-version` records the AFM version.
|
|
69
|
+
5. **To deliver a feature, the default path is `afm deliver <feature>`.** It orchestrates discovery, then one approval, then task-by-task execution to completion. À la carte, run one isolated step when the feature meets the criteria in `core/afm.md` § 2.1 (more than 1 day, a new layer, a new external boundary, or more than 2 unknowns): `afm specify <slug>`, `afm plan`, `afm tasks`. A small change goes straight to the task loop in § 2.
|
|
70
|
+
6. **Auxiliaries, used as needed:** `afm clarify [<feature>]` runs a structured ambiguity scan, `afm analyze [<feature>]` runs cross-artifact validation before T001. External technical unknowns go to nasca, never to AFM: 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.
|
|
71
|
+
|
|
72
|
+
**Instruction files.** `AGENTS.md` is the canonical, harness-neutral file: the doc map and the doctrine sit between the `afm:begin` and `afm:end` markers, which `afm init` manages. A harness that does not read `AGENTS.md` itself gets a generated stub (`CLAUDE.md`, `GEMINI.md`) that only imports it. **Never duplicate a rule there:** the rules live in `docs/afm.md` § 3, and the instruction files only point to them. A stub without the generated marker belongs to the operator and is never overwritten. If the repo already has an `AGENTS.md`, `afm init` adds the managed block and leaves the rest.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## How to use it in an EXISTING project (brownfield)
|
|
77
|
+
|
|
78
|
+
The codebase already has relevant code: a populated source tree, a manifest with real dependencies, and git history. It has no docs in the AFM pattern yet.
|
|
79
|
+
|
|
80
|
+
1. Install AFM (same as greenfield).
|
|
81
|
+
2. In the project, run the `refactor` skill (or ask "adopt AFM here"). `afm refactor --mechanical` runs the stack scan and the rule audit.
|
|
82
|
+
3. The agent runs a 4-part flow (`interview/refactor.md`):
|
|
83
|
+
- **Part A** — autonomous code archaeology, with no turns needed: stack from the manifest, the folder tree, entities from the schema, the README and git log, and an audit of the hard rules against the current code.
|
|
84
|
+
- **Part B** — materializes drafts of the 5 docs with `[TBD]` in the gaps, and presents a single diff.
|
|
85
|
+
- **Part C** — a short interview, 5 questions, one per turn (`questions/refactor.questions.yaml`): persona, pain point, README summary validation, load-bearing retroactive ADRs, confirmed gotchas.
|
|
86
|
+
- **Part D** — writes `afm.md` § 3.1 with forward-only rules based on the audit, creates `docs/.afm-version`, and updates the instruction files.
|
|
87
|
+
|
|
88
|
+
**Key difference from greenfield:**
|
|
89
|
+
- Refactor **never guesses**: persona, pain point and intentional decisions stay `[TBD]` when the code does not reveal them.
|
|
90
|
+
- Refactor **allows retroactive ADRs**, with a load-bearing guardrail: the decision must still be load-bearing today.
|
|
91
|
+
- Inherited hard rules (TDD, zero `any`) apply **forward-only by default**: to new code plus boy-scout cleanup, never blocking on legacy code.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## How to use it with an architectural template (accelerated greenfield)
|
|
96
|
+
|
|
97
|
+
Scenario: you maintain a template repository (a starter with a ready stack, base code and inherited rules). You want a new project focused only on product, so the stack, data, mapping and rules steps are skipped.
|
|
98
|
+
|
|
99
|
+
### Creating the template (once per template)
|
|
100
|
+
|
|
101
|
+
1. In a well-bootstrapped project that will become a template, run `afm template export --dry-run`. It shows the full diff first, because deleting files is a destructive bright line (principle #6).
|
|
102
|
+
2. Review the diff: it keeps `ach.md`, `afm.md`, `gotchas/` and `adr/`, deletes the product files (`prd.md`, `ust.md`, `docs/features/`, `docs/.afm-version`), and writes the `docs/.template` marker. Then apply with `afm template export --yes`.
|
|
103
|
+
3. Package the repo as a starter (degit, tiged, git template, or a manual clone).
|
|
104
|
+
|
|
105
|
+
### Using the template in a new project
|
|
106
|
+
|
|
107
|
+
1. Clone the template into the new repo (empty, or with only `git init`).
|
|
108
|
+
2. Run the `init` skill. Pre-check 2 detects `docs/.template`, and `afm ask init` confirms the branch-from-template path.
|
|
109
|
+
3. The agent loads the inherited `ach.md`/`afm.md`/`gotchas/` read-only and runs **only** four steps: product, pain point, persona and metric (step 0); critical flows and the US (step 3); does the inherited DoD still hold (step 6); do the gotchas still hold (step 7).
|
|
110
|
+
4. In about 10 minutes `prd.md` and `ust.md` exist, and the inherited docs stay intact. `.afm-version` records the inheritance in its footer: `Inherited from template "<name>" v<version> (exported with afm v<X>)`.
|
|
111
|
+
5. `AGENTS.md` gets the **Origin** line.
|
|
112
|
+
|
|
113
|
+
**When does it make sense?** The team maintains a consolidated starter, and new projects differ in product but not in stack, rules or gotchas. It cuts interview turns from 7 to about 3.
|
|
114
|
+
|
|
115
|
+
**Drift between versions.** The skill trusts the inherited docs completely. New rules in `core/afm.md` do not propagate into the inherited `afm.md` by themselves: update the template, and re-export it, periodically. `afm update` moves a bootstrapped instance to a newer AFM version.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Versioning
|
|
120
|
+
|
|
121
|
+
[SemVer](https://semver.org/):
|
|
122
|
+
|
|
123
|
+
- **Patch** — new gotcha, example, counter-example, refinement.
|
|
124
|
+
- **Minor** — new hard rule, new rubric, new module.
|
|
125
|
+
- **Major** — breaking change to the bootstrap flow, incompatible change in `core/`.
|
|
126
|
+
|
|
127
|
+
Every change is documented in [`CHANGELOG.md`](./CHANGELOG.md). An instance moves between versions with `afm update`, which applies the changelog's consumer migrations and moves the pin last. A 3.x instance moves to 4.0 with `afm migrate`.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## How to contribute (from the instance project back to the template)
|
|
132
|
+
|
|
133
|
+
A learning in `docs/` that applies to any project can move up to the template:
|
|
134
|
+
|
|
135
|
+
1. The agent detects a candidate via `interview/promotion.md` and asks the user.
|
|
136
|
+
2. The user approves. A change to this content is made in the AFM repository: edit the file, bump `VERSION`, add a `CHANGELOG.md` entry, and commit.
|
|
137
|
+
|
|
138
|
+
Criteria for "applies to any project": see `interview/promotion.md` § "Criteria".
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Distribution across projects
|
|
143
|
+
|
|
144
|
+
AFM is distributed on npm as `@tenkara/afm`: a small launcher plus one compiled binary per platform, so the end user needs no runtime. Each consumer records the version in use in `docs/.afm-version`, and `afm self-update` reads the registry.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Philosophy
|
|
149
|
+
|
|
150
|
+
> "Every new project should start wiser than the last one — without the team needing to remember everything it learned."
|
|
151
|
+
|
|
152
|
+
The template exists to capture durable learning **outside people's heads and outside the agent's memory**. It lives in versioned, auditable, transferable files.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: code-style
|
|
3
|
+
description: 'Decides whether a file-length ceiling exists at all, and how its value gets set.'
|
|
4
|
+
load: cold
|
|
5
|
+
concern: file-size
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Code style — File size
|
|
9
|
+
|
|
10
|
+
## The decision
|
|
11
|
+
|
|
12
|
+
Two separate questions hide inside "how big can a file get": whether a ceiling is enforced
|
|
13
|
+
mechanically at all, and — only if the answer is yes — what number it is set to. Answer them in
|
|
14
|
+
that order. The second question has no honest default; see Measurement below before proposing any
|
|
15
|
+
number.
|
|
16
|
+
|
|
17
|
+
## Option A — A mechanical ceiling (a hard rule with a `wc -l` trigger)
|
|
18
|
+
|
|
19
|
+
A gate fails the merge when a source file crosses the line.
|
|
20
|
+
|
|
21
|
+
- **For:** it has teeth. A file that would have grown past the point of being one responsibility
|
|
22
|
+
gets caught the day it crosses the line, not months later when splitting it means untangling a
|
|
23
|
+
thousand lines of accumulated cross-references.
|
|
24
|
+
- **Against:** a single ceiling does not fit every file shape. A barrel/index file, a generated
|
|
25
|
+
file, a large enum, or a table of fixtures can legitimately be long without being unreadable —
|
|
26
|
+
and a rigid ceiling turns those into constant, noisy exceptions instead of catching the files
|
|
27
|
+
the rule is actually meant for.
|
|
28
|
+
|
|
29
|
+
## Option B — A guideline enforced at review, not by a gate
|
|
30
|
+
|
|
31
|
+
The number is a shared expectation, checked by a human at PR time, with no mechanical trigger.
|
|
32
|
+
|
|
33
|
+
- **For:** no false positive ever blocks an unrelated diff. A reviewer applies judgment — the
|
|
34
|
+
fixture table and the ballooning god-function get different treatment even though both are
|
|
35
|
+
long.
|
|
36
|
+
- **Against:** a rule with no trigger erodes. The one file that crossed the line "just this once"
|
|
37
|
+
sets the precedent for the next one, and six months later the guideline describes nothing that
|
|
38
|
+
is actually true of the codebase.
|
|
39
|
+
|
|
40
|
+
## Measurement — never a default disguised as best practice
|
|
41
|
+
|
|
42
|
+
**Do not propose a round number ("300 lines", "80 lines") without measuring this codebase first.**
|
|
43
|
+
A ceiling picked from habit or from a blog post is invention, and a rule whose constant the
|
|
44
|
+
operator did not choose is a rule the operator turns off at first friction. The template's own
|
|
45
|
+
placeholder for this value is `{{limite-linhas}}` precisely because the number belongs to the
|
|
46
|
+
operator, not the framework.
|
|
47
|
+
|
|
48
|
+
The measurement procedure — file-size distribution, p90-based proposal, greenfield fallback, and
|
|
49
|
+
what to do when the operator does not answer — already exists and is not repeated here (hard rule
|
|
50
|
+
34: a procedure lives in one place). Follow "Rule constants — measure first, then propose, never
|
|
51
|
+
assume" in `interview/bootstrap.md`. That section also covers the companion constant
|
|
52
|
+
`{{prefixo-dominio}}`, measured the same way.
|
|
53
|
+
|
|
54
|
+
## Consequence of mixing both
|
|
55
|
+
|
|
56
|
+
The riskiest state is not "no ceiling" or "a measured ceiling" — it is a ceiling that was invented
|
|
57
|
+
rather than measured, sitting silently among files that were already past it before the rule
|
|
58
|
+
existed. A hardcoded "all files are under 80 lines" with no measurement behind it and no
|
|
59
|
+
placeholder to fill in is not a convention; it is a number nobody chose, applied to a codebase
|
|
60
|
+
nobody checked it against. The first consequence is a rule that immediately fails on the file that
|
|
61
|
+
was already 120 lines the day the rule landed — and a failing rule that nobody asked for is the
|
|
62
|
+
one that gets silenced first, taking the legitimate cases down with it.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: code-style
|
|
3
|
+
description: 'Decides how a layer-direction rule (what may import what) gets declared and enforced.'
|
|
4
|
+
load: cold
|
|
5
|
+
concern: imports
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Code style — Import direction
|
|
9
|
+
|
|
10
|
+
## The decision
|
|
11
|
+
|
|
12
|
+
Most codebases with layers already have an intended direction — domain code should not reach into
|
|
13
|
+
transport, a publishable `lib/` should not reach into app-internal generated code, a UI layer
|
|
14
|
+
should not reach past its server client into a raw database driver. The decision is not whether
|
|
15
|
+
such a direction exists (it almost always does, at least informally) — it is **how it gets
|
|
16
|
+
enforced**, and stated as a decision about the mechanism, not as one project's specific folder
|
|
17
|
+
tree.
|
|
18
|
+
|
|
19
|
+
## Option A — One grep-based hard rule per boundary
|
|
20
|
+
|
|
21
|
+
Each forbidden crossing gets its own trigger: `grep -rn "<forbidden identifier>" <layer path>`
|
|
22
|
+
must return zero results.
|
|
23
|
+
|
|
24
|
+
- **For:** immediate and mechanical. Each rule is small, readable in isolation, and needs no new
|
|
25
|
+
tooling — it runs in the same pre-commit gate everything else does.
|
|
26
|
+
- **Against:** the boundary set is only as complete as the list of rules someone remembered to
|
|
27
|
+
write. A new layer, or a new pair of layers that should not talk, needs a new grep by hand — and
|
|
28
|
+
a grep only catches the literal identifier crossing the boundary directly. A re-export through a
|
|
29
|
+
barrel file (`export * from "../transport"`) can carry the same violation through a name the
|
|
30
|
+
grep never matches.
|
|
31
|
+
|
|
32
|
+
## Option B — A declared dependency graph, checked by a tool
|
|
33
|
+
|
|
34
|
+
The allowed direction between layers is declared once, as data (a layer graph), and a tool derives
|
|
35
|
+
every pairwise check from it — for example a dependency-boundary linter driven by a config file
|
|
36
|
+
instead of hand-written greps.
|
|
37
|
+
|
|
38
|
+
- **For:** one place declares the whole graph, so adding a layer means adding one node instead of
|
|
39
|
+
writing N new greps. A graph-aware tool also resolves re-exports and transitive imports that a
|
|
40
|
+
literal grep misses.
|
|
41
|
+
- **Against:** it is a new dependency, a new config file, and a new step in the build a small
|
|
42
|
+
project may not want to carry. The graph is also now a second description of the architecture,
|
|
43
|
+
separate from the folder structure that already implies it — and a second description is a
|
|
44
|
+
second thing that can go stale relative to the first (the same drift risk a naming prefix has
|
|
45
|
+
relative to its file's real location).
|
|
46
|
+
|
|
47
|
+
## How to measure what this codebase already does
|
|
48
|
+
|
|
49
|
+
Before proposing a direction, check whether it already holds — or already doesn't:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
# how many places does the domain layer already import the transport/framework layer directly?
|
|
53
|
+
grep -rln "TRPCError\|NextRequest\|express" src/**/domain/ 2>/dev/null | wc -l
|
|
54
|
+
# how many places does a publishable lib already reach into app-internal generated code?
|
|
55
|
+
grep -rln "from ['\"]\.\./\.\./generated" src/lib/ 2>/dev/null | wc -l
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Adapt the identifiers to the stack in use. A nonzero count is not necessarily a blocker — it is
|
|
59
|
+
the starting debt the operator is choosing to accept, freeze, or pay down before the rule goes in.
|
|
60
|
+
|
|
61
|
+
## Consequence of mixing both
|
|
62
|
+
|
|
63
|
+
Enforcing some boundaries with a grep and leaving others undeclared does not average out to
|
|
64
|
+
"partially enforced" — it produces exactly one unguarded seam, and coupling accumulates precisely
|
|
65
|
+
there, because it is the one crossing nobody wrote a check for. The architecture diagram keeps
|
|
66
|
+
describing a clean direction while the one boundary with no rule quietly fills with the imports
|
|
67
|
+
that were supposed to be impossible. The fix is not more greps after the fact; it is deciding, per
|
|
68
|
+
boundary, which mechanism (A or B) covers it before the first violation lands.
|