@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,14 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: status
|
|
3
|
+
prompt: What is the status of this decision?
|
|
4
|
+
header: Status
|
|
5
|
+
recommended: Accepted
|
|
6
|
+
options:
|
|
7
|
+
- label: Proposed
|
|
8
|
+
description: Written down, not yet in force. Pass it as --status proposed.
|
|
9
|
+
- label: Accepted
|
|
10
|
+
description: In force today. Pass it as --status accepted.
|
|
11
|
+
- label: Superseded by ADR-NNNN
|
|
12
|
+
description: A later decision replaced it; write the new ADR with --supersedes N.
|
|
13
|
+
- label: Deprecated
|
|
14
|
+
description: No longer in force and nothing replaced it. Pass it as --status deprecated.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: remediation
|
|
3
|
+
prompt: Do you want concrete edits for the top findings?
|
|
4
|
+
header: Remediation
|
|
5
|
+
recommended: top-5
|
|
6
|
+
options:
|
|
7
|
+
- label: top-5
|
|
8
|
+
description: Apply the edits for the top 5 findings in severity order, then report what changed and where.
|
|
9
|
+
- label: top-10
|
|
10
|
+
description: Same as top-5, for the top 10 findings.
|
|
11
|
+
- label: report-only
|
|
12
|
+
description: The report is enough. Nothing is edited and the findings are addressed manually.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: mapping
|
|
3
|
+
prompt: Does the component-type to stack mapping drafted for the architecture doc make sense?
|
|
4
|
+
header: Mapping
|
|
5
|
+
recommended: All match
|
|
6
|
+
options:
|
|
7
|
+
- label: All match
|
|
8
|
+
description: Materializes the mapping as drafted.
|
|
9
|
+
- label: Adjust
|
|
10
|
+
description: One or two entries change; the operator points them out.
|
|
11
|
+
- label: Some do not apply
|
|
12
|
+
description: The operator lists the component types the project does not have.
|
|
13
|
+
- label: Rewrite
|
|
14
|
+
description: The operator dictates the mapping again.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: rules
|
|
3
|
+
prompt: Does any inherited hard rule not fit this project? Inalienable rules are never offered.
|
|
4
|
+
header: Rules
|
|
5
|
+
recommended: Keep all
|
|
6
|
+
options:
|
|
7
|
+
- label: Keep all
|
|
8
|
+
description: Every opt-out-able rule stays in force.
|
|
9
|
+
- label: Opt out of some
|
|
10
|
+
description: The operator names each rule and why; each becomes N/A with that reason.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: stack
|
|
3
|
+
prompt: Is the stack that afm init reported, layer by layer with its evidence, right?
|
|
4
|
+
header: Stack
|
|
5
|
+
recommended: Confirm
|
|
6
|
+
options:
|
|
7
|
+
- label: Confirm
|
|
8
|
+
description: Records every reported layer as decided.
|
|
9
|
+
- label: Adjust
|
|
10
|
+
description: Some layers are wrong or missing; the operator names them and the answer is recorded as given.
|
|
11
|
+
- label: Leave as TBD
|
|
12
|
+
description: Records [TBD] for the layers; a recommendation works better once the operator also knows what they do not want.
|
|
13
|
+
- id: modules
|
|
14
|
+
prompt: Apply every opt-in module detected for the stack? A module is applied whole, so the default is to opt out only what does not fit.
|
|
15
|
+
header: Modules
|
|
16
|
+
recommended: All
|
|
17
|
+
options:
|
|
18
|
+
- label: All
|
|
19
|
+
description: Merges each detected module's architecture and rule patches.
|
|
20
|
+
- label: Some
|
|
21
|
+
description: Applies all but the modules the operator names; those simply stay out.
|
|
22
|
+
- label: None
|
|
23
|
+
description: No module is applied.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: underspecified
|
|
3
|
+
prompt: Most categories are Missing and many markers are open. How should clarify proceed?
|
|
4
|
+
header: Thin spec
|
|
5
|
+
recommended: respecify
|
|
6
|
+
options:
|
|
7
|
+
- label: respecify
|
|
8
|
+
description: Re-run specify with new input. A spec this thin needs rewriting, not a long question loop.
|
|
9
|
+
- label: continue
|
|
10
|
+
description: Keep clarifying anyway, within the limit of 5 questions for this session.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: code-style
|
|
3
|
+
prompt: The listed code-style files are house conventions one project observed, not facts of the stack. Apply any? An unmarked item is written nowhere.
|
|
4
|
+
header: Code style
|
|
5
|
+
recommended: None
|
|
6
|
+
options:
|
|
7
|
+
- label: None
|
|
8
|
+
description: Nothing applies. The default, because a silent opt-in is the defect this question corrects.
|
|
9
|
+
- label: Some
|
|
10
|
+
description: The operator names the files; each is copied verbatim as the project's rule.
|
|
11
|
+
- label: All
|
|
12
|
+
description: Every listed file is copied verbatim as the project's rule.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: restated
|
|
3
|
+
prompt: Is the restatement above correct?
|
|
4
|
+
header: Confirmation
|
|
5
|
+
recommended: Yes, exact
|
|
6
|
+
options:
|
|
7
|
+
- label: Yes, exact
|
|
8
|
+
description: Materializes it as restated.
|
|
9
|
+
- label: Almost
|
|
10
|
+
description: A small adjustment; the operator describes the fix.
|
|
11
|
+
- label: No, rewrite
|
|
12
|
+
description: The operator dictates it again.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: outcome
|
|
3
|
+
prompt: The plan is drafted and verified. What should the delivery do now?
|
|
4
|
+
header: Outcome
|
|
5
|
+
recommended: run-to-completion
|
|
6
|
+
options:
|
|
7
|
+
- label: run-to-completion
|
|
8
|
+
description: Approve the plan and execute every task, stopping only at a halt or the push boundary.
|
|
9
|
+
- label: pause-per-phase
|
|
10
|
+
description: Approve the plan, execute it, and stop after each phase to ask whether to continue.
|
|
11
|
+
- label: materialize-only
|
|
12
|
+
description: Keep the drafted spec, plan and tasks on disk and execute nothing.
|
|
13
|
+
- label: adjust-or-cancel
|
|
14
|
+
description: Record no approval. Say what to change in the drafts, or stop here.
|
|
15
|
+
- id: phase-continue
|
|
16
|
+
prompt: The phase is done. Continue to the next phase?
|
|
17
|
+
header: Next phase
|
|
18
|
+
recommended: continue
|
|
19
|
+
options:
|
|
20
|
+
- label: continue
|
|
21
|
+
description: Run the next phase.
|
|
22
|
+
- label: stop
|
|
23
|
+
description: Stop here; re-running deliver resumes at the first open task.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# One question per (b) item of the evolve package. Run it once per item:
|
|
2
|
+
# afm ask evolve --scope <item-slug> --recommend <label>
|
|
3
|
+
# The item's evidence, its recommendation and "what changes if this is wrong" sit in the package the
|
|
4
|
+
# agent shows before asking; the answer applies to that one item only.
|
|
5
|
+
questions:
|
|
6
|
+
- id: apply
|
|
7
|
+
prompt: Apply this proposed change to the docs?
|
|
8
|
+
header: Apply
|
|
9
|
+
options:
|
|
10
|
+
- label: Apply
|
|
11
|
+
description: Apply the change after the gate, exactly as itemized in the package.
|
|
12
|
+
- label: Skip
|
|
13
|
+
description: Reject it; the report records the rejection as attempt memory, so it is not proposed again without new evidence.
|
|
14
|
+
- label: Stage
|
|
15
|
+
description: Defer it to the next cycle; the report records it as staged.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: apply
|
|
3
|
+
prompt: Delete the listed files and write the template marker?
|
|
4
|
+
header: Apply
|
|
5
|
+
options:
|
|
6
|
+
- label: Apply
|
|
7
|
+
description: Runs the same command with --yes. The deletion is not reversible outside git.
|
|
8
|
+
- label: Adjust
|
|
9
|
+
description: Go back to the keep question and review the plan again.
|
|
10
|
+
- label: Cancel
|
|
11
|
+
description: Nothing is touched.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: keep
|
|
3
|
+
prompt: Which of the artifacts a template normally drops should STAY? Leave empty to keep none.
|
|
4
|
+
header: Keep
|
|
5
|
+
multiSelect: true
|
|
6
|
+
options:
|
|
7
|
+
- label: prd
|
|
8
|
+
description: prd.md is product-specific; a template usually drops it.
|
|
9
|
+
- label: ust
|
|
10
|
+
description: ust.md holds the product's stories; a template usually drops it.
|
|
11
|
+
- label: features
|
|
12
|
+
description: docs/features/ is product work; its tasks are first induced into a reusable shape.
|
|
13
|
+
- label: afm-version
|
|
14
|
+
description: A template is not an instance, so the version pin is dropped unless kept.
|
|
15
|
+
- id: research
|
|
16
|
+
prompt: What happens to docs/research/, which may hold reusable technical research?
|
|
17
|
+
header: Research
|
|
18
|
+
recommended: Keep
|
|
19
|
+
options:
|
|
20
|
+
- label: Keep
|
|
21
|
+
description: The research stays in the template.
|
|
22
|
+
- label: Delete
|
|
23
|
+
description: The research goes with the product content.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: dod
|
|
3
|
+
prompt: Which checks must pass to merge? Pre-check the ones the scan reported as gating merge.
|
|
4
|
+
header: Merge DoD
|
|
5
|
+
multiSelect: true
|
|
6
|
+
options:
|
|
7
|
+
- label: Test runner
|
|
8
|
+
description: The project's tests.
|
|
9
|
+
- label: Type check
|
|
10
|
+
description: The type checker with no emit.
|
|
11
|
+
- label: Lint
|
|
12
|
+
description: The linter or formatter check.
|
|
13
|
+
- label: Build
|
|
14
|
+
description: A production build.
|
|
15
|
+
- id: pre-push
|
|
16
|
+
prompt: Which checks run before a push? Pre-check the ones the scan reported in a pre-push hook.
|
|
17
|
+
header: Pre-push
|
|
18
|
+
multiSelect: true
|
|
19
|
+
options:
|
|
20
|
+
- label: Test runner
|
|
21
|
+
description: The project's tests.
|
|
22
|
+
- label: Type check
|
|
23
|
+
description: The type checker with no emit.
|
|
24
|
+
- label: Lint
|
|
25
|
+
description: The linter or formatter check.
|
|
26
|
+
- label: Build
|
|
27
|
+
description: A production build.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# One question per merge of gotchas into an abstract rule:
|
|
2
|
+
# afm ask generalize --scope <rule-slug>
|
|
3
|
+
questions:
|
|
4
|
+
- id: merge
|
|
5
|
+
prompt: Merge the batch of gotchas into the proposed rule and archive the members with tombstones?
|
|
6
|
+
header: Merge
|
|
7
|
+
options:
|
|
8
|
+
- label: Merge as a rule
|
|
9
|
+
description: Write a hard rule in afm.md section 3 with its 0/1 trigger, then archive the merged gotchas with tombstones.
|
|
10
|
+
- label: Merge as a principle
|
|
11
|
+
description: Write the abstraction in afm.md section 1.3 (guidance only, no executable trigger), then archive the merged gotchas with tombstones.
|
|
12
|
+
- label: Keep separate
|
|
13
|
+
description: The abstraction loses too much; keep the gotchas as they are and report "not generalizable without loss".
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: basis
|
|
3
|
+
prompt: Does this behavior qualify for registration?
|
|
4
|
+
header: Qualify
|
|
5
|
+
options:
|
|
6
|
+
- label: bitten-twice
|
|
7
|
+
description: Confirmed to have bitten a developer at least twice.
|
|
8
|
+
- label: documented-sdk
|
|
9
|
+
description: Documented behavior of a known external SDK or runtime that surprises its users.
|
|
10
|
+
- label: neither
|
|
11
|
+
description: No second incidence and no external documentation; nothing is registered.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: branch
|
|
3
|
+
prompt: This project comes from an architectural template (docs/.template). How should the interview run?
|
|
4
|
+
header: Interview
|
|
5
|
+
recommended: Product only
|
|
6
|
+
options:
|
|
7
|
+
- label: Product only
|
|
8
|
+
description: Runs only product, flows, a short validation step and gotchas. Stack, data model, mapping and rules are inherited.
|
|
9
|
+
- label: Full interview
|
|
10
|
+
description: Ignores the marker for this session and runs all seven steps. The marker stays on disk.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: harnesses
|
|
3
|
+
prompt: Which harnesses should the instruction files of this project cover?
|
|
4
|
+
header: Harnesses
|
|
5
|
+
multiSelect: true
|
|
6
|
+
recommended: [claude-code]
|
|
7
|
+
options:
|
|
8
|
+
- label: claude-code
|
|
9
|
+
description: Writes a CLAUDE.md stub that imports AGENTS.md.
|
|
10
|
+
- label: opencode
|
|
11
|
+
description: Reads AGENTS.md itself, so no stub is written.
|
|
12
|
+
- label: agy
|
|
13
|
+
description: Writes a GEMINI.md stub that imports AGENTS.md.
|
|
14
|
+
- label: git
|
|
15
|
+
description: Git hooks only; no instruction file is needed.
|
|
16
|
+
- id: app-language
|
|
17
|
+
prompt: In which language does this product show its own users their strings?
|
|
18
|
+
header: App language
|
|
19
|
+
recommended: Decide later
|
|
20
|
+
options:
|
|
21
|
+
- label: English
|
|
22
|
+
description: User-facing strings are in English.
|
|
23
|
+
- label: Portuguese
|
|
24
|
+
description: User-facing strings are in Portuguese.
|
|
25
|
+
- label: Spanish
|
|
26
|
+
description: User-facing strings are in Spanish.
|
|
27
|
+
- label: Decide later
|
|
28
|
+
description: Records [TBD] in the PRD; the language migration stops and asks.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: open-markers
|
|
3
|
+
prompt: The spec has open NEEDS CLARIFICATION markers. How should the plan proceed?
|
|
4
|
+
header: Markers
|
|
5
|
+
recommended: clarify-first
|
|
6
|
+
options:
|
|
7
|
+
- label: clarify-first
|
|
8
|
+
description: Run the structured clarify scan first. It records dated answers in the spec, then planning resumes.
|
|
9
|
+
- label: resolve-inline
|
|
10
|
+
description: Quick fallback. Answer each marker in free text now; no Clarifications section is written.
|
|
11
|
+
- label: keep-going
|
|
12
|
+
description: Not recommended. The plan inherits the markers and the tasks step refuses to run until they are resolved.
|
|
13
|
+
- label: cancel
|
|
14
|
+
description: Go back to the spec and plan nothing yet.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: adr
|
|
3
|
+
prompt: Which of the inferred decisions still load-bear today and become a retroactive ADR? Would someone need a doc to explain why if it were swapped tomorrow?
|
|
4
|
+
header: ADRs
|
|
5
|
+
recommended: None
|
|
6
|
+
options:
|
|
7
|
+
- label: None
|
|
8
|
+
description: No retroactive ADR; a dead decision never becomes one later.
|
|
9
|
+
- label: Some
|
|
10
|
+
description: The operator names the decisions; each becomes an accepted retroactive ADR.
|
|
11
|
+
- label: All
|
|
12
|
+
description: Every listed candidate becomes an accepted retroactive ADR.
|
|
13
|
+
- id: gotcha-seeds
|
|
14
|
+
prompt: Which gotcha seeds of the detected stacks has the team here already been bitten by? Seeds are candidates, not active entries.
|
|
15
|
+
header: Gotchas
|
|
16
|
+
recommended: None
|
|
17
|
+
options:
|
|
18
|
+
- label: None
|
|
19
|
+
description: No seed is activated.
|
|
20
|
+
- label: Some
|
|
21
|
+
description: The operator names the seeds; each becomes its own gotcha file.
|
|
22
|
+
- label: All
|
|
23
|
+
description: Every seed is confirmed as already lived here and becomes its own gotcha file.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# One question per refinement of a doc that guided badly in the session:
|
|
2
|
+
# afm ask reflect --scope <item-slug>
|
|
3
|
+
questions:
|
|
4
|
+
- id: refinement
|
|
5
|
+
prompt: Refine this doc as proposed?
|
|
6
|
+
header: Refinement
|
|
7
|
+
options:
|
|
8
|
+
- label: Apply
|
|
9
|
+
description: Apply the refinement (rewrite, added trigger, or disambiguation) exactly as itemized.
|
|
10
|
+
- label: Report only
|
|
11
|
+
description: Do not edit the doc; keep the finding as a suggestion in the report.
|
|
12
|
+
- label: Skip
|
|
13
|
+
description: Reject it; the report records the rejection so the finding is not proposed again without new evidence.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# One pair of questions per recurring failure (the scope is the sig= as a slug):
|
|
2
|
+
# afm ask remediate --scope <sig>
|
|
3
|
+
questions:
|
|
4
|
+
- id: artifact
|
|
5
|
+
prompt: Which durable artifact should this failure become?
|
|
6
|
+
header: Artifact
|
|
7
|
+
options:
|
|
8
|
+
- label: Guardrail
|
|
9
|
+
description: A check a command can run with no judgment; takes precedence over the other two.
|
|
10
|
+
- label: Procedure
|
|
11
|
+
description: A repeatable sequence of steps with a 0/1 gate per step and a start trigger.
|
|
12
|
+
- label: Learning
|
|
13
|
+
description: A conceptual lesson whose value is in its cause.
|
|
14
|
+
- label: Not now
|
|
15
|
+
description: Leave the failure open; it waits for recurrence or for a user correction.
|
|
16
|
+
- id: surface
|
|
17
|
+
prompt: For a guardrail, where is the check installed?
|
|
18
|
+
header: Surface
|
|
19
|
+
options:
|
|
20
|
+
- label: Linter
|
|
21
|
+
description: The linter config the project already runs.
|
|
22
|
+
- label: CI
|
|
23
|
+
description: The CI workflow the project already runs.
|
|
24
|
+
- label: Git hook
|
|
25
|
+
description: A git hook (afm install git runs the gate there).
|
|
26
|
+
- label: Not a guardrail
|
|
27
|
+
description: The artifact is a procedure, a learning or nothing, so no check is installed.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# One question per staleness, findability or dead-gotcha finding:
|
|
2
|
+
# afm ask restructure --scope <item-slug>
|
|
3
|
+
questions:
|
|
4
|
+
- id: finding
|
|
5
|
+
prompt: What should be done with this finding?
|
|
6
|
+
header: Finding
|
|
7
|
+
options:
|
|
8
|
+
- label: Update the doc
|
|
9
|
+
description: Read the current code, then update the stale doc (a proposal, never an auto-fix).
|
|
10
|
+
- label: Relocate
|
|
11
|
+
description: Move the information to where it is expected, or add a pointer there; a loading-strategy ADR for a tiering finding.
|
|
12
|
+
- label: Archive
|
|
13
|
+
description: Comment the dead entry out as a tombstone; nothing is deleted.
|
|
14
|
+
- label: Leave as is
|
|
15
|
+
description: The doc is still right; the report records the review.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: rf
|
|
3
|
+
prompt: Which PRD requirement does this user story implement?
|
|
4
|
+
header: RF mapping
|
|
5
|
+
recommended: New RF
|
|
6
|
+
options:
|
|
7
|
+
- label: New RF
|
|
8
|
+
description: Drafts the next RF in the PRD from the story.
|
|
9
|
+
- label: Existing RF
|
|
10
|
+
description: The operator names the number or the title.
|
|
11
|
+
- label: Not yet
|
|
12
|
+
description: Records [TBD]; decided later.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: scope
|
|
3
|
+
prompt: Where does the rule enter?
|
|
4
|
+
header: Rule scope
|
|
5
|
+
recommended: forward-only
|
|
6
|
+
options:
|
|
7
|
+
- label: universal
|
|
8
|
+
description: Section 3, applies to all code including legacy. May produce a large cleanup change.
|
|
9
|
+
- label: forward-only
|
|
10
|
+
description: Section 3.1, new code and files touched from today on. Legacy debt is tracked, not blocking.
|
|
11
|
+
- label: cancel
|
|
12
|
+
description: Nothing is written; the decision needs more thought.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: surface
|
|
3
|
+
prompt: Where does this trigger run?
|
|
4
|
+
header: Surface
|
|
5
|
+
recommended: pre-commit
|
|
6
|
+
options:
|
|
7
|
+
- label: pre-commit
|
|
8
|
+
description: Blocks every commit, including one made outside an agent session. Costs the trigger's runtime on each commit.
|
|
9
|
+
- label: ci
|
|
10
|
+
description: Blocks the merge, not the local commit. Only honest when the project already has CI.
|
|
11
|
+
- label: agent
|
|
12
|
+
description: Stays in the doc and runs by judgment. Honest for a heuristic trigger, not for a precise one nobody automated.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: heuristic
|
|
3
|
+
prompt: The change is borderline for a feature folder. Open one, or go straight to the loop?
|
|
4
|
+
header: Feature?
|
|
5
|
+
recommended: open-feature
|
|
6
|
+
options:
|
|
7
|
+
- label: open-feature
|
|
8
|
+
description: Create docs/features/NNN-slug with a spec, then plan and tasks. Best when the change spans files or has unknowns.
|
|
9
|
+
- label: straight-to-loop
|
|
10
|
+
description: Skip the folder and run the RED, GREEN, REFACTOR, COMMIT loop of core/afm.md section 2 once.
|
|
11
|
+
- id: us-link
|
|
12
|
+
prompt: Which user story does this feature correspond to?
|
|
13
|
+
header: Linked US
|
|
14
|
+
recommended: candidate
|
|
15
|
+
options:
|
|
16
|
+
- label: candidate
|
|
17
|
+
description: The story the scan matched in docs/ust.md. Confirms the link.
|
|
18
|
+
- label: other-existing
|
|
19
|
+
description: A different existing story. The operator gives its number.
|
|
20
|
+
- label: create-first
|
|
21
|
+
description: Write a new story with a Gherkin criterion in docs/ust.md before the spec.
|
|
22
|
+
- label: later
|
|
23
|
+
description: No story yet. The spec records a NEEDS CLARIFICATION marker to link it.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: artifact-language
|
|
3
|
+
prompt: Migrate the artifacts (docs, code comments, test names) to English?
|
|
4
|
+
header: Artifacts
|
|
5
|
+
recommended: Migrate to English
|
|
6
|
+
options:
|
|
7
|
+
- label: Migrate to English
|
|
8
|
+
description: Artifacts move to English and stop paying the token cost of a second language in every context load.
|
|
9
|
+
- label: Keep the current language
|
|
10
|
+
description: Nothing moves. The choice is recorded so the next update does not ask again.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: app-language
|
|
3
|
+
prompt: In which language does this product show its own users their strings? The PRD records none yet.
|
|
4
|
+
header: App language
|
|
5
|
+
recommended: Decide later
|
|
6
|
+
options:
|
|
7
|
+
- label: English
|
|
8
|
+
description: User-facing strings are English; nothing is excluded from the artifact migration.
|
|
9
|
+
- label: Portuguese
|
|
10
|
+
description: User-facing strings are Portuguese and stay out of the migration.
|
|
11
|
+
- label: Spanish
|
|
12
|
+
description: User-facing strings are Spanish and stay out of the migration.
|
|
13
|
+
- label: Decide later
|
|
14
|
+
description: Records [TBD]; the artifact language migration does not run until it is set.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: apply
|
|
3
|
+
prompt: Apply the migrations the dry run listed and move the version pin?
|
|
4
|
+
header: Update
|
|
5
|
+
recommended: Apply
|
|
6
|
+
options:
|
|
7
|
+
- label: Apply
|
|
8
|
+
description: Applies every migration in order, proves each one, then moves the pin. A failed migration keeps the pin where it was.
|
|
9
|
+
- label: Not now
|
|
10
|
+
description: Nothing is applied and the pin stays; the dry run can be repeated later.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
questions:
|
|
2
|
+
- id: reviewed
|
|
3
|
+
prompt: Did you read this document yourself and stand behind it?
|
|
4
|
+
header: Reviewed
|
|
5
|
+
options:
|
|
6
|
+
- label: Yes, I read it
|
|
7
|
+
description: Stamps the verification under your name.
|
|
8
|
+
- label: No
|
|
9
|
+
description: Nothing is stamped; a stamp asserts that a person read the content.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: executor
|
|
3
|
+
description: Writer of one bounded change. Makes the edit its brief names, test first, inside the files the brief grants, and reports what changed; dispatched with a brief.
|
|
4
|
+
capabilities: read, search, write, shell
|
|
5
|
+
---
|
|
6
|
+
You are an executor. The message that dispatched you is your brief: follow it.
|
|
7
|
+
|
|
8
|
+
You make the change the brief names, and only that change.
|
|
9
|
+
|
|
10
|
+
- Touch only the files the brief grants. Another file you need is a question for the caller, not an edit.
|
|
11
|
+
- Test first: a failing test (or a type that does not compile yet), then the smallest change that
|
|
12
|
+
makes it pass, then the refactor. Run the tests and the type check before you report.
|
|
13
|
+
- Reuse what exists before you add a helper. Add no option, hook or abstraction the brief did not ask for.
|
|
14
|
+
- Never print, write or commit a secret.
|
|
15
|
+
- Never push, and never commit unless the brief says to.
|
|
16
|
+
|
|
17
|
+
Reply with the files you changed, the checks you ran with their exact result, and anything you left
|
|
18
|
+
undone or doubt.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: explorer
|
|
3
|
+
description: Read-only investigator. Answers one question from the code, the docs or the web, cites what it read, and changes nothing; dispatched with a brief.
|
|
4
|
+
steps: 60
|
|
5
|
+
capabilities: read, search, web
|
|
6
|
+
mcpTools: approve, config, detect, doctor, failures_promotable, feature_lint, feature_status, gate, index, lang, next_id, path, policy, preflight, version
|
|
7
|
+
cliDoor: false
|
|
8
|
+
---
|
|
9
|
+
You are an explorer. The message that dispatched you is your brief: follow it.
|
|
10
|
+
|
|
11
|
+
You only read. You never edit a file, run a command that changes state, or commit.
|
|
12
|
+
|
|
13
|
+
- Read only what the question needs: the sections you are about to use, not whole trees.
|
|
14
|
+
- Cite every claim: a path with the line, or a source URL with the literal quote. A claim with no
|
|
15
|
+
citation is a guess, and you label it a guess.
|
|
16
|
+
- Never invent a path, a line number, a URL or a quote. If you did not read it, you do not cite it.
|
|
17
|
+
- Say what you could not find. Absence is a result.
|
|
18
|
+
|
|
19
|
+
You have at most 60 steps. Write the answer whole, not a step at a time. If you run out, reply with
|
|
20
|
+
what you have and what is still missing.
|
|
21
|
+
|
|
22
|
+
Reply with the answer first, then the evidence, then the gaps.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: reviewer
|
|
3
|
+
description: Blind auditor. Checks one piece of work it did not write against its sources and rules, and returns a verdict with evidence; dispatched with a brief.
|
|
4
|
+
capabilities: read, search, web
|
|
5
|
+
mcpTools: approve, config, detect, doctor, failures_promotable, feature_lint, feature_status, gate, index, lang, next_id, path, policy, preflight, version
|
|
6
|
+
cliDoor: false
|
|
7
|
+
---
|
|
8
|
+
You are a reviewer. The message that dispatched you is your brief: follow it.
|
|
9
|
+
|
|
10
|
+
You audit work you did not write. You read it and the sources or rules it answers to. You never
|
|
11
|
+
write a fix.
|
|
12
|
+
|
|
13
|
+
- Judge against the rules and sources the brief names, not against taste.
|
|
14
|
+
- Verify, do not trust: open each cited path, line or quote and confirm it says what the work claims.
|
|
15
|
+
- Run the checks the brief lists that the `afm` tools offer (the gate, the doctor, the index), alone and one
|
|
16
|
+
at a time, and report their exact output. You have no shell: a check that needs one is a check you did
|
|
17
|
+
not run, and you say so.
|
|
18
|
+
- Report a finding only with its evidence: the path and line, the rule it breaks, and the concrete
|
|
19
|
+
input or state that fails. A suspicion with no evidence is not a finding.
|
|
20
|
+
- Say what you did not check.
|
|
21
|
+
|
|
22
|
+
End with one verdict line: PASS when no finding stands, FAIL otherwise, followed by the findings
|
|
23
|
+
most severe first.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: rubric
|
|
3
|
+
description: Chooses between an ORM enum, a literal union, a branded type and a parser schema.
|
|
4
|
+
load: warm
|
|
5
|
+
fires_on: file-shape
|
|
6
|
+
trigger_ext: '.ts .tsx'
|
|
7
|
+
trigger_grep: '(^[[:space:]]*(export[[:space:]]+)?(const[[:space:]]+)?enum[[:space:]]+[A-Za-z_]|\([[:space:]]*[a-zA-Z_][A-Za-z0-9_]*:[[:space:]]*string[[:space:]]*,[[:space:]]*[a-zA-Z_][A-Za-z0-9_]*:[[:space:]]*string[[:space:]]*[,)])'
|
|
8
|
+
fires_when: 'a TS `enum` is declared, or a signature takes two adjacent `string` parameters'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Rubric — enum vs literal union vs branded type vs Zod schema
|
|
12
|
+
|
|
13
|
+
## Decision table
|
|
14
|
+
|
|
15
|
+
| Case | Choice | Anti-pattern |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Value exists in the DB (status, role, plan) | **ORM enum** (Prisma enum, etc) — the only path that survives `generate` | Pure TS enum that mirrors the ORM enum — duplication |
|
|
18
|
+
| ≤ 5 closed values, used only in code | **Literal union** (`"latest" \| "next" \| "beta"`) | Pure TS enum — produces transpiled waste, not tree-shakeable |
|
|
19
|
+
| Open string with a rule (user input, free dist-tag) | **Parser schema** (Zod) + parse at the boundary | Validation inside the domain (violates hard rule 16) |
|
|
20
|
+
| Primitive with a semantic invariant (sha256, userId ≠ sessionId, currency cents) | **Branded type** (`type Hash = string & { __brand: "Hash" }`) | Raw `string` — loses the check at the call site |
|
|
21
|
+
| Opaque value from an external SDK (Stripe price id) | SDK type + Zod at the boundary | Re-type as branded — duplicates the SDK |
|
|
22
|
+
|
|
23
|
+
## When a branded type wins
|
|
24
|
+
|
|
25
|
+
- A function takes two strings with different meanings (`copy(from: string, to: string)`). A branded type stops you from swapping the order.
|
|
26
|
+
- Hash, ID, currency in cents, timestamp in ms vs s. A branded type makes the conversion explicit.
|
|
27
|
+
- Different domain IDs (UserId vs SessionId vs OrgId). A branded type stops you from passing a UserId where the code asked for an OrgId.
|
|
28
|
+
|
|
29
|
+
## When a branded type does not pay off
|
|
30
|
+
|
|
31
|
+
- A string that goes to a log, a UI, or the network. The reader gains nothing.
|
|
32
|
+
- The type already comes from the SDK as an opaque string. Re-typing it just duplicates the SDK.
|
|
33
|
+
- The function has one parameter. There is no ambiguity to resolve.
|
|
34
|
+
|
|
35
|
+
## Anti-examples
|
|
36
|
+
|
|
37
|
+
- ❌ `enum Plan { FREE = "FREE", PRO = "PRO" }` in TS when Prisma already has `enum Plan { FREE, PRO }`. Use the Prisma one directly.
|
|
38
|
+
- ❌ `type DistTag = string` that accepts anything. Use a literal union if the set is closed, or Zod if it is open with a rule.
|
|
39
|
+
- ❌ `copy(src: string, dst: string)` called by mistake as `copy(dst, src)`. Branded `SrcPath` and `DstPath` types fix this.
|
|
40
|
+
- ❌ Branding every `string` "for consistency". This adds overhead with no check gained.
|