@really-knows-ai/foundry 1.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/.opencode/plugins/foundry.js +106 -0
- package/LICENSE +21 -0
- package/README.md +250 -0
- package/docs/concepts.md +55 -0
- package/docs/getting-started.md +78 -0
- package/docs/work-spec.md +193 -0
- package/package.json +44 -0
- package/scripts/lib/tags.js +108 -0
- package/scripts/sort.js +410 -0
- package/scripts/validate-tags.js +54 -0
- package/skills/add-appraiser/SKILL.md +101 -0
- package/skills/add-artefact-type/SKILL.md +147 -0
- package/skills/add-cycle/SKILL.md +131 -0
- package/skills/add-flow/SKILL.md +84 -0
- package/skills/add-law/SKILL.md +99 -0
- package/skills/appraise/SKILL.md +142 -0
- package/skills/cycle/SKILL.md +111 -0
- package/skills/flow/SKILL.md +38 -0
- package/skills/forge/SKILL.md +73 -0
- package/skills/hitl/SKILL.md +65 -0
- package/skills/init-foundry/SKILL.md +51 -0
- package/skills/quench/SKILL.md +55 -0
- package/skills/sort/SKILL.md +77 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foundry plugin for OpenCode.ai
|
|
3
|
+
*
|
|
4
|
+
* Conditional bootstrap:
|
|
5
|
+
* - If foundry/ exists in project: full skill registration + pipeline context
|
|
6
|
+
* - If foundry/ does not exist: only init-foundry skill + minimal prompt
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const packageRoot = path.resolve(__dirname, '../..');
|
|
15
|
+
const allSkillsDir = path.join(packageRoot, 'skills');
|
|
16
|
+
const initSkillDir = path.join(allSkillsDir, 'init-foundry');
|
|
17
|
+
|
|
18
|
+
function getBootstrapContent(directory) {
|
|
19
|
+
const foundryDir = path.join(directory, 'foundry');
|
|
20
|
+
const foundryExists = fs.existsSync(foundryDir) && fs.statSync(foundryDir).isDirectory();
|
|
21
|
+
|
|
22
|
+
if (!foundryExists) {
|
|
23
|
+
return `<FOUNDRY_CONTEXT>
|
|
24
|
+
Foundry is installed but not initialized in this project. There is no foundry/ directory.
|
|
25
|
+
|
|
26
|
+
To set up Foundry, use the \`init-foundry\` skill. This will create the foundry/ directory structure
|
|
27
|
+
and guide you through defining artefact types, laws, appraisers, cycles, and flows.
|
|
28
|
+
</FOUNDRY_CONTEXT>`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return `<FOUNDRY_CONTEXT>
|
|
32
|
+
Foundry is active in this project. The foundry/ directory contains the project's artefact definitions,
|
|
33
|
+
laws, appraisers, cycles, and flows.
|
|
34
|
+
|
|
35
|
+
Foundry is a skill-driven framework for governed artefact generation and evaluation.
|
|
36
|
+
The pipeline: forge (produce) → quench (deterministic checks) → appraise (subjective evaluation) → iterate.
|
|
37
|
+
|
|
38
|
+
Available skills:
|
|
39
|
+
- **Pipeline:** forge, quench, appraise, cycle, flow, sort, hitl
|
|
40
|
+
- **Helpers:** add-artefact-type, add-law, add-appraiser, add-cycle, add-flow, init-foundry
|
|
41
|
+
|
|
42
|
+
Multi-model routing: The Foundry plugin has auto-registered \`foundry-*\` sub-agents for each available model.
|
|
43
|
+
Cycle definitions can specify per-stage models via the \`models\` frontmatter map. Appraisers can override with their own \`model\` field.
|
|
44
|
+
|
|
45
|
+
To start a flow, use the \`flow\` skill. All user content lives under foundry/.
|
|
46
|
+
Scripts are located at: ${path.join(packageRoot, 'scripts')}
|
|
47
|
+
</FOUNDRY_CONTEXT>`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const FoundryPlugin = async ({ client, directory }) => {
|
|
51
|
+
const foundryDir = path.join(directory, 'foundry');
|
|
52
|
+
const foundryExists = fs.existsSync(foundryDir) && fs.statSync(foundryDir).isDirectory();
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
config: async (config) => {
|
|
56
|
+
config.skills = config.skills || {};
|
|
57
|
+
config.skills.paths = config.skills.paths || [];
|
|
58
|
+
|
|
59
|
+
if (foundryExists) {
|
|
60
|
+
if (!config.skills.paths.includes(allSkillsDir)) {
|
|
61
|
+
config.skills.paths.push(allSkillsDir);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Register per-model subagents for multi-model stage routing
|
|
65
|
+
try {
|
|
66
|
+
const providers = await client.provider.list();
|
|
67
|
+
config.agent = config.agent || {};
|
|
68
|
+
for (const provider of providers) {
|
|
69
|
+
if (!provider.models) continue;
|
|
70
|
+
const modelKeys = Array.isArray(provider.models)
|
|
71
|
+
? provider.models
|
|
72
|
+
: Object.keys(provider.models);
|
|
73
|
+
for (const modelKey of modelKeys) {
|
|
74
|
+
const agentName = `foundry-${provider.id}-${modelKey}`;
|
|
75
|
+
config.agent[agentName] = {
|
|
76
|
+
model: `${provider.id}/${modelKey}`,
|
|
77
|
+
mode: 'subagent',
|
|
78
|
+
hidden: true,
|
|
79
|
+
description: `Foundry stage agent using ${provider.id}/${modelKey}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch (err) {
|
|
84
|
+
console.warn('[foundry] Failed to discover models for agent registration:', err.message);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
if (!config.skills.paths.includes(initSkillDir)) {
|
|
88
|
+
config.skills.paths.push(initSkillDir);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
'experimental.chat.messages.transform': async (_input, output) => {
|
|
94
|
+
const bootstrap = getBootstrapContent(directory);
|
|
95
|
+
if (!bootstrap || !output.messages.length) return;
|
|
96
|
+
|
|
97
|
+
const firstUser = output.messages.find(m => m.info.role === 'user');
|
|
98
|
+
if (!firstUser || !firstUser.parts.length) return;
|
|
99
|
+
|
|
100
|
+
if (firstUser.parts.some(p => p.type === 'text' && p.text.includes('FOUNDRY_CONTEXT'))) return;
|
|
101
|
+
|
|
102
|
+
const ref = firstUser.parts[0];
|
|
103
|
+
firstUser.parts.unshift({ ...ref, type: 'text', text: bootstrap });
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
};
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Really Knows AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Foundry
|
|
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.
|
|
4
|
+
|
|
5
|
+
## Compatibility
|
|
6
|
+
|
|
7
|
+
- **OpenCode** — full support, multi-model routing via plugin-registered agents
|
|
8
|
+
|
|
9
|
+
Multi-model support enables model diversity across pipeline stages. The Foundry plugin auto-discovers available models at startup and registers them as hidden sub-agents. Cycle definitions specify which model each stage uses. Tools limited to a single model lose model-diversity but still get personality-based diversity.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Add `@really-knows-ai/foundry` to your OpenCode config:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
// opencode.json
|
|
17
|
+
{
|
|
18
|
+
"packages": {
|
|
19
|
+
"@really-knows-ai/foundry": "latest"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick start
|
|
25
|
+
|
|
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
|
|
34
|
+
|
|
35
|
+
## How it works
|
|
36
|
+
|
|
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
|
+
```
|
|
51
|
+
|
|
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.
|
|
53
|
+
|
|
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.
|
|
55
|
+
|
|
56
|
+
## Core concepts
|
|
57
|
+
|
|
58
|
+
### Foundry Flows
|
|
59
|
+
|
|
60
|
+
Defined in `foundry/flows/`. A flow lists cycles to execute in order. Starting a flow creates a work branch and a fresh `WORK.md`.
|
|
61
|
+
|
|
62
|
+
### Foundry Cycles
|
|
63
|
+
|
|
64
|
+
Defined in `foundry/cycles/`. A cycle specifies:
|
|
65
|
+
- `output` — the artefact type it produces (read-write)
|
|
66
|
+
- `inputs` — artefact types from previous cycles (read-only)
|
|
67
|
+
|
|
68
|
+
### Stages
|
|
69
|
+
|
|
70
|
+
The three steps within a cycle:
|
|
71
|
+
- **Forge** — produce or revise the artefact
|
|
72
|
+
- **Quench** — run deterministic CLI checks (skipped if artefact type has no `validation.md`)
|
|
73
|
+
- **Appraise** — subjective evaluation by multiple independent appraisers
|
|
74
|
+
|
|
75
|
+
### Artefact types
|
|
76
|
+
|
|
77
|
+
Defined in `foundry/artefacts/<type>/`. Each type has:
|
|
78
|
+
- `definition.md` — id, name, file patterns, output directory, appraiser config, prose description
|
|
79
|
+
- `laws.md` (optional) — type-specific subjective criteria
|
|
80
|
+
- `validation.md` (optional) — CLI commands with `{file}` placeholder; non-zero exit = failure
|
|
81
|
+
|
|
82
|
+
### Laws
|
|
83
|
+
|
|
84
|
+
Subjective pass/fail criteria. Two scopes:
|
|
85
|
+
- `foundry/laws/*.md` — global laws, all files concatenated, apply to everything
|
|
86
|
+
- `foundry/artefacts/<type>/laws.md` — type-specific laws
|
|
87
|
+
|
|
88
|
+
Each law is a `## heading` (the identifier, used in feedback tags as `#law:<id>`) with a description, passing criteria, and failing criteria.
|
|
89
|
+
|
|
90
|
+
### Appraisers
|
|
91
|
+
|
|
92
|
+
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`:
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
appraisers:
|
|
96
|
+
count: 3 # how many appraisers (default: 3)
|
|
97
|
+
allowed: [pedantic, pragmatic] # which personalities (default: all available)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
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).
|
|
101
|
+
|
|
102
|
+
### WORK.md
|
|
103
|
+
|
|
104
|
+
Transient shared state on the work branch. Tracks:
|
|
105
|
+
- Current position (flow, cycle, stage) in frontmatter
|
|
106
|
+
- Goal description
|
|
107
|
+
- Artefact registry (what exists, its status)
|
|
108
|
+
- All feedback with full lifecycle
|
|
109
|
+
|
|
110
|
+
### Feedback lifecycle
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
open - [ ] issue #tag → needs generator action
|
|
114
|
+
actioned - [x] issue #tag → needs approval
|
|
115
|
+
wont-fix - [~] issue #tag | wont-fix: <reason> → needs approval
|
|
116
|
+
approved - [x] issue #tag | approved → resolved
|
|
117
|
+
approved - [~] issue #tag | wont-fix: <reason> | approved → resolved
|
|
118
|
+
rejected - [x] issue #tag | rejected: <reason> → re-opened
|
|
119
|
+
rejected - [~] issue #tag | wont-fix: <reason> | rejected → re-opened
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Validation feedback (`#validation`) cannot be wont-fixed — deterministic rules are not negotiable.
|
|
123
|
+
|
|
124
|
+
### File modification enforcement
|
|
125
|
+
|
|
126
|
+
Every stage micro-commits. The cycle checks the git diff:
|
|
127
|
+
- After forge: only output artefact file patterns + WORK.md + WORK.history.yaml (input artefacts are read-only — violation if touched)
|
|
128
|
+
- After quench/appraise: only WORK.md + WORK.history.yaml
|
|
129
|
+
- Violations are hard stops
|
|
130
|
+
|
|
131
|
+
> **Merge hygiene:** WORK.md and WORK.history.yaml are ephemeral working files. Delete them before squash-merging the branch back into main.
|
|
132
|
+
|
|
133
|
+
## Skills
|
|
134
|
+
|
|
135
|
+
Everything is a skill. Skills are either atomic (do one thing) or composite (orchestrate other skills).
|
|
136
|
+
|
|
137
|
+
### Pipeline skills
|
|
138
|
+
|
|
139
|
+
| Skill | Type | Purpose |
|
|
140
|
+
|-------|------|---------|
|
|
141
|
+
| `forge` | atomic | Produce or revise an artefact |
|
|
142
|
+
| `quench` | atomic | Run deterministic CLI checks |
|
|
143
|
+
| `appraise` | atomic | Dispatch multiple appraisers, consolidate feedback |
|
|
144
|
+
| `cycle` | composite | forge → quench → appraise → iterate |
|
|
145
|
+
| `flow` | composite | Orchestrate cycles on a work branch |
|
|
146
|
+
|
|
147
|
+
### Helper skills
|
|
148
|
+
|
|
149
|
+
| Skill | Purpose |
|
|
150
|
+
|-------|---------|
|
|
151
|
+
| `init-foundry` | Scaffold the `foundry/` directory in your project |
|
|
152
|
+
| `add-artefact-type` | Create a new artefact type with conflict and glob-overlap checks |
|
|
153
|
+
| `add-law` | Create a new law with conflict detection |
|
|
154
|
+
| `add-appraiser` | Create a new appraiser personality with semantic overlap checks |
|
|
155
|
+
| `add-cycle` | Create a new cycle within a flow with dependency validation |
|
|
156
|
+
| `add-flow` | Create a new flow definition |
|
|
157
|
+
|
|
158
|
+
### Utility skills
|
|
159
|
+
|
|
160
|
+
| Skill | Purpose |
|
|
161
|
+
|-------|---------|
|
|
162
|
+
| `sort` | Deterministic cycle router — determines and dispatches the next stage |
|
|
163
|
+
| `hitl` | Human-in-the-loop intervention points |
|
|
164
|
+
|
|
165
|
+
All helper skills are interactive — they walk you through the process, check for conflicts, and confirm before writing files.
|
|
166
|
+
|
|
167
|
+
## Package structure
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
@really-knows-ai/foundry
|
|
171
|
+
├── .opencode/
|
|
172
|
+
│ └── plugins/
|
|
173
|
+
│ └── foundry.js # OpenCode plugin (registers skills)
|
|
174
|
+
├── skills/ # skill definitions (the pipeline)
|
|
175
|
+
│ ├── forge/
|
|
176
|
+
│ ├── quench/
|
|
177
|
+
│ ├── appraise/
|
|
178
|
+
│ ├── cycle/
|
|
179
|
+
│ ├── flow/
|
|
180
|
+
│ ├── init-foundry/
|
|
181
|
+
│ ├── add-artefact-type/
|
|
182
|
+
│ ├── add-law/
|
|
183
|
+
│ ├── add-appraiser/
|
|
184
|
+
│ ├── add-cycle/
|
|
185
|
+
│ ├── add-flow/
|
|
186
|
+
│ ├── sort/
|
|
187
|
+
│ └── hitl/
|
|
188
|
+
├── scripts/ # validation support scripts
|
|
189
|
+
├── docs/ # concept docs and specs
|
|
190
|
+
├── package.json
|
|
191
|
+
└── README.md
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## User project structure
|
|
195
|
+
|
|
196
|
+
After running `init-foundry`, your project gets a `foundry/` directory:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
your-project/
|
|
200
|
+
├── foundry/
|
|
201
|
+
│ ├── flows/ # flow definitions
|
|
202
|
+
│ ├── cycles/ # cycle definitions
|
|
203
|
+
│ ├── artefacts/ # artefact type definitions
|
|
204
|
+
│ │ └── <type>/
|
|
205
|
+
│ │ ├── definition.md
|
|
206
|
+
│ │ ├── laws.md # (optional) type-specific laws
|
|
207
|
+
│ │ └── validation.md # (optional) CLI checks
|
|
208
|
+
│ ├── laws/ # global laws
|
|
209
|
+
│ └── appraisers/ # appraiser personalities
|
|
210
|
+
├── opencode.json
|
|
211
|
+
└── ...
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Design decisions
|
|
215
|
+
|
|
216
|
+
### Everything is markdown
|
|
217
|
+
|
|
218
|
+
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.
|
|
219
|
+
|
|
220
|
+
### Skills are the pipeline
|
|
221
|
+
|
|
222
|
+
No separate runner script. 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`. This keeps everything in one format.
|
|
223
|
+
|
|
224
|
+
### WORK.md as shared state
|
|
225
|
+
|
|
226
|
+
All communication between stages goes through WORK.md. No stage passes output directly to another. This gives a complete audit trail, makes the process resumable, and means any stage can be re-run independently.
|
|
227
|
+
|
|
228
|
+
### Feedback as checklist items
|
|
229
|
+
|
|
230
|
+
Feedback uses markdown checklists with `#validation` or `#law:<id>` tags. Human-readable, trivially parseable by an LLM, with lifecycle states expressed inline.
|
|
231
|
+
|
|
232
|
+
### Wont-fix requires appraiser approval
|
|
233
|
+
|
|
234
|
+
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.
|
|
235
|
+
|
|
236
|
+
### Multi-model stage routing
|
|
237
|
+
|
|
238
|
+
Cycle definitions specify which model each stage uses via a `models` map. The Foundry plugin auto-discovers available models and registers them as `foundry-*` sub-agents. 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.
|
|
239
|
+
|
|
240
|
+
### Input artefacts are read-only
|
|
241
|
+
|
|
242
|
+
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.
|
|
243
|
+
|
|
244
|
+
### Glob patterns must not overlap
|
|
245
|
+
|
|
246
|
+
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.
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
[MIT](LICENSE)
|
package/docs/concepts.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Concepts
|
|
2
|
+
|
|
3
|
+
Core concepts and how they relate.
|
|
4
|
+
|
|
5
|
+
## Foundry Flow
|
|
6
|
+
|
|
7
|
+
A foundry flow is the top-level unit of work. It is defined in `foundry/flows/` and lists the foundry cycles to execute in order. Starting a foundry flow creates a work branch and a WORK.md file. A foundry flow is complete when all its foundry cycles are done.
|
|
8
|
+
|
|
9
|
+
## Foundry Cycle
|
|
10
|
+
|
|
11
|
+
A foundry cycle is an iterative loop that produces a single artefact type. It is defined in `foundry/cycles/` and specifies:
|
|
12
|
+
- An output artefact type (read-write)
|
|
13
|
+
- Zero or more input artefact types (read-only, from previous foundry cycles)
|
|
14
|
+
|
|
15
|
+
A foundry cycle runs: forge → quench → appraise, repeating until all feedback is resolved or the iteration limit is hit.
|
|
16
|
+
|
|
17
|
+
## Stage
|
|
18
|
+
|
|
19
|
+
The steps within a foundry cycle. Each stage is referenced using a `base:alias` format (e.g. `forge:write-haiku`) where the base is the stage type and the alias describes its role in that cycle.
|
|
20
|
+
|
|
21
|
+
- Forge — produce or revise the artefact
|
|
22
|
+
- Quench — run deterministic CLI checks
|
|
23
|
+
- Appraise — subjective evaluation by multiple appraisers
|
|
24
|
+
- HITL — human-in-the-loop checkpoint (see below)
|
|
25
|
+
|
|
26
|
+
## Artefact type
|
|
27
|
+
|
|
28
|
+
A definition of what kind of thing is being produced. Lives in `foundry/artefacts/<type>/` with:
|
|
29
|
+
- `definition.md` — identity, file patterns, output location, prose description
|
|
30
|
+
- `laws.md` — type-specific subjective evaluation criteria
|
|
31
|
+
- `validation.md` — CLI commands for deterministic quench checks
|
|
32
|
+
|
|
33
|
+
## Law
|
|
34
|
+
|
|
35
|
+
A subjective pass/fail criterion. Global laws live in `foundry/laws/` (all files concatenated). Type-specific laws live in `foundry/artefacts/<type>/laws.md`. Each law has an identifier (its heading), used in feedback tags.
|
|
36
|
+
|
|
37
|
+
## Appraiser
|
|
38
|
+
|
|
39
|
+
An independent evaluator with a defined personality. Lives in `foundry/appraisers/`. Each appraiser can optionally specify a `model` to override the cycle-level appraise model. Model diversity is configured at the cycle level (via the `models` frontmatter map) and optionally per-appraiser. They can be assigned to specific artefact types or appraise everything.
|
|
40
|
+
|
|
41
|
+
## WORK.md
|
|
42
|
+
|
|
43
|
+
The transient shared state for a foundry flow. Created on the work branch, it tracks: where the foundry flow is (frontmatter cursor), what artefacts exist, and all feedback with its full lifecycle. See [work-spec.md](work-spec.md) for the full spec.
|
|
44
|
+
|
|
45
|
+
## Feedback
|
|
46
|
+
|
|
47
|
+
The communication mechanism between stages. Written as markdown checklist items in WORK.md with tags (`#validation` or `#law:<id>`). Follows a lifecycle: open → actioned/wont-fix → approved/rejected. See [work-spec.md](work-spec.md) for details.
|
|
48
|
+
|
|
49
|
+
## HITL
|
|
50
|
+
|
|
51
|
+
Human-in-the-loop checkpoint. A stage type that pauses the foundry cycle and requests human input before continuing. Configured per cycle by including a `hitl:alias` entry in the `stages` list. When a hitl stage runs, it presents the current artefact state to the human and collects feedback tagged `#hitl`. Like other feedback, hitl feedback follows the standard lifecycle (open → actioned → approved/rejected).
|
|
52
|
+
|
|
53
|
+
## Micro commit
|
|
54
|
+
|
|
55
|
+
Every stage ends with a commit. This enables file modification enforcement — the foundry cycle checks the git diff to ensure each stage only touched files it was allowed to.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
How to set up and run your first foundry flow.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Git repository initialised
|
|
8
|
+
- Node.js available (for validation scripts)
|
|
9
|
+
- An AI coding tool that supports skills (OpenCode, Claude Code, Copilot CLI, etc.)
|
|
10
|
+
|
|
11
|
+
## Step by step
|
|
12
|
+
|
|
13
|
+
### 1. Define an artefact type
|
|
14
|
+
|
|
15
|
+
Create a directory under `foundry/artefacts/` with three files:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
foundry/artefacts/my-type/
|
|
19
|
+
definition.md # what it is, file patterns, output location
|
|
20
|
+
laws.md # subjective laws (optional)
|
|
21
|
+
validation.md # CLI validation commands (optional)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Use the `init-foundry` skill to scaffold the `foundry/` directory, then use `add-artefact-type` to create your first artefact type interactively — or create the directory structure above manually.
|
|
25
|
+
|
|
26
|
+
### 2. Write laws
|
|
27
|
+
|
|
28
|
+
Add global laws to any `.md` file in `foundry/laws/`. Add type-specific laws to `foundry/artefacts/<type>/laws.md`.
|
|
29
|
+
|
|
30
|
+
Each law is a `##` heading with: a description, what passing looks like, and what failing looks like.
|
|
31
|
+
|
|
32
|
+
### 3. Define a foundry cycle
|
|
33
|
+
|
|
34
|
+
Create a file in `foundry/cycles/` that specifies what artefact type the foundry cycle produces and what inputs it reads:
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
---
|
|
38
|
+
id: my-cycle
|
|
39
|
+
name: My Cycle
|
|
40
|
+
output: my-type
|
|
41
|
+
inputs: []
|
|
42
|
+
---
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Cycles list their stages using `base:alias` format — e.g. `forge:write-haiku`, `quench:check-syllables`. The alias makes each stage's purpose clear when reading WORK.md. You can also include `hitl:alias` stages for human-in-the-loop checkpoints.
|
|
46
|
+
|
|
47
|
+
### 4. Define a foundry flow
|
|
48
|
+
|
|
49
|
+
Create a file in `foundry/flows/` that lists foundry cycles in order:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
---
|
|
53
|
+
id: my-flow
|
|
54
|
+
name: My Flow
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
# My Flow
|
|
58
|
+
|
|
59
|
+
Description of what this flow produces.
|
|
60
|
+
|
|
61
|
+
## Cycles
|
|
62
|
+
|
|
63
|
+
1. my-cycle
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 5. Run the foundry flow
|
|
67
|
+
|
|
68
|
+
Tell your AI tool to start the foundry flow. It will create a work branch, initialise WORK.md, and begin executing foundry cycles.
|
|
69
|
+
|
|
70
|
+
## What happens during a foundry flow
|
|
71
|
+
|
|
72
|
+
1. The foundry flow skill creates a branch and WORK.md
|
|
73
|
+
2. For each foundry cycle:
|
|
74
|
+
- Forge produces the artefact
|
|
75
|
+
- Quench runs CLI commands (if defined)
|
|
76
|
+
- Appraise dispatches sub-agent appraisers against the laws
|
|
77
|
+
- If feedback exists, forge revises and the foundry cycle repeats
|
|
78
|
+
3. When all foundry cycles complete, the human decides to merge, PR, or discard
|