@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.
- package/README.md +200 -198
- package/dist/.opencode/plugins/foundry-tools/appraiser-tools.js +28 -0
- package/dist/.opencode/plugins/foundry-tools/artefact-tools.js +58 -0
- package/dist/.opencode/plugins/foundry-tools/assay-tools.js +92 -0
- package/dist/.opencode/plugins/foundry-tools/attestation-tools.js +191 -0
- package/dist/.opencode/plugins/foundry-tools/config-create-tools.js +128 -0
- package/dist/.opencode/plugins/foundry-tools/config-law-tools.js +380 -0
- package/dist/.opencode/plugins/foundry-tools/config-tools.js +43 -0
- package/dist/.opencode/plugins/foundry-tools/feedback-tools.js +234 -0
- package/dist/.opencode/plugins/foundry-tools/git-helpers.js +354 -0
- package/dist/.opencode/plugins/foundry-tools/git-tools.js +181 -0
- package/dist/.opencode/plugins/foundry-tools/helpers.js +340 -0
- package/dist/.opencode/plugins/foundry-tools/history-tools.js +20 -0
- package/dist/.opencode/plugins/foundry-tools/memory-admin-tools.js +296 -0
- package/dist/.opencode/plugins/foundry-tools/memory-helpers.js +104 -0
- package/dist/.opencode/plugins/foundry-tools/memory-tools.js +286 -0
- package/dist/.opencode/plugins/foundry-tools/orchestrate-tool.js +159 -0
- package/dist/.opencode/plugins/foundry-tools/snapshot-tools.js +104 -0
- package/dist/.opencode/plugins/foundry-tools/stage-tools.js +186 -0
- package/dist/.opencode/plugins/foundry-tools/validate-tools.js +263 -0
- package/dist/.opencode/plugins/foundry-tools/workfile-tools.js +102 -0
- package/dist/.opencode/plugins/foundry.js +105 -0
- package/dist/CHANGELOG.md +490 -0
- package/dist/LICENSE +21 -0
- package/dist/README.md +278 -0
- package/dist/docs/README.md +59 -0
- package/dist/docs/architecture.md +434 -0
- package/dist/docs/concepts.md +396 -0
- package/dist/docs/getting-started.md +345 -0
- package/dist/docs/memory-maintenance.md +176 -0
- package/dist/docs/tools.md +1411 -0
- package/dist/docs/work-spec.md +283 -0
- package/dist/scripts/lib/artefacts.js +151 -0
- package/dist/scripts/lib/assay/loader.js +151 -0
- package/dist/scripts/lib/assay/parse-jsonl.js +102 -0
- package/dist/scripts/lib/assay/permissions.js +52 -0
- package/dist/scripts/lib/assay/run.js +219 -0
- package/dist/scripts/lib/assay/spawn-with-timeout.js +138 -0
- package/dist/scripts/lib/attestation/attest.js +111 -0
- package/dist/scripts/lib/attestation/canonical-json.js +109 -0
- package/dist/scripts/lib/attestation/hash.js +17 -0
- package/dist/scripts/lib/attestation/parse.js +14 -0
- package/dist/scripts/lib/attestation/payload.js +106 -0
- package/dist/scripts/lib/attestation/render.js +16 -0
- package/dist/scripts/lib/attestation/verify.js +15 -0
- package/dist/scripts/lib/branch-guard.js +72 -0
- package/dist/scripts/lib/config-creators/appraiser.js +9 -0
- package/dist/scripts/lib/config-creators/artefact-type.js +9 -0
- package/dist/scripts/lib/config-creators/cycle.js +11 -0
- package/dist/scripts/lib/config-creators/factory.js +49 -0
- package/dist/scripts/lib/config-creators/flow.js +11 -0
- package/dist/scripts/lib/config-validators/appraiser.js +49 -0
- package/dist/scripts/lib/config-validators/artefact-type.js +38 -0
- package/dist/scripts/lib/config-validators/cycle.js +131 -0
- package/dist/scripts/lib/config-validators/flow.js +57 -0
- package/dist/scripts/lib/config-validators/helpers.js +96 -0
- package/dist/scripts/lib/config-validators/law.js +96 -0
- package/dist/scripts/lib/config.js +393 -0
- package/dist/scripts/lib/failed-flow.js +131 -0
- package/dist/scripts/lib/feedback-store.js +249 -0
- package/dist/scripts/lib/feedback-transitions.js +105 -0
- package/dist/scripts/lib/finalize.js +70 -0
- package/dist/scripts/lib/foundational-guards.js +13 -0
- package/dist/scripts/lib/git-bridge.js +77 -0
- package/dist/scripts/lib/git-finish/work-finish.js +233 -0
- package/dist/scripts/lib/git-policy.js +101 -0
- package/dist/scripts/lib/guards.js +125 -0
- package/dist/scripts/lib/history.js +132 -0
- package/dist/scripts/lib/memory/admin/create-edge-type.js +91 -0
- package/dist/scripts/lib/memory/admin/create-entity-type.js +43 -0
- package/dist/scripts/lib/memory/admin/create-extractor.js +67 -0
- package/dist/scripts/lib/memory/admin/drop-edge-type.js +40 -0
- package/dist/scripts/lib/memory/admin/drop-entity-type.js +172 -0
- package/dist/scripts/lib/memory/admin/dump.js +47 -0
- package/dist/scripts/lib/memory/admin/helpers.js +31 -0
- package/dist/scripts/lib/memory/admin/init.js +170 -0
- package/dist/scripts/lib/memory/admin/live-store.js +76 -0
- package/dist/scripts/lib/memory/admin/reembed.js +285 -0
- package/dist/scripts/lib/memory/admin/rename-edge-type.js +54 -0
- package/dist/scripts/lib/memory/admin/rename-entity-type.js +151 -0
- package/dist/scripts/lib/memory/admin/reset.js +24 -0
- package/dist/scripts/lib/memory/admin/vacuum.js +9 -0
- package/dist/scripts/lib/memory/admin/validate.js +19 -0
- package/dist/scripts/lib/memory/config.js +149 -0
- package/dist/scripts/lib/memory/cozo.js +136 -0
- package/dist/scripts/lib/memory/drift.js +71 -0
- package/dist/scripts/lib/memory/embeddings.js +128 -0
- package/dist/scripts/lib/memory/frontmatter.js +75 -0
- package/dist/scripts/lib/memory/ndjson.js +84 -0
- package/dist/scripts/lib/memory/paths.js +25 -0
- package/dist/scripts/lib/memory/permissions.js +41 -0
- package/dist/scripts/lib/memory/prompt.js +109 -0
- package/dist/scripts/lib/memory/query.js +56 -0
- package/dist/scripts/lib/memory/reads.js +109 -0
- package/dist/scripts/lib/memory/schema.js +64 -0
- package/dist/scripts/lib/memory/search.js +73 -0
- package/dist/scripts/lib/memory/singleton.js +49 -0
- package/dist/scripts/lib/memory/store.js +162 -0
- package/dist/scripts/lib/memory/types.js +93 -0
- package/dist/scripts/lib/memory/validate.js +58 -0
- package/dist/scripts/lib/memory/writes.js +40 -0
- package/{scripts → dist/scripts}/lib/pending.js +7 -2
- package/dist/scripts/lib/secret.js +59 -0
- package/{scripts → dist/scripts}/lib/slug.js +3 -2
- package/dist/scripts/lib/snapshot/finish.js +103 -0
- package/dist/scripts/lib/snapshot/inspect.js +253 -0
- package/dist/scripts/lib/snapshot/render.js +55 -0
- package/dist/scripts/lib/sort-fs-check.js +121 -0
- package/dist/scripts/lib/sort-routing.js +101 -0
- package/{scripts → dist/scripts}/lib/stage-guard.js +12 -6
- package/{scripts → dist/scripts}/lib/state.js +4 -0
- package/dist/scripts/lib/token.js +57 -0
- package/dist/scripts/lib/tracing.js +59 -0
- package/dist/scripts/lib/ulid.js +100 -0
- package/dist/scripts/lib/validator-jsonl.js +162 -0
- package/{scripts → dist/scripts}/lib/workfile.js +38 -20
- package/dist/scripts/orchestrate-cycle.js +215 -0
- package/dist/scripts/orchestrate-phases.js +314 -0
- package/dist/scripts/orchestrate.js +163 -0
- package/dist/scripts/sort.js +278 -0
- package/{skills → dist/skills}/add-appraiser/SKILL.md +42 -6
- package/{skills → dist/skills}/add-artefact-type/SKILL.md +49 -21
- package/{skills → dist/skills}/add-cycle/SKILL.md +60 -14
- package/dist/skills/add-extractor/SKILL.md +133 -0
- package/{skills → dist/skills}/add-flow/SKILL.md +39 -7
- package/dist/skills/add-law/SKILL.md +191 -0
- package/dist/skills/add-memory-edge-type/SKILL.md +52 -0
- package/dist/skills/add-memory-entity-type/SKILL.md +74 -0
- package/{skills → dist/skills}/appraise/SKILL.md +62 -13
- package/dist/skills/assay/SKILL.md +72 -0
- package/dist/skills/change-embedding-model/SKILL.md +58 -0
- package/dist/skills/drop-memory-edge-type/SKILL.md +54 -0
- package/dist/skills/drop-memory-entity-type/SKILL.md +57 -0
- package/dist/skills/dry-run/SKILL.md +116 -0
- package/{skills → dist/skills}/flow/SKILL.md +15 -2
- package/dist/skills/forge/SKILL.md +121 -0
- package/dist/skills/human-appraise/SKILL.md +153 -0
- package/{skills → dist/skills}/init-foundry/SKILL.md +23 -4
- package/dist/skills/init-memory/SKILL.md +92 -0
- package/{skills → dist/skills}/orchestrate/SKILL.md +30 -4
- package/dist/skills/quench/SKILL.md +99 -0
- package/{skills → dist/skills}/refresh-agents/SKILL.md +1 -1
- package/dist/skills/rename-memory-edge-type/SKILL.md +50 -0
- package/dist/skills/rename-memory-entity-type/SKILL.md +51 -0
- package/dist/skills/reset-memory/SKILL.md +54 -0
- package/dist/skills/upgrade-foundry/SKILL.md +192 -0
- package/package.json +34 -17
- package/.opencode/plugins/foundry.js +0 -761
- package/CHANGELOG.md +0 -90
- package/docs/concepts.md +0 -59
- package/docs/getting-started.md +0 -78
- package/docs/work-spec.md +0 -193
- package/scripts/lib/artefacts.js +0 -124
- package/scripts/lib/config.js +0 -175
- package/scripts/lib/feedback-transitions.js +0 -25
- package/scripts/lib/feedback.js +0 -440
- package/scripts/lib/finalize.js +0 -41
- package/scripts/lib/history.js +0 -59
- package/scripts/lib/secret.js +0 -23
- package/scripts/lib/tags.js +0 -108
- package/scripts/lib/token.js +0 -26
- package/scripts/orchestrate.js +0 -418
- package/scripts/sort.js +0 -370
- package/scripts/validate-tags.js +0 -54
- package/skills/add-law/SKILL.md +0 -105
- package/skills/forge/SKILL.md +0 -88
- package/skills/human-appraise/SKILL.md +0 -82
- package/skills/quench/SKILL.md +0 -62
- package/skills/upgrade-foundry/SKILL.md +0 -216
- /package/{skills → dist/skills}/list-agents/SKILL.md +0 -0
package/README.md
CHANGED
|
@@ -1,276 +1,278 @@
|
|
|
1
1
|
# Foundry
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Engineered confidence for AI-generated work. Define what good looks like.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@really-knows-ai/foundry)
|
|
6
|
+
[](https://github.com/really-knows-ai/foundry/actions/workflows/test.yml)
|
|
7
|
+
[](LICENSE)
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Engineering confidence
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
### Confidence is engineered
|
|
12
14
|
|
|
13
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
53
|
+
- **Appraise** judges quality against written laws. Independent evaluators inspect
|
|
54
|
+
whether the work meets the subjective standards you define.
|
|
57
55
|
|
|
58
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
64
|
+
### What you describe, what Foundry enforces
|
|
72
65
|
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
79
|
+
---
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
## Compatibility
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
-
|
|
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
|
-
|
|
86
|
+
- **OpenCode** — full support. Multi-model routing via file-based `foundry-*` agents.
|
|
87
|
+
This is the primary target platform.
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
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
|
-
|
|
93
|
+
---
|
|
93
94
|
|
|
94
|
-
|
|
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
|
-
|
|
97
|
+
Add the plugin to `opencode.json`:
|
|
100
98
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"$schema": "https://opencode.ai/config.json",
|
|
102
|
+
"plugin": ["@really-knows-ai/foundry"]
|
|
103
|
+
}
|
|
104
|
+
```
|
|
104
105
|
|
|
105
|
-
|
|
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
|
-
|
|
110
|
+
---
|
|
108
111
|
|
|
109
|
-
|
|
112
|
+
## Upgrade
|
|
110
113
|
|
|
111
|
-
|
|
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
|
-
|
|
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
|
-
|
|
118
|
+
---
|
|
120
119
|
|
|
121
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"$schema": "https://opencode.ai/config.json",
|
|
129
|
+
"plugin": ["@really-knows-ai/foundry"]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
140
132
|
|
|
141
|
-
|
|
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
|
-
|
|
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
|
-
|
|
139
|
+
Open OpenCode in your project repo and say:
|
|
149
140
|
|
|
150
|
-
|
|
141
|
+
```
|
|
142
|
+
> run init-foundry
|
|
143
|
+
```
|
|
151
144
|
|
|
152
|
-
|
|
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
|
-
|
|
150
|
+
Restart OpenCode so the new `foundry-<model>` agents register — multi-model dispatch cannot route to agents it cannot discover.
|
|
155
151
|
|
|
156
|
-
|
|
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
|
-
|
|
154
|
+
Ask Foundry to set up a flow:
|
|
165
155
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
169
|
+
```
|
|
170
|
+
> write me a haiku about autumn
|
|
171
|
+
```
|
|
183
172
|
|
|
184
|
-
|
|
173
|
+
Here is what the loop produces:
|
|
185
174
|
|
|
186
175
|
```
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
234
|
+
---
|
|
245
235
|
|
|
246
|
-
|
|
236
|
+
## What's in the box
|
|
247
237
|
|
|
248
|
-
|
|
238
|
+
- **Deterministic governance** — routing, commits, write boundaries, and feedback
|
|
239
|
+
state live in tested plugin code, outside LLM control.
|
|
249
240
|
|
|
250
|
-
|
|
241
|
+
- **Written quality criteria** — laws are markdown files; an appraiser panel scores
|
|
242
|
+
each artefact against them, so quality is objective.
|
|
251
243
|
|
|
252
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
267
|
+
---
|
|
267
268
|
|
|
268
|
-
|
|
269
|
+
## Further reading
|
|
269
270
|
|
|
270
|
-
|
|
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
|
-
|
|
274
|
+
---
|
|
273
275
|
|
|
274
276
|
## License
|
|
275
277
|
|
|
276
|
-
|
|
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
|
+
}
|