@really-knows-ai/foundry 2.3.1 → 3.0.0

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.
Files changed (170) hide show
  1. package/README.md +200 -198
  2. package/dist/.opencode/plugins/foundry-tools/appraiser-tools.js +28 -0
  3. package/dist/.opencode/plugins/foundry-tools/artefact-tools.js +58 -0
  4. package/dist/.opencode/plugins/foundry-tools/assay-tools.js +92 -0
  5. package/dist/.opencode/plugins/foundry-tools/attestation-tools.js +191 -0
  6. package/dist/.opencode/plugins/foundry-tools/config-create-tools.js +128 -0
  7. package/dist/.opencode/plugins/foundry-tools/config-law-tools.js +380 -0
  8. package/dist/.opencode/plugins/foundry-tools/config-tools.js +43 -0
  9. package/dist/.opencode/plugins/foundry-tools/feedback-tools.js +234 -0
  10. package/dist/.opencode/plugins/foundry-tools/git-helpers.js +354 -0
  11. package/dist/.opencode/plugins/foundry-tools/git-tools.js +181 -0
  12. package/dist/.opencode/plugins/foundry-tools/helpers.js +340 -0
  13. package/dist/.opencode/plugins/foundry-tools/history-tools.js +20 -0
  14. package/dist/.opencode/plugins/foundry-tools/memory-admin-tools.js +296 -0
  15. package/dist/.opencode/plugins/foundry-tools/memory-helpers.js +104 -0
  16. package/dist/.opencode/plugins/foundry-tools/memory-tools.js +286 -0
  17. package/dist/.opencode/plugins/foundry-tools/orchestrate-tool.js +159 -0
  18. package/dist/.opencode/plugins/foundry-tools/snapshot-tools.js +104 -0
  19. package/dist/.opencode/plugins/foundry-tools/stage-tools.js +186 -0
  20. package/dist/.opencode/plugins/foundry-tools/validate-tools.js +263 -0
  21. package/dist/.opencode/plugins/foundry-tools/workfile-tools.js +102 -0
  22. package/dist/.opencode/plugins/foundry.js +105 -0
  23. package/dist/CHANGELOG.md +490 -0
  24. package/dist/LICENSE +21 -0
  25. package/dist/README.md +278 -0
  26. package/dist/docs/README.md +59 -0
  27. package/dist/docs/architecture.md +434 -0
  28. package/dist/docs/concepts.md +396 -0
  29. package/dist/docs/getting-started.md +345 -0
  30. package/dist/docs/memory-maintenance.md +176 -0
  31. package/dist/docs/tools.md +1411 -0
  32. package/dist/docs/work-spec.md +283 -0
  33. package/dist/scripts/lib/artefacts.js +151 -0
  34. package/dist/scripts/lib/assay/loader.js +151 -0
  35. package/dist/scripts/lib/assay/parse-jsonl.js +102 -0
  36. package/dist/scripts/lib/assay/permissions.js +52 -0
  37. package/dist/scripts/lib/assay/run.js +219 -0
  38. package/dist/scripts/lib/assay/spawn-with-timeout.js +138 -0
  39. package/dist/scripts/lib/attestation/attest.js +111 -0
  40. package/dist/scripts/lib/attestation/canonical-json.js +109 -0
  41. package/dist/scripts/lib/attestation/hash.js +17 -0
  42. package/dist/scripts/lib/attestation/parse.js +14 -0
  43. package/dist/scripts/lib/attestation/payload.js +106 -0
  44. package/dist/scripts/lib/attestation/render.js +16 -0
  45. package/dist/scripts/lib/attestation/verify.js +15 -0
  46. package/dist/scripts/lib/branch-guard.js +72 -0
  47. package/dist/scripts/lib/config-creators/appraiser.js +9 -0
  48. package/dist/scripts/lib/config-creators/artefact-type.js +9 -0
  49. package/dist/scripts/lib/config-creators/cycle.js +11 -0
  50. package/dist/scripts/lib/config-creators/factory.js +49 -0
  51. package/dist/scripts/lib/config-creators/flow.js +11 -0
  52. package/dist/scripts/lib/config-validators/appraiser.js +49 -0
  53. package/dist/scripts/lib/config-validators/artefact-type.js +38 -0
  54. package/dist/scripts/lib/config-validators/cycle.js +131 -0
  55. package/dist/scripts/lib/config-validators/flow.js +57 -0
  56. package/dist/scripts/lib/config-validators/helpers.js +96 -0
  57. package/dist/scripts/lib/config-validators/law.js +96 -0
  58. package/dist/scripts/lib/config.js +393 -0
  59. package/dist/scripts/lib/failed-flow.js +131 -0
  60. package/dist/scripts/lib/feedback-store.js +249 -0
  61. package/dist/scripts/lib/feedback-transitions.js +105 -0
  62. package/dist/scripts/lib/finalize.js +70 -0
  63. package/dist/scripts/lib/foundational-guards.js +13 -0
  64. package/dist/scripts/lib/git-bridge.js +77 -0
  65. package/dist/scripts/lib/git-finish/work-finish.js +233 -0
  66. package/dist/scripts/lib/git-policy.js +101 -0
  67. package/dist/scripts/lib/guards.js +125 -0
  68. package/dist/scripts/lib/history.js +132 -0
  69. package/dist/scripts/lib/memory/admin/create-edge-type.js +91 -0
  70. package/dist/scripts/lib/memory/admin/create-entity-type.js +43 -0
  71. package/dist/scripts/lib/memory/admin/create-extractor.js +67 -0
  72. package/dist/scripts/lib/memory/admin/drop-edge-type.js +40 -0
  73. package/dist/scripts/lib/memory/admin/drop-entity-type.js +172 -0
  74. package/dist/scripts/lib/memory/admin/dump.js +47 -0
  75. package/dist/scripts/lib/memory/admin/helpers.js +31 -0
  76. package/dist/scripts/lib/memory/admin/init.js +170 -0
  77. package/dist/scripts/lib/memory/admin/live-store.js +76 -0
  78. package/dist/scripts/lib/memory/admin/reembed.js +285 -0
  79. package/dist/scripts/lib/memory/admin/rename-edge-type.js +54 -0
  80. package/dist/scripts/lib/memory/admin/rename-entity-type.js +151 -0
  81. package/dist/scripts/lib/memory/admin/reset.js +24 -0
  82. package/dist/scripts/lib/memory/admin/vacuum.js +9 -0
  83. package/dist/scripts/lib/memory/admin/validate.js +19 -0
  84. package/dist/scripts/lib/memory/config.js +149 -0
  85. package/dist/scripts/lib/memory/cozo.js +136 -0
  86. package/dist/scripts/lib/memory/drift.js +71 -0
  87. package/dist/scripts/lib/memory/embeddings.js +128 -0
  88. package/dist/scripts/lib/memory/frontmatter.js +75 -0
  89. package/dist/scripts/lib/memory/ndjson.js +84 -0
  90. package/dist/scripts/lib/memory/paths.js +25 -0
  91. package/dist/scripts/lib/memory/permissions.js +41 -0
  92. package/dist/scripts/lib/memory/prompt.js +109 -0
  93. package/dist/scripts/lib/memory/query.js +56 -0
  94. package/dist/scripts/lib/memory/reads.js +109 -0
  95. package/dist/scripts/lib/memory/schema.js +64 -0
  96. package/dist/scripts/lib/memory/search.js +73 -0
  97. package/dist/scripts/lib/memory/singleton.js +49 -0
  98. package/dist/scripts/lib/memory/store.js +162 -0
  99. package/dist/scripts/lib/memory/types.js +93 -0
  100. package/dist/scripts/lib/memory/validate.js +58 -0
  101. package/dist/scripts/lib/memory/writes.js +40 -0
  102. package/{scripts → dist/scripts}/lib/pending.js +7 -2
  103. package/dist/scripts/lib/secret.js +59 -0
  104. package/{scripts → dist/scripts}/lib/slug.js +3 -2
  105. package/dist/scripts/lib/snapshot/finish.js +103 -0
  106. package/dist/scripts/lib/snapshot/inspect.js +253 -0
  107. package/dist/scripts/lib/snapshot/render.js +55 -0
  108. package/dist/scripts/lib/sort-fs-check.js +121 -0
  109. package/dist/scripts/lib/sort-routing.js +101 -0
  110. package/{scripts → dist/scripts}/lib/stage-guard.js +12 -6
  111. package/{scripts → dist/scripts}/lib/state.js +4 -0
  112. package/dist/scripts/lib/token.js +57 -0
  113. package/dist/scripts/lib/tracing.js +59 -0
  114. package/dist/scripts/lib/ulid.js +100 -0
  115. package/dist/scripts/lib/validator-jsonl.js +162 -0
  116. package/{scripts → dist/scripts}/lib/workfile.js +38 -20
  117. package/dist/scripts/orchestrate-cycle.js +215 -0
  118. package/dist/scripts/orchestrate-phases.js +314 -0
  119. package/dist/scripts/orchestrate.js +163 -0
  120. package/dist/scripts/sort.js +278 -0
  121. package/{skills → dist/skills}/add-appraiser/SKILL.md +42 -6
  122. package/{skills → dist/skills}/add-artefact-type/SKILL.md +49 -21
  123. package/{skills → dist/skills}/add-cycle/SKILL.md +60 -14
  124. package/dist/skills/add-extractor/SKILL.md +133 -0
  125. package/{skills → dist/skills}/add-flow/SKILL.md +39 -7
  126. package/dist/skills/add-law/SKILL.md +191 -0
  127. package/dist/skills/add-memory-edge-type/SKILL.md +52 -0
  128. package/dist/skills/add-memory-entity-type/SKILL.md +74 -0
  129. package/{skills → dist/skills}/appraise/SKILL.md +62 -13
  130. package/dist/skills/assay/SKILL.md +72 -0
  131. package/dist/skills/change-embedding-model/SKILL.md +58 -0
  132. package/dist/skills/drop-memory-edge-type/SKILL.md +54 -0
  133. package/dist/skills/drop-memory-entity-type/SKILL.md +57 -0
  134. package/dist/skills/dry-run/SKILL.md +116 -0
  135. package/{skills → dist/skills}/flow/SKILL.md +15 -2
  136. package/dist/skills/forge/SKILL.md +121 -0
  137. package/dist/skills/human-appraise/SKILL.md +153 -0
  138. package/{skills → dist/skills}/init-foundry/SKILL.md +23 -4
  139. package/dist/skills/init-memory/SKILL.md +92 -0
  140. package/{skills → dist/skills}/orchestrate/SKILL.md +30 -4
  141. package/dist/skills/quench/SKILL.md +99 -0
  142. package/{skills → dist/skills}/refresh-agents/SKILL.md +1 -1
  143. package/dist/skills/rename-memory-edge-type/SKILL.md +50 -0
  144. package/dist/skills/rename-memory-entity-type/SKILL.md +51 -0
  145. package/dist/skills/reset-memory/SKILL.md +54 -0
  146. package/dist/skills/upgrade-foundry/SKILL.md +192 -0
  147. package/package.json +34 -17
  148. package/.opencode/plugins/foundry.js +0 -761
  149. package/CHANGELOG.md +0 -90
  150. package/docs/concepts.md +0 -59
  151. package/docs/getting-started.md +0 -78
  152. package/docs/work-spec.md +0 -193
  153. package/scripts/lib/artefacts.js +0 -124
  154. package/scripts/lib/config.js +0 -175
  155. package/scripts/lib/feedback-transitions.js +0 -25
  156. package/scripts/lib/feedback.js +0 -440
  157. package/scripts/lib/finalize.js +0 -41
  158. package/scripts/lib/history.js +0 -59
  159. package/scripts/lib/secret.js +0 -23
  160. package/scripts/lib/tags.js +0 -108
  161. package/scripts/lib/token.js +0 -26
  162. package/scripts/orchestrate.js +0 -418
  163. package/scripts/sort.js +0 -370
  164. package/scripts/validate-tags.js +0 -54
  165. package/skills/add-law/SKILL.md +0 -105
  166. package/skills/forge/SKILL.md +0 -88
  167. package/skills/human-appraise/SKILL.md +0 -82
  168. package/skills/quench/SKILL.md +0 -62
  169. package/skills/upgrade-foundry/SKILL.md +0 -216
  170. /package/{skills → dist/skills}/list-agents/SKILL.md +0 -0
package/README.md CHANGED
@@ -1,276 +1,278 @@
1
1
  # Foundry
2
2
 
3
- A skill-driven framework for governed artefact generation and evaluation using AI coding tools. Install it as an npm package and define your own artefact types, laws, and flows — Foundry handles the forge-quench-appraise pipeline.
3
+ > Engineered confidence for AI-generated work. Define what good looks like.
4
4
 
5
- ## Compatibility
5
+ [![npm version](https://img.shields.io/npm/v/@really-knows-ai/foundry.svg)](https://www.npmjs.com/package/@really-knows-ai/foundry)
6
+ [![Tests](https://github.com/really-knows-ai/foundry/actions/workflows/test.yml/badge.svg)](https://github.com/really-knows-ai/foundry/actions/workflows/test.yml)
7
+ [![license](https://img.shields.io/npm/l/@really-knows-ai/foundry.svg)](LICENSE)
6
8
 
7
- - **OpenCode** — full support, multi-model routing via file-based agents
9
+ ---
8
10
 
9
- Multi-model support enables model diversity across pipeline stages. Foundry agents are defined as `.opencode/agents/foundry-*.md` files, generated by the `refresh-agents` skill (also run during `init-foundry`). Cycle definitions specify which model each stage uses. Tools limited to a single model lose model-diversity but still get personality-based diversity.
11
+ ## Engineering confidence
10
12
 
11
- ## Installation
13
+ ### Confidence is engineered
12
14
 
13
- Add `@really-knows-ai/foundry` to your OpenCode config:
15
+ Generation is cheap; trust is expensive. An agent can produce output quickly, skip
16
+ validation, or lose feedback between iterations. The work arrives fast, but the
17
+ evidence is incomplete and trust is fragile. Nobody can see the path from prompt to
18
+ finish. Nobody knows how many times the agent tried, what it fixed, or why it
19
+ stopped.
14
20
 
15
- ```json
16
- // opencode.json
17
- {
18
- "packages": {
19
- "@really-knows-ai/foundry": "latest"
20
- }
21
- }
22
- ```
21
+ Foundry is the system around the prompt: explicit standards, repeatable checks, and
22
+ recorded sign-off applied to every artefact your AI produces. It transforms "ask an
23
+ agent and hope" into a staged system where the checks are structural and mandatory.
24
+ If an artefact should be validated, it is validated. If feedback must be resolved,
25
+ that state is recorded. If a stage writes outside its lane, the cycle stops. The
26
+ framework is deterministic; the LLM is not. Your laws are.
23
27
 
24
- ## Quick start
28
+ Variability helps where creativity matters; control enforces discipline where
29
+ reliability does. You choose what gates each stage passes through, what laws your
30
+ artefacts must satisfy, and which models you trust for each decision. Foundry runs
31
+ the loop and records every step in git, so the path from draft to approved artefact
32
+ is auditable, repeatable, and defensible to auditors and stakeholders. You can show
33
+ exactly how the output was made. Confidence is engineered; it is not hoped for.
25
34
 
26
- 1. **Install** the package as shown above
27
- 2. **Initialize** — use the `init-foundry` skill to scaffold a `foundry/` directory in your project
28
- 3. **Define artefact types** — use `add-artefact-type` to create types with file patterns, descriptions, and optional validation
29
- 4. **Add laws** — use `add-law` to define subjective pass/fail criteria (global or per-type)
30
- 5. **Add appraisers** — use `add-appraiser` to create appraiser personalities
31
- 6. **Define cycles** — use `add-cycle` to wire artefact types into forge/quench/appraise loops
32
- 7. **Define flows** — use `add-flow` to sequence cycles into end-to-end pipelines
33
- 8. **Run** — use the `flow` skill to execute a flow
35
+ ### The operating model: assay, then forge → quench → appraise
34
36
 
35
- ## How it works
37
+ A codebase-aware cycle can begin with **assay**: a deterministic pre-forge stage
38
+ that runs project-authored extractor scripts, parses the strict JSONL facts they
39
+ emit, and writes typed facts into flow memory. In the foundry metaphor, an assay
40
+ establishes composition before work begins. In Foundry, assay gives forge a
41
+ measured map of the project before it creates an artefact. Cycles without memory
42
+ configuration skip this stage.
36
43
 
37
- ```
38
- Foundry Flow
39
- └─ Cycle 1 (e.g., ideation)
40
- │ ├─ Forge → produce the artefact
41
- │ ├─ Quench → deterministic CLI checks (if defined)
42
- │ ├─ Appraise → subjective evaluation by multiple appraisers
43
- │ └─ ↺ iterate until all feedback is resolved
44
- └─ Cycle 2 (e.g., creation)
45
- ├─ reads output from Cycle 1 (read-only)
46
- ├─ Forge → produce the artefact
47
- ├─ Quench → deterministic CLI checks
48
- ├─ Appraise → subjective evaluation
49
- └─ ↺ iterate until all feedback is resolved
50
- ```
44
+ After assay, one draft enters a short loop and leaves only when it passes quality
45
+ gates. Each loop has four distinct roles that turn a candidate into a verified output:
51
46
 
52
- A **foundry flow** runs one or more **foundry cycles** in sequence. Each cycle produces a single artefact type by looping through forge → quench → appraise until the artefact passes all criteria. The output of one cycle becomes read-only input for the next.
47
+ - **Forge** produces or revises the artefact. The stage that creates and reshapes
48
+ work, responding to feedback from appraisers or building on prior drafts.
53
49
 
54
- All state lives in `WORK.md` on a dedicated work branch. Every stage micro-commits, and file modification enforcement ensures stages only touch what they're allowed to.
50
+ - **Quench** runs deterministic checks that harden or reject the work. Validation is
51
+ fast and non-negotiable, catching errors before they reach appraisers.
55
52
 
56
- ## Custom tools
53
+ - **Appraise** judges quality against written laws. Independent evaluators inspect
54
+ whether the work meets the subjective standards you define.
57
55
 
58
- The Foundry plugin exposes 25 custom tools that handle all deterministic pipeline operations. Skills call these tools instead of manipulating files directly — this eliminates LLM interpretation of file formats and ensures consistent state management.
56
+ - **Human-appraise** provides direct judgement when the stakes require it or the loop
57
+ deadlocks. Offers human oversight at critical decision points.
59
58
 
60
- | Category | Tools |
61
- |----------|-------|
62
- | **Workfile** | `foundry_workfile_create`, `foundry_workfile_get`, `foundry_workfile_set`, `foundry_workfile_delete` |
63
- | **Artefacts** | `foundry_artefacts_add`, `foundry_artefacts_list`, `foundry_artefacts_set_status` |
64
- | **Feedback** | `foundry_feedback_add`, `foundry_feedback_action`, `foundry_feedback_wontfix`, `foundry_feedback_resolve`, `foundry_feedback_list` |
65
- | **History** | `foundry_history_append`, `foundry_history_list` |
66
- | **Sort** | `foundry_sort` |
67
- | **Config** | `foundry_config_cycle`, `foundry_config_artefact_type`, `foundry_config_laws`, `foundry_config_validation`, `foundry_config_appraisers`, `foundry_config_flow` |
68
- | **Validation** | `foundry_validate_run`, `foundry_appraisers_select` |
69
- | **Git** | `foundry_git_branch`, `foundry_git_commit` |
59
+ Every stage commits separately, so every step leaves a record. Every decision is
60
+ timestamped. A single loop produces an **output** — a verified draft. A flow
61
+ composes one or more such loops to produce an **outcome** the final artefact that
62
+ reaches your codebase or customers.
70
63
 
71
- Tools are backed by shared library modules in `scripts/lib/` that use injectable I/O for testability. The sort routing engine (`scripts/sort.js`) exports `runSort()` for the sort tool.
64
+ ### What you describe, what Foundry enforces
72
65
 
73
- ## Core concepts
66
+ You write the laws — the criteria that define acceptable. You describe the artefact
67
+ types you want produced and what files they generate. You choose which stages each
68
+ cycle passes through and what models to use at each step. You control the operating
69
+ model entirely. Your configuration is law.
74
70
 
75
- ### Foundry Flows
71
+ Foundry runs the loop, gates writes per stage so only the right mutation happens at
72
+ the right time, records every decision in git, and stops when there is nothing left
73
+ to fix. Each stage holds a token that authorises its mutations. Stages cannot write
74
+ outside their assigned lane. Feedback state moves through a state machine that
75
+ prevents invalid transitions. The framework owns the process and enforces the rules;
76
+ the LLM performs the creative and evaluative work inside each stage. You define the
77
+ machine; Foundry runs it. Confidence is the difference.
76
78
 
77
- Defined in `foundry/flows/`. A flow lists cycles to execute in order. Starting a flow creates a work branch and a fresh `WORK.md`.
79
+ ---
78
80
 
79
- ### Foundry Cycles
81
+ ## Compatibility
80
82
 
81
- Defined in `foundry/cycles/`. A cycle specifies:
82
- - `output` the artefact type it produces (read-write)
83
- - `inputs` — artefact types from previous cycles (read-only)
83
+ Foundry works primarily with OpenCode. The skills and tools are portable to other
84
+ skill-aware AI systems. Multi-model stage routing is OpenCode-specific today.
84
85
 
85
- ### Stages
86
+ - **OpenCode** — full support. Multi-model routing via file-based `foundry-*` agents.
87
+ This is the primary target platform.
86
88
 
87
- The three steps within a cycle:
88
- - **Forge** produce or revise the artefact
89
- - **Quench** run deterministic CLI checks (skipped if artefact type has no `validation.md`)
90
- - **Appraise** — subjective evaluation by multiple independent appraisers
89
+ - **Other skill-aware AI tools** — the skills and tools are portable to any
90
+ skill-aware AI system. Multi-model stage routing is OpenCode-specific today
91
+ because it relies on `.opencode/agents/` files.
91
92
 
92
- ### Artefact types
93
+ ---
93
94
 
94
- Defined in `foundry/artefacts/<type>/`. Each type has:
95
- - `definition.md` — id, name, file patterns, output directory, appraiser config, prose description
96
- - `laws.md` (optional) — type-specific subjective criteria
97
- - `validation.md` (optional) — CLI commands with `{file}` placeholder; non-zero exit = failure
95
+ ## Install
98
96
 
99
- ### Laws
97
+ Add the plugin to `opencode.json`:
100
98
 
101
- Subjective pass/fail criteria. Two scopes:
102
- - `foundry/laws/*.md` — global laws, all files concatenated, apply to everything
103
- - `foundry/artefacts/<type>/laws.md` — type-specific laws
99
+ ```json
100
+ {
101
+ "$schema": "https://opencode.ai/config.json",
102
+ "plugin": ["@really-knows-ai/foundry"]
103
+ }
104
+ ```
104
105
 
105
- Each law is a `## heading` (the identifier, used in feedback tags as `#law:<id>`) with a description, passing criteria, and failing criteria.
106
+ Restart OpenCode so the plugin registers its tools and skills. You will see new
107
+ tools and skills become available in OpenCode's command palette once the restart
108
+ completes. The `init-foundry` skill and flow-management tools are now ready to use.
106
109
 
107
- ### Appraisers
110
+ ---
108
111
 
109
- Defined in `foundry/appraisers/`. Each appraiser has a personality and an optional model override. Appraisers are assigned to artefact types via the `appraisers` section in the type's `definition.md`:
112
+ ## Upgrade
110
113
 
111
- ```yaml
112
- appraisers:
113
- count: 3 # how many appraisers (default: 3)
114
- allowed: [pedantic, pragmatic] # which personalities (default: all available)
115
- ```
114
+ Run the `upgrade-foundry` skill from a clean project state when moving an existing project to the installed Foundry version. The skill preserves the existing `foundry/` directory, initialises a fresh current-version configuration, analyses the preserved configuration as source material, and recreates supported concepts through current tools.
116
115
 
117
- Appraisers are distributed evenly across available personalities for maximum diversity. If you request 6 appraisers with 3 personalities, you get 2 of each. Model diversity is configured at the cycle level (per-stage) and optionally per-appraiser — see [concepts](docs/concepts.md).
116
+ The upgrade process asks clarifying questions for ambiguous routing, input contracts, validation behaviour, memory settings, and deprecated concepts. It leaves the preserved source directory in place until you explicitly approve cleanup.
118
117
 
119
- ### WORK.md
118
+ ---
120
119
 
121
- Transient shared state on the work branch. Tracks:
122
- - Current position (flow, cycle, stage) in frontmatter
123
- - Goal description
124
- - Artefact registry (what exists, its status)
125
- - All feedback with full lifecycle
120
+ ## Quick start
126
121
 
127
- ### Feedback lifecycle
122
+ ### Phase 1 — Install
128
123
 
129
- ```
130
- open - [ ] issue #tag → needs generator action
131
- actioned - [x] issue #tag → needs approval
132
- wont-fix - [~] issue #tag | wont-fix: <reason> → needs approval
133
- approved - [x] issue #tag | approved → resolved
134
- approved - [~] issue #tag | wont-fix: <reason> | approved → resolved
135
- rejected - [x] issue #tag | rejected: <reason> → re-opened
136
- rejected - [~] issue #tag | wont-fix: <reason> | rejected → re-opened
137
- ```
124
+ Add the plugin to `opencode.json` (see Install section above):
138
125
 
139
- Validation feedback (`#validation`) cannot be wont-fixed — deterministic rules are not negotiable.
126
+ ```json
127
+ {
128
+ "$schema": "https://opencode.ai/config.json",
129
+ "plugin": ["@really-knows-ai/foundry"]
130
+ }
131
+ ```
140
132
 
141
- ### File modification enforcement
133
+ Then restart OpenCode so the plugin registers its tools and skills. You will see new
134
+ tools and skills become available in OpenCode's command palette once the restart
135
+ completes. The `init-foundry` skill and flow-management tools are now ready to use.
142
136
 
143
- Every stage micro-commits. The cycle checks the git diff:
144
- - After forge: only output artefact file patterns + WORK.md + WORK.history.yaml (input artefacts are read-only — violation if touched)
145
- - After quench/appraise: only WORK.md + WORK.history.yaml
146
- - Violations are hard stops
137
+ ### Phase 2 Initialise
147
138
 
148
- > **Merge hygiene:** WORK.md and WORK.history.yaml are ephemeral working files. Delete them before squash-merging the branch back into main.
139
+ Open OpenCode in your project repo and say:
149
140
 
150
- ## Skills
141
+ ```
142
+ > run init-foundry
143
+ ```
151
144
 
152
- Everything is a skill. Skills are either atomic (do one thing) or composite (orchestrate other skills).
145
+ Foundry scaffolds a `foundry/` directory, generates one `foundry-<model>` agent file
146
+ per model available in your session, commits the structure, and then asks you to
147
+ restart. All the foundational configuration directories are created; you will
148
+ populate them next.
153
149
 
154
- ### Pipeline skills
150
+ Restart OpenCode so the new `foundry-<model>` agents register — multi-model dispatch cannot route to agents it cannot discover.
155
151
 
156
- | Skill | Type | Purpose |
157
- |-------|------|---------|
158
- | `forge` | atomic | Produce or revise an artefact |
159
- | `quench` | atomic | Run deterministic CLI checks |
160
- | `appraise` | atomic | Dispatch multiple appraisers, consolidate feedback |
161
- | `cycle` | composite | forge → quench → appraise → iterate |
162
- | `flow` | composite | Orchestrate cycles on a work branch |
152
+ ### Phase 3 Build a flow without writing one
163
153
 
164
- ### Helper skills
154
+ Ask Foundry to set up a flow:
165
155
 
166
- | Skill | Purpose |
167
- |-------|---------|
168
- | `init-foundry` | Scaffold the `foundry/` directory in your project |
169
- | `add-artefact-type` | Create a new artefact type with conflict and glob-overlap checks |
170
- | `add-law` | Create a new law with conflict detection |
171
- | `add-appraiser` | Create a new appraiser personality with semantic overlap checks |
172
- | `add-cycle` | Create a new cycle within a flow with dependency validation |
173
- | `add-flow` | Create a new flow definition |
156
+ ```
157
+ > set up a flow that writes haikus
158
+ ```
174
159
 
175
- ### Utility skills
160
+ Foundry will ask clarifying questions about the flow's purpose, constraints, and
161
+ entry points. It will then scaffold a haiku artefact type with a syllable-count
162
+ validator, laws for form / imagery / mood, two appraisers with different
163
+ sensibilities and bias profiles, a cycle that connects them in sequence, and a flow
164
+ that ties it all together. Everything is scaffolded; you do not write any
165
+ configuration by hand. This demonstrates the full system in action.
176
166
 
177
- | Skill | Purpose |
178
- |-------|---------|
179
- | `sort` | Deterministic cycle router — determines and dispatches the next stage |
180
- | `hitl` | Human-in-the-loop intervention points |
167
+ Now run it:
181
168
 
182
- All helper skills are interactive — they walk you through the process, check for conflicts, and confirm before writing files.
169
+ ```
170
+ > write me a haiku about autumn
171
+ ```
183
172
 
184
- ## Package structure
173
+ Here is what the loop produces:
185
174
 
186
175
  ```
187
- @really-knows-ai/foundry
188
- ├── .opencode/
189
- │ └── plugins/
190
- │ └── foundry.js # OpenCode plugin (skills + 25 custom tools)
191
- ├── skills/ # skill definitions (the pipeline)
192
- │ ├── forge/
193
- │ ├── quench/
194
- │ ├── appraise/
195
- │ ├── cycle/
196
- │ ├── flow/
197
- │ ├── init-foundry/
198
- │ ├── add-artefact-type/
199
- │ ├── add-law/
200
- │ ├── add-appraiser/
201
- │ ├── add-cycle/
202
- │ ├── add-flow/
203
- │ ├── sort/
204
- │ └── hitl/
205
- ├── scripts/ # shared library and routing engine
206
- │ ├── lib/
207
- │ │ ├── workfile.js # WORK.md frontmatter parsing/writing
208
- │ │ ├── artefacts.js # artefacts table operations
209
- │ │ ├── history.js # WORK.history.yaml operations
210
- │ │ ├── feedback.js # feedback lifecycle operations
211
- │ │ ├── config.js # foundry/ config readers
212
- │ │ └── tags.js # tag extraction
213
- │ └── sort.js # deterministic routing engine (exports runSort)
214
- ├── tests/ # test suite (node:test)
215
- ├── docs/ # concept docs and specs
216
- ├── package.json
217
- └── README.md
176
+ forge → drafts a haiku [commit]
177
+ quench → 7/7/5 — fails syllable check [commit]
178
+ forge → revises [commit]
179
+ quench → 5/7/5 passes [commit]
180
+ appraise → 2 appraisers, one flags weak imagery [commit]
181
+ forge → revises [commit]
182
+ appraise → clean [commit]
183
+ done → squash-merged to main with attestation
218
184
  ```
219
185
 
220
- ## User project structure
186
+ Every stage commits. Every decision is recorded. Every piece of feedback and every
187
+ revision leaves a trace in the work branch. The final artefact on `main` carries a
188
+ signed attestation showing exactly how that output was produced, which models
189
+ contributed, and when each appraiser signed off.
221
190
 
222
- After running `init-foundry`, your project gets a `foundry/` directory:
191
+ This trace is the proof. You can play it back, audit it, replay it under a different
192
+ model, or use it to argue that the AI output is trustworthy. Every step is visible.
193
+ Nothing is hidden.
223
194
 
224
- ```
225
- your-project/
226
- ├── foundry/
227
- │ ├── flows/ # flow definitions
228
- │ ├── cycles/ # cycle definitions
229
- │ ├── artefacts/ # artefact type definitions
230
- │ │ └── <type>/
231
- │ │ ├── definition.md
232
- │ │ ├── laws.md # (optional) type-specific laws
233
- │ │ └── validation.md # (optional) CLI checks
234
- │ ├── laws/ # global laws
235
- │ └── appraisers/ # appraiser personalities
236
- ├── opencode.json
237
- └── ...
238
- ```
195
+ For codebase-aware flows, add flow memory after the first run: initialise memory,
196
+ declare the entity and edge vocabulary, add extractors, and opt a cycle into
197
+ `assay.extractors`. See [Optional: flow memory](docs/getting-started.md#optional-flow-memory)
198
+ and [Assay](docs/concepts.md#assay) for the configuration path.
199
+
200
+ > **Note (3.0.0):** flow memory currently persists to `cozo-node`, which is
201
+ > unmaintained upstream. Installation produces six cosmetic deprecation warnings
202
+ > from transitive dependencies (`pnpm audit` is clean). Foundry will migrate to
203
+ > a maintained backend in a future release; the public `foundry_memory_*` tools
204
+ > and on-disk vocabulary/NDJSON format are designed to survive that migration.
205
+ > See `CHANGELOG.md` and [docs/memory-maintenance.md](docs/memory-maintenance.md#backend-status-as-of-300).
206
+
207
+ ---
208
+
209
+ ## What you can show your team
210
+
211
+ After the quick start completes, you have five concrete artefacts to point at to
212
+ demonstrate engineered confidence:
213
+
214
+ - **The artefact itself** — `haikus/autumn.md` on `main`. The final, approved output
215
+ ready for use or deployment.
216
+
217
+ - **The laws it satisfied** — `foundry/artefacts/haiku/laws.md`. The criteria it was
218
+ measured against, written in markdown and version-controlled.
219
+
220
+ - **The feedback ledger** — `WORK.feedback.yaml` on the archived work branch. Every
221
+ issue raised, by whom, and how it was resolved during the loop.
222
+
223
+ - **The per-stage commit history** — the raw commits on `archive/work/<flow>-<...>`.
224
+ A micro-commit per stage showing exactly what changed and why at each step.
239
225
 
240
- ## Design decisions
226
+ - **The signed attestation on main** — the squash commit with the Foundry attestation
227
+ block embedded in its message. Proof of approval, signed and timestamped.
241
228
 
242
- ### Everything is markdown
229
+ This is what makes "engineered confidence" concrete. You can show your team exactly
230
+ how that AI output was produced, what it passed through, why you trust it, and who
231
+ signed off. Every step is auditable. Every decision is recorded. The loop is
232
+ reproducible.
243
233
 
244
- Flow definitions, cycle definitions, artefact types, laws, appraiser personalities, skills — all markdown. Readable by humans, consumable by LLMs, versionable in git. No config files, no databases, no custom formats.
234
+ ---
245
235
 
246
- ### Skills are the pipeline, tools are the machinery
236
+ ## What's in the box
247
237
 
248
- Composition happens via skills referencing other skills. The `flow` skill reads a flow definition and invokes the `cycle` skill. The `cycle` skill invokes `forge`, `quench`, and `appraise`. Skills handle creative and subjective work; deterministic operations (parsing, routing, state updates) are handled by custom tools backed by shared library code.
238
+ - **Deterministic governance** routing, commits, write boundaries, and feedback
239
+ state live in tested plugin code, outside LLM control.
249
240
 
250
- ### WORK.md as shared state
241
+ - **Written quality criteria** — laws are markdown files; an appraiser panel scores
242
+ each artefact against them, so quality is objective.
251
243
 
252
- All communication between stages goes through WORK.md. No stage passes output directly to another all reads and writes go through the `foundry_workfile_*`, `foundry_artefacts_*`, and `foundry_feedback_*` tools. This gives a complete audit trail, makes the process resumable, and means any stage can be re-run independently.
244
+ - **Multi-model diversity**forge on one model, appraise on another, every
245
+ appraiser on a different model if you want. Different models catch different
246
+ mistakes.
253
247
 
254
- ### Feedback as checklist items
248
+ - **Full git audit trail** — one commit per stage with `WORK.md`,
249
+ `WORK.feedback.yaml`, and `WORK.history.yaml`. Every iteration is recorded.
255
250
 
256
- Feedback uses markdown checklists with `#validation` or `#law:<id>` tags. Human-readable, trivially parseable by an LLM, with lifecycle states expressed inline.
251
+ - **Signed attestation on main** every flow finishes with a squash commit carrying
252
+ a canonical Foundry attestation block that proves the artefact was processed.
257
253
 
258
- ### Wont-fix requires appraiser approval
254
+ - **Archived forensic branch** — the raw work branch is retained for auditors as
255
+ `archive/work/<flow>-<desc>-<hash>`. The full micro-history is never lost.
259
256
 
260
- The generator can decline subjective feedback with a justification, but an appraiser must approve or reject that decision. This prevents silently ignoring feedback while allowing legitimate pushback.
257
+ - **Bring your own pipeline** artefact types, laws, and stages are yours; works
258
+ for code, specs, docs, data, and anything else you can describe as files with
259
+ pass/fail criteria.
261
260
 
262
- ### Multi-model stage routing
261
+ - **Assay preflight** — deterministic extractor stage that measures the project
262
+ before forge starts, so codebase-aware flows can begin from structured facts.
263
263
 
264
- Cycle definitions specify which model each stage uses via a `models` map. The `refresh-agents` skill generates `foundry-*` agent files in `.opencode/agents/` from available models. Individual appraisers can override the cycle-level model. Resolution order: appraiser `model` → cycle `models.<stage>` → session default. Multiple personalities catch different issues. Consolidation is union with dedup one appraiser flagging an issue is enough.
264
+ - **Flow memory** typed graph store with scoped tools, semantic search when
265
+ enabled, and committed NDJSON rows for cross-cycle reuse.
265
266
 
266
- ### Input artefacts are read-only
267
+ ---
267
268
 
268
- When a cycle reads from a previous cycle's output, those files cannot be modified. Enforced via git diff after every micro-commit. This prevents downstream cycles from corrupting upstream work.
269
+ ## Further reading
269
270
 
270
- ### Glob patterns must not overlap
271
+ The full reference set lives in [docs/](docs/) — start at [docs/README.md](docs/README.md)
272
+ for a guided index of every document and when to read it.
271
273
 
272
- Two artefact types cannot have file patterns that match the same files. This is checked when creating new types and is a hard block — file modification enforcement can't determine ownership if patterns overlap.
274
+ ---
273
275
 
274
276
  ## License
275
277
 
276
- [MIT](LICENSE)
278
+ MIT.
@@ -0,0 +1,28 @@
1
+ import { selectAppraisers } from '../../../scripts/lib/config.js';
2
+ import { makeIO, branchIoFactory, asyncIoFactory, flowBranchGuard } from './helpers.js';
3
+ import { guarded, notFailedGuard } from '../../../scripts/lib/guards.js';
4
+
5
+ const gateNotFailed = notFailedGuard(makeIO);
6
+
7
+ export function createAppraiserTools({ tool }) {
8
+ return {
9
+ foundry_appraisers_select: tool({
10
+ description: 'Select appraisers for an artefact type',
11
+ args: {
12
+ typeId: tool.schema.string().describe('Artefact type ID'),
13
+ count: tool.schema.number().optional().describe('Number of appraisers to select'),
14
+ },
15
+ // Flow-tier mutation per SPEC §6: appraiser selection mutates the
16
+ // dispatch state of the in-flight cycle. Branch guard runs before
17
+ // failed-flow gate so wrong-branch refusals win over failed-state.
18
+ execute: guarded('foundry_appraisers_select', [flowBranchGuard, gateNotFailed], async (args, context) => {
19
+ const io = makeIO(context.worktree);
20
+ const result = await selectAppraisers('foundry', args.typeId, {
21
+ io,
22
+ countOverride: args.count ?? null,
23
+ });
24
+ return JSON.stringify(result);
25
+ }, { branchIo: branchIoFactory, io: asyncIoFactory }),
26
+ }),
27
+ };
28
+ }
@@ -0,0 +1,58 @@
1
+ import path from 'path';
2
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
3
+ import { requireNoActiveStage } from '../../../scripts/lib/stage-guard.js';
4
+ import { guarded, notFailedGuard } from '../../../scripts/lib/guards.js';
5
+ import { parseArtefactsTable, setArtefactStatus } from '../../../scripts/lib/artefacts.js';
6
+ import { makeIO, branchIoFactory, asyncIoFactory, flowBranchGuard } from './helpers.js';
7
+
8
+ const gateNotFailed = notFailedGuard(makeIO);
9
+
10
+ function makeListTool(tool) {
11
+ return tool({
12
+ description: 'List artefacts from the WORK.md table. Optionally filter by cycle — callers should always pass the current cycle to avoid picking up stale rows from prior sessions.',
13
+ args: {
14
+ cycle: tool.schema.string().optional().describe('Only return rows whose Cycle column matches this value'),
15
+ },
16
+ async execute(args, context) {
17
+ const workPath = path.join(context.worktree, 'WORK.md');
18
+ if (!existsSync(workPath)) {
19
+ return JSON.stringify({ error: 'WORK.md not found' });
20
+ }
21
+ const text = readFileSync(workPath, 'utf-8');
22
+ const rows = parseArtefactsTable(text);
23
+ const filtered = args.cycle ? rows.filter(r => r.cycle === args.cycle) : rows;
24
+ return JSON.stringify(filtered);
25
+ },
26
+ });
27
+ }
28
+
29
+ export function createArtefactTools({ tool }) {
30
+ return {
31
+ // NOTE: `foundry_artefacts_add` was removed in v2.2.0. Artefacts are now
32
+ // registered automatically by the orchestrator's internal finalize step as drafts,
33
+ // then promoted to done|blocked via `foundry_artefacts_set_status`.
34
+ foundry_artefacts_set_status: tool({
35
+ description: 'Update the status of an artefact in WORK.md (done|blocked only)',
36
+ args: {
37
+ file: tool.schema.string().describe('Artefact file path'),
38
+ status: tool.schema.string().describe('New status (done|blocked)'),
39
+ },
40
+ execute: guarded('foundry_artefacts_set_status', [flowBranchGuard, gateNotFailed], async (args, context) => {
41
+ const io = makeIO(context.worktree);
42
+ const guard = requireNoActiveStage(io);
43
+ if (!guard.ok) return JSON.stringify({ error: `foundry_artefacts_set_status ${guard.error}` });
44
+ const workPath = path.join(context.worktree, 'WORK.md');
45
+ const text = readFileSync(workPath, 'utf-8');
46
+ try {
47
+ const updated = setArtefactStatus(text, args.file, args.status);
48
+ writeFileSync(workPath, updated, 'utf-8');
49
+ return JSON.stringify({ ok: true });
50
+ } catch (e) {
51
+ return JSON.stringify({ error: e.message });
52
+ }
53
+ }, { branchIo: branchIoFactory, io: asyncIoFactory }),
54
+ }),
55
+
56
+ foundry_artefacts_list: makeListTool(tool),
57
+ };
58
+ }