@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,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-cycle
|
|
3
|
+
type: atomic
|
|
4
|
+
description: Creates a new foundry cycle within a foundry flow, specifying the output artefact type and any input artefact types.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Add Cycle
|
|
8
|
+
|
|
9
|
+
You help the user create a new foundry cycle and add it to an existing foundry flow. A foundry cycle produces one artefact type (read-write) and optionally reads from artefact types produced by earlier foundry cycles (read-only).
|
|
10
|
+
|
|
11
|
+
## Protocol
|
|
12
|
+
|
|
13
|
+
### 1. Identify the foundry flow
|
|
14
|
+
|
|
15
|
+
From the user's prompt, identify which foundry flow this foundry cycle belongs to. If not specified, list available flows from `foundry/flows/` and ask.
|
|
16
|
+
|
|
17
|
+
Verify the flow exists. If it doesn't, tell the user and ask if they want to create the foundry flow first (separate skill).
|
|
18
|
+
|
|
19
|
+
### 2. Gather basics
|
|
20
|
+
|
|
21
|
+
From the user's prompt, establish:
|
|
22
|
+
- `id` — lowercase, hyphenated identifier for the foundry cycle
|
|
23
|
+
- `name` — human-readable name
|
|
24
|
+
- `output` — the artefact type this foundry cycle produces (must exist in `foundry/artefacts/`)
|
|
25
|
+
- `inputs` — artefact types from earlier foundry cycles that this foundry cycle reads (may be empty)
|
|
26
|
+
- A prose description of what this foundry cycle does
|
|
27
|
+
|
|
28
|
+
If any of these are missing, ask.
|
|
29
|
+
|
|
30
|
+
### 3. Gather model configuration
|
|
31
|
+
|
|
32
|
+
For each stage in the cycle (forge, quench, appraise), ask the user if they want to specify a model:
|
|
33
|
+
|
|
34
|
+
> Each stage can optionally run on a specific model for model diversity. Available models are registered as `foundry-*` agents by the Foundry plugin.
|
|
35
|
+
>
|
|
36
|
+
> For each stage, specify a model ID (e.g., `openai/gpt-4o`) or leave blank to use the session's default model:
|
|
37
|
+
> - forge: ___
|
|
38
|
+
> - quench: ___
|
|
39
|
+
> - appraise: ___
|
|
40
|
+
|
|
41
|
+
Only stages with an explicitly specified model are included in the `models` frontmatter map.
|
|
42
|
+
|
|
43
|
+
### 4. Validate artefact types
|
|
44
|
+
|
|
45
|
+
For `output` and each entry in `inputs`:
|
|
46
|
+
- Verify the artefact type exists in `foundry/artefacts/<type>/definition.md`
|
|
47
|
+
- If it doesn't, tell the user and ask if they want to create it first (separate skill)
|
|
48
|
+
|
|
49
|
+
### 5. Validate against the foundry flow
|
|
50
|
+
|
|
51
|
+
Read the flow definition from `foundry/flows/<flow-id>.md`. Check:
|
|
52
|
+
|
|
53
|
+
- No existing foundry cycle in the foundry flow already outputs the same artefact type. Two foundry cycles producing the same type in one foundry flow is a conflict — the file modification enforcement can't distinguish which foundry cycle owns the files.
|
|
54
|
+
- Each `input` artefact type is produced by an earlier foundry cycle in the foundry flow. If an input references an artefact type that no prior foundry cycle outputs, warn:
|
|
55
|
+
|
|
56
|
+
> Input `<type>` is not produced by any earlier foundry cycle in this foundry flow. The artefact won't exist when this foundry cycle runs.
|
|
57
|
+
>
|
|
58
|
+
> Options:
|
|
59
|
+
> 1. Add a foundry cycle that produces `<type>` before this one
|
|
60
|
+
> 2. Remove `<type>` from inputs (this foundry cycle won't have that context)
|
|
61
|
+
> 3. Proceed anyway (the artefact may exist from a previous foundry flow run)
|
|
62
|
+
|
|
63
|
+
### 6. Check for id conflicts
|
|
64
|
+
|
|
65
|
+
Read all existing cycle definitions in `foundry/cycles/*.md`.
|
|
66
|
+
|
|
67
|
+
- Exact id match → hard conflict, must choose a different id
|
|
68
|
+
|
|
69
|
+
### 7. Check for semantic overlap
|
|
70
|
+
|
|
71
|
+
For foundry cycles already in this foundry flow, check whether the new foundry cycle overlaps in purpose:
|
|
72
|
+
- Does another foundry cycle already transform the same inputs into a similar output?
|
|
73
|
+
- Would the new foundry cycle's description make sense as a revision of an existing foundry cycle rather than a new one?
|
|
74
|
+
|
|
75
|
+
If overlap is found, present it and ask the user to confirm the distinction is real.
|
|
76
|
+
|
|
77
|
+
### 8. Draft the definition
|
|
78
|
+
|
|
79
|
+
Present the foundry cycle definition to the user:
|
|
80
|
+
|
|
81
|
+
```markdown
|
|
82
|
+
---
|
|
83
|
+
id: <id>
|
|
84
|
+
name: <name>
|
|
85
|
+
output: <artefact-type-id>
|
|
86
|
+
inputs:
|
|
87
|
+
- <artefact-type-id>
|
|
88
|
+
models:
|
|
89
|
+
appraise: <model-id> # optional, only if specified
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
# <Name>
|
|
93
|
+
|
|
94
|
+
<description — what this foundry cycle does, what it reads, what it produces>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Ask: does this capture the foundry cycle correctly?
|
|
98
|
+
|
|
99
|
+
### 9. Determine position in foundry flow
|
|
100
|
+
|
|
101
|
+
The foundry cycle needs a position in the foundry flow's ordered cycle list. Based on its inputs:
|
|
102
|
+
- If no inputs: it can go first (or early)
|
|
103
|
+
- If it reads from other foundry cycles: it must come after those foundry cycles
|
|
104
|
+
|
|
105
|
+
Propose a position and confirm with the user:
|
|
106
|
+
|
|
107
|
+
> This foundry cycle reads from `<inputs>`, which are produced by `<cycle-ids>`. It should go after those foundry cycles.
|
|
108
|
+
>
|
|
109
|
+
> Proposed order:
|
|
110
|
+
> 1. <existing-cycle>
|
|
111
|
+
> 2. <existing-cycle>
|
|
112
|
+
> 3. <new-cycle> ← here
|
|
113
|
+
>
|
|
114
|
+
> Does this look right?
|
|
115
|
+
|
|
116
|
+
### 10. Write files
|
|
117
|
+
|
|
118
|
+
- Create `foundry/cycles/<id>.md` with the foundry cycle definition
|
|
119
|
+
- Update `foundry/flows/<flow-id>.md` to add the foundry cycle at the agreed position
|
|
120
|
+
|
|
121
|
+
### 11. Confirm
|
|
122
|
+
|
|
123
|
+
Show the user the created/modified files and their contents.
|
|
124
|
+
|
|
125
|
+
## What you do NOT do
|
|
126
|
+
|
|
127
|
+
- You do not create foundry cycles that output an artefact type already produced by another foundry cycle in the same foundry flow
|
|
128
|
+
- You do not write files without showing the user first
|
|
129
|
+
- You do not skip artefact type validation
|
|
130
|
+
- You do not create artefact types — that is a separate skill
|
|
131
|
+
- You do not create foundry flows — that is a separate skill
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-flow
|
|
3
|
+
type: atomic
|
|
4
|
+
description: Creates a new foundry flow definition.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Add Flow
|
|
8
|
+
|
|
9
|
+
You help the user create a new foundry flow. A foundry flow is an ordered list of foundry cycles that transforms a request into finished artefacts.
|
|
10
|
+
|
|
11
|
+
## Protocol
|
|
12
|
+
|
|
13
|
+
### 1. Gather basics
|
|
14
|
+
|
|
15
|
+
From the user's prompt, establish:
|
|
16
|
+
- `id` — lowercase, hyphenated identifier
|
|
17
|
+
- `name` — human-readable name
|
|
18
|
+
- A prose description of what this foundry flow achieves end-to-end
|
|
19
|
+
|
|
20
|
+
If any of these are missing, ask.
|
|
21
|
+
|
|
22
|
+
### 2. Check for id conflicts
|
|
23
|
+
|
|
24
|
+
Read all existing flow definitions in `foundry/flows/*.md`.
|
|
25
|
+
|
|
26
|
+
- Exact id match → hard conflict, must choose a different id
|
|
27
|
+
- Semantically similar name or description → warn and ask if the new foundry flow is genuinely distinct
|
|
28
|
+
|
|
29
|
+
### 3. Determine foundry cycles
|
|
30
|
+
|
|
31
|
+
Ask the user which foundry cycles this foundry flow should include, in order. List available cycles from `foundry/cycles/*.md` for reference.
|
|
32
|
+
|
|
33
|
+
The user may:
|
|
34
|
+
- Pick from existing foundry cycles
|
|
35
|
+
- Describe foundry cycles that don't exist yet — note these and tell the user they'll need to create them with the add-cycle skill
|
|
36
|
+
|
|
37
|
+
For each selected foundry cycle, verify it exists in `foundry/cycles/`. If it doesn't, note it as pending:
|
|
38
|
+
|
|
39
|
+
> Foundry cycle `<id>` doesn't exist yet. I'll include it in the foundry flow definition, but you'll need to create it before running the foundry flow.
|
|
40
|
+
|
|
41
|
+
### 4. Validate foundry cycle ordering
|
|
42
|
+
|
|
43
|
+
Check that input dependencies are satisfied:
|
|
44
|
+
- For each foundry cycle, its `inputs` must be produced as `output` by an earlier foundry cycle in the list
|
|
45
|
+
|
|
46
|
+
If a dependency is unmet, warn:
|
|
47
|
+
|
|
48
|
+
> Foundry cycle `<cycle-id>` reads from `<type>`, but no earlier foundry cycle produces it. Either reorder or add a foundry cycle that produces `<type>` first.
|
|
49
|
+
|
|
50
|
+
### 5. Draft the definition
|
|
51
|
+
|
|
52
|
+
Present the foundry flow definition to the user:
|
|
53
|
+
|
|
54
|
+
```markdown
|
|
55
|
+
---
|
|
56
|
+
id: <id>
|
|
57
|
+
name: <name>
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
# <Name>
|
|
61
|
+
|
|
62
|
+
<description>
|
|
63
|
+
|
|
64
|
+
## Cycles
|
|
65
|
+
|
|
66
|
+
1. <cycle-id>
|
|
67
|
+
2. <cycle-id>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Ask: does this capture the foundry flow correctly?
|
|
71
|
+
|
|
72
|
+
### 6. Write the file
|
|
73
|
+
|
|
74
|
+
Create `foundry/flows/<id>.md` with the agreed definition.
|
|
75
|
+
|
|
76
|
+
### 7. Confirm
|
|
77
|
+
|
|
78
|
+
Show the user the created file and its contents.
|
|
79
|
+
|
|
80
|
+
## What you do NOT do
|
|
81
|
+
|
|
82
|
+
- You do not create foundry cycles — that is a separate skill
|
|
83
|
+
- You do not write files without showing the user first
|
|
84
|
+
- You do not skip dependency validation
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-law
|
|
3
|
+
type: atomic
|
|
4
|
+
description: Creates a new law, checking for conflicts with existing laws.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Add Law
|
|
8
|
+
|
|
9
|
+
You help the user create a new law. You ensure it's well-scoped, doesn't conflict with existing laws, and ends up in the right file.
|
|
10
|
+
|
|
11
|
+
## Protocol
|
|
12
|
+
|
|
13
|
+
### 1. Determine scope
|
|
14
|
+
|
|
15
|
+
If the user specifies where the law applies:
|
|
16
|
+
- "global law" → goes in `foundry/laws/` (ask which file, or create a new one)
|
|
17
|
+
- "law for X artefacts" → goes in `foundry/artefacts/<type>/laws.md`
|
|
18
|
+
|
|
19
|
+
If the user doesn't specify, ask:
|
|
20
|
+
|
|
21
|
+
> Should this law apply globally to all artefact types, or to a specific type?
|
|
22
|
+
|
|
23
|
+
If they name a type, verify it exists in `foundry/artefacts/`. If it doesn't, tell them and ask if they want to create the artefact type first.
|
|
24
|
+
|
|
25
|
+
### 2. Draft the law
|
|
26
|
+
|
|
27
|
+
Write the law following the standard format:
|
|
28
|
+
|
|
29
|
+
```markdown
|
|
30
|
+
## <law-id>
|
|
31
|
+
|
|
32
|
+
<What this law checks — one or two sentences.>
|
|
33
|
+
|
|
34
|
+
Passing: <What a passing artefact looks like.>
|
|
35
|
+
Failing: <What a failing artefact looks like.>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The `law-id` (heading) should be:
|
|
39
|
+
- Lowercase, hyphenated
|
|
40
|
+
- Short but descriptive
|
|
41
|
+
- Unique across all laws (global and type-specific)
|
|
42
|
+
|
|
43
|
+
### 3. Check for conflicts
|
|
44
|
+
|
|
45
|
+
Read all existing laws that would apply to the same artefact types:
|
|
46
|
+
- All files in `foundry/laws/` (global)
|
|
47
|
+
- `foundry/artefacts/<type>/laws.md` if the law is type-specific
|
|
48
|
+
- If the law is global, also read all `foundry/artefacts/*/laws.md` since a global law applies everywhere
|
|
49
|
+
|
|
50
|
+
For each existing law, check:
|
|
51
|
+
- Does the new law contradict an existing law? (e.g., "must be formal" vs "must be conversational")
|
|
52
|
+
- Does the new law duplicate an existing law? (same criterion, different wording)
|
|
53
|
+
- Does the new law overlap with an existing law? (partially covers the same ground)
|
|
54
|
+
|
|
55
|
+
If any conflict is found, present it to the user:
|
|
56
|
+
|
|
57
|
+
> The new law `<new-id>` may conflict with existing law `<existing-id>`:
|
|
58
|
+
> - New: <summary of new law>
|
|
59
|
+
> - Existing: <summary of existing law>
|
|
60
|
+
> - Conflict: <what the conflict is>
|
|
61
|
+
>
|
|
62
|
+
> Options:
|
|
63
|
+
> 1. Proceed anyway (both laws will apply)
|
|
64
|
+
> 2. Replace the existing law with the new one
|
|
65
|
+
> 3. Rephrase the new law to avoid the conflict
|
|
66
|
+
> 4. Cancel
|
|
67
|
+
|
|
68
|
+
### 4. Refine with the user
|
|
69
|
+
|
|
70
|
+
Present the drafted law to the user before writing it. Ask:
|
|
71
|
+
|
|
72
|
+
> Here's the draft law:
|
|
73
|
+
>
|
|
74
|
+
> ## <law-id>
|
|
75
|
+
>
|
|
76
|
+
> <law content>
|
|
77
|
+
>
|
|
78
|
+
> Does this capture what you want, or should we adjust the wording?
|
|
79
|
+
|
|
80
|
+
Iterate until the user is happy.
|
|
81
|
+
|
|
82
|
+
### 5. Write the law
|
|
83
|
+
|
|
84
|
+
Append the law to the appropriate file:
|
|
85
|
+
- Global: the specified file in `foundry/laws/`, or a new file
|
|
86
|
+
- Type-specific: `foundry/artefacts/<type>/laws.md`
|
|
87
|
+
|
|
88
|
+
If the target file doesn't exist yet, create it with a top-level heading.
|
|
89
|
+
|
|
90
|
+
### 6. Verify uniqueness
|
|
91
|
+
|
|
92
|
+
After writing, confirm the law id is unique. If there's a collision, ask the user to rename.
|
|
93
|
+
|
|
94
|
+
## What you do NOT do
|
|
95
|
+
|
|
96
|
+
- You do not write the law without showing the user first
|
|
97
|
+
- You do not skip the conflict check
|
|
98
|
+
- You do not silently overwrite existing laws
|
|
99
|
+
- You do not create artefact types — that is a separate skill
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: appraise
|
|
3
|
+
type: atomic
|
|
4
|
+
description: Subjective evaluation of an artefact against laws via multiple independent appraisers.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Appraise
|
|
8
|
+
|
|
9
|
+
You orchestrate subjective appraisal of an artefact by dispatching independent sub-agent appraisers, then consolidating their feedback into WORK.md.
|
|
10
|
+
|
|
11
|
+
## Appraiser configuration
|
|
12
|
+
|
|
13
|
+
Appraiser personalities are defined in `foundry/appraisers/` (the appraiser directory). Each markdown file defines:
|
|
14
|
+
- `id` — identifier
|
|
15
|
+
- `model` — (optional) specific model ID to use for this appraiser, overriding the cycle-level appraise model
|
|
16
|
+
|
|
17
|
+
The artefact type definition (`foundry/artefacts/<type>/definition.md`) controls how appraisers are assigned via its `appraisers` frontmatter:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
appraisers:
|
|
21
|
+
count: 3 # how many appraisers (default: 3)
|
|
22
|
+
allowed: [pedantic, pragmatic] # which personalities (default: all available)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Appraiser selection
|
|
26
|
+
|
|
27
|
+
1. Read the `appraisers` config from the artefact type definition
|
|
28
|
+
2. If `allowed` is specified, filter to only those personalities. Otherwise use all in `foundry/appraisers/`.
|
|
29
|
+
3. If `count` is omitted, default to 3
|
|
30
|
+
4. Distribute evenly across available personalities for maximum diversity:
|
|
31
|
+
- 3 appraisers, 3 personalities → 1 of each
|
|
32
|
+
- 6 appraisers, 3 personalities → 2 of each
|
|
33
|
+
- 4 appraisers, 3 personalities → 2, 1, 1 (round-robin)
|
|
34
|
+
5. If count > available personalities, wrap around (same personality, still independent sub-agents)
|
|
35
|
+
|
|
36
|
+
Model diversity is configured at two levels: the cycle definition sets a default model for the appraise stage (which should differ from the forge model), and individual appraisers can optionally override with their own model. If no models are configured, the session's default model is used — personality diversity still adds value but model diversity is lost.
|
|
37
|
+
|
|
38
|
+
## Protocol
|
|
39
|
+
|
|
40
|
+
1. Read `WORK.md` — identify the artefact to appraise and its type
|
|
41
|
+
2. Read all files in `foundry/laws/` — identify global laws
|
|
42
|
+
3. Read `foundry/artefacts/<type>/laws.md` — identify type-specific laws (if it exists)
|
|
43
|
+
4. Read `foundry/artefacts/<type>/definition.md` — for context and appraiser config
|
|
44
|
+
5. Select appraisers (see Appraiser selection above)
|
|
45
|
+
6. Dispatch each appraiser as a sub-agent (see Dispatch below)
|
|
46
|
+
7. Collect results from all appraisers
|
|
47
|
+
8. Consolidate:
|
|
48
|
+
- Union of all issues — if any one appraiser flags it, it's feedback
|
|
49
|
+
- De-duplicate: merge overlapping observations into a single feedback item
|
|
50
|
+
- Preserve which appraiser(s) raised each issue (for traceability)
|
|
51
|
+
9. Write consolidated feedback to WORK.md:
|
|
52
|
+
- `- [ ] <description of the issue> #law:<law-id>`
|
|
53
|
+
10. If no appraiser found any issues, the artefact clears appraisal
|
|
54
|
+
|
|
55
|
+
## Dispatch
|
|
56
|
+
|
|
57
|
+
Each appraiser is dispatched as an independent sub-agent. The sub-agent receives a prompt containing:
|
|
58
|
+
- The appraiser's personality (from their definition file)
|
|
59
|
+
- The artefact content
|
|
60
|
+
- All applicable laws (global + type-specific)
|
|
61
|
+
- Instructions to evaluate the artefact against each law and return issues as a structured list
|
|
62
|
+
|
|
63
|
+
### Model resolution
|
|
64
|
+
|
|
65
|
+
For each appraiser being dispatched, resolve the model in this order:
|
|
66
|
+
1. **Appraiser `model` field** — if the appraiser definition specifies a `model`, use it
|
|
67
|
+
2. **Cycle `models.appraise`** — if the cycle definition specifies a model for the appraise stage, use it (read from WORK.md frontmatter or the cycle definition)
|
|
68
|
+
3. **Default** — use `subagent_type: "general"` (inherits the session's model)
|
|
69
|
+
|
|
70
|
+
If a model is resolved (options 1 or 2), convert it to an agent name: `foundry-<provider-id>-<model-key>` (e.g., `openai/gpt-4o` → `foundry-openai-gpt-4o`). If no agent with that name exists, **hard fail** with an error:
|
|
71
|
+
|
|
72
|
+
> Appraiser `<appraiser-id>` specifies model `<model-id>` but no matching agent `foundry-<agent-name>` is registered. Check your OpenCode provider config.
|
|
73
|
+
|
|
74
|
+
### OpenCode dispatch
|
|
75
|
+
|
|
76
|
+
Use the Task tool to dispatch each appraiser:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Task tool call for each appraiser:
|
|
80
|
+
- subagent_type: "<resolved agent name>" or "general" if no model specified
|
|
81
|
+
- prompt: contains personality, artefact, laws, evaluation instructions
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Dispatch all appraisers in parallel (multiple Task calls in a single response).
|
|
85
|
+
|
|
86
|
+
### Sub-agent prompt template
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
You are an appraiser. Your personality:
|
|
90
|
+
|
|
91
|
+
<contents of foundry/appraisers/<id>.md>
|
|
92
|
+
|
|
93
|
+
Evaluate the following artefact against each law below. For each law, either:
|
|
94
|
+
- Note no issues (pass)
|
|
95
|
+
- Describe the issue, quoting evidence from the artefact
|
|
96
|
+
|
|
97
|
+
## Artefact
|
|
98
|
+
|
|
99
|
+
<artefact content>
|
|
100
|
+
|
|
101
|
+
## Laws
|
|
102
|
+
|
|
103
|
+
<all applicable laws>
|
|
104
|
+
|
|
105
|
+
## Output
|
|
106
|
+
|
|
107
|
+
Return a list of issues. For each issue:
|
|
108
|
+
- law: <law-id>
|
|
109
|
+
- issue: <description>
|
|
110
|
+
- evidence: <quote from artefact>
|
|
111
|
+
|
|
112
|
+
If there are no issues, return an empty list.
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Reviewing actioned and wont-fix feedback
|
|
116
|
+
|
|
117
|
+
On subsequent passes, appraisers also evaluate previously actioned and wont-fix items:
|
|
118
|
+
|
|
119
|
+
- `[x]` actioned items: appraiser checks whether the change actually addresses the issue
|
|
120
|
+
- If yes: mark `| approved`
|
|
121
|
+
- If no: mark `| rejected: <reason>` (item is effectively re-opened)
|
|
122
|
+
- `[~]` wont-fix items: appraiser reads the justification
|
|
123
|
+
- If the justification is sound: mark `| approved`
|
|
124
|
+
- If not: mark `| rejected` (item is effectively re-opened)
|
|
125
|
+
|
|
126
|
+
## History
|
|
127
|
+
|
|
128
|
+
After completing the appraisal consolidation, append an entry to `WORK.history.yaml`:
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
- timestamp: "<ISO 8601 UTC>"
|
|
132
|
+
cycle: <current-cycle-id>
|
|
133
|
+
stage: <alias>
|
|
134
|
+
iteration: <current iteration from history>
|
|
135
|
+
comment: <brief summary, e.g., "3 issues found across 2 appraisers" or "No issues found, cycle complete">
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## What you do NOT do
|
|
139
|
+
|
|
140
|
+
- You do not revise the artefact
|
|
141
|
+
- You do not check deterministic rules — that is the quench skill's job
|
|
142
|
+
- You do not filter out feedback because only one appraiser raised it — one is enough
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cycle
|
|
3
|
+
type: composite
|
|
4
|
+
description: Runs a foundry cycle by delegating all routing to the sort skill.
|
|
5
|
+
composes: [sort, forge, quench, appraise, hitl]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Cycle
|
|
9
|
+
|
|
10
|
+
A foundry cycle reads its definition from `foundry/cycles/<cycle-id>.md`, sets up WORK.md for routing, then hands control to the sort skill which drives the forge → quench → appraise loop.
|
|
11
|
+
|
|
12
|
+
## Cycle definition
|
|
13
|
+
|
|
14
|
+
The cycle definition (`foundry/cycles/<cycle-id>.md`) specifies:
|
|
15
|
+
- `output` — the artefact type this foundry cycle produces (read-write)
|
|
16
|
+
- `inputs` — artefact types from previous foundry cycles that are read-only context
|
|
17
|
+
- `stages` — (optional) explicit stage list with aliases in `base:alias` format (e.g., `[forge:write-haiku, quench:check-syllables, appraise:evaluate-quality]`)
|
|
18
|
+
- `hitl` — (optional) configuration for human-in-the-loop stages, including prompts
|
|
19
|
+
- `models` — (optional) map of stage base names to model IDs for multi-model routing (e.g., `{ appraise: openai/gpt-4o }`). Stages not listed use the session's default model. If a specified model has no matching `foundry-*` agent, the cycle fails with an error.
|
|
20
|
+
|
|
21
|
+
If `stages` is not provided, the cycle skill generates default aliases from the cycle id and artefact type.
|
|
22
|
+
|
|
23
|
+
## Starting a foundry cycle
|
|
24
|
+
|
|
25
|
+
1. Read the cycle definition from `foundry/cycles/<cycle-id>.md`
|
|
26
|
+
2. Read the output artefact type definition from `foundry/artefacts/<type>/definition.md`
|
|
27
|
+
3. Determine the stage route using `base:alias` format:
|
|
28
|
+
- Build the stages list from the cycle definition's `stages` field if present
|
|
29
|
+
- Otherwise, generate defaults: always `forge`, add `quench` if `foundry/artefacts/<type>/validation.md` exists, always `appraise`
|
|
30
|
+
- Cycle definitions can include `hitl` entries in the stages list for human-in-the-loop checkpoints
|
|
31
|
+
- Examples:
|
|
32
|
+
- `[forge:write-haiku, quench:check-syllables, appraise:evaluate-quality]`
|
|
33
|
+
- `[forge:write-petition, appraise:evaluate-petition]`
|
|
34
|
+
- `[forge:draft-proposal, hitl:review-proposal, appraise:evaluate-proposal]`
|
|
35
|
+
4. Update WORK.md frontmatter:
|
|
36
|
+
- Set `cycle` to the cycle id
|
|
37
|
+
- Set `stages` to the determined route (e.g., `[forge:write-haiku, quench:check-syllables, appraise:evaluate-quality]`)
|
|
38
|
+
- Set `max-iterations` (default 3, or from cycle definition if overridden)
|
|
39
|
+
- If the cycle definition has a `models` map, set `models` in WORK.md frontmatter (e.g., `models: { appraise: openai/gpt-4o }`)
|
|
40
|
+
5. Invoke the sort skill
|
|
41
|
+
|
|
42
|
+
## Sort drives everything
|
|
43
|
+
|
|
44
|
+
Once sort is invoked, it runs `scripts/sort.js` to determine the next stage, invokes the corresponding skill, then runs sort again. This repeats until sort returns `done` or `blocked`.
|
|
45
|
+
|
|
46
|
+
The cycle skill does not contain routing logic — sort owns all of that.
|
|
47
|
+
|
|
48
|
+
## Completing a foundry cycle
|
|
49
|
+
|
|
50
|
+
When sort returns `done`:
|
|
51
|
+
- Update the artefact status in WORK.md to `done`
|
|
52
|
+
- Return control to the foundry flow skill
|
|
53
|
+
|
|
54
|
+
When sort returns `blocked`:
|
|
55
|
+
- Update the artefact status in WORK.md to `blocked`
|
|
56
|
+
- Return control to the foundry flow skill (the foundry flow decides how to handle it)
|
|
57
|
+
|
|
58
|
+
## HITL stages
|
|
59
|
+
|
|
60
|
+
Cycle definitions can include `hitl` entries in their stages list to pause for human input. The cycle definition's `hitl:` config section specifies prompts shown to the human at each hitl checkpoint.
|
|
61
|
+
|
|
62
|
+
When sort routes to a `hitl` stage:
|
|
63
|
+
- The hitl skill presents the configured prompt to the human
|
|
64
|
+
- The human provides feedback, which is recorded in WORK.md and WORK.history.yaml
|
|
65
|
+
- Sort then determines the next stage based on the feedback
|
|
66
|
+
|
|
67
|
+
HITL stages follow the same file modification rules as quench/appraise — only WORK.md and WORK.history.yaml may be modified.
|
|
68
|
+
|
|
69
|
+
## Micro commits
|
|
70
|
+
|
|
71
|
+
Every stage must end with a micro commit. Commit message format: `[<cycle-id>] <base>:<alias>: <brief description>`
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
- `[haiku-creation] forge:write-haiku: initial draft`
|
|
75
|
+
- `[haiku-creation] quench:check-syllables: checked syllable pattern`
|
|
76
|
+
- `[haiku-creation] forge:write-haiku: addressed validation feedback`
|
|
77
|
+
- `[haiku-creation] hitl:review-draft: recorded human feedback`
|
|
78
|
+
|
|
79
|
+
## File modification enforcement
|
|
80
|
+
|
|
81
|
+
File modification enforcement is handled automatically by the sort script (`scripts/sort.js`). Before routing to the next stage, sort checks the git diff from the last commit against allowed file patterns:
|
|
82
|
+
|
|
83
|
+
- After forge: output artefact file patterns + WORK.md + WORK.history.yaml
|
|
84
|
+
- After quench/appraise/hitl: only WORK.md + WORK.history.yaml
|
|
85
|
+
- Input artefact files are never allowed (read-only)
|
|
86
|
+
|
|
87
|
+
Sort reads the cycle definition and artefact type definition to determine allowed patterns. If a violation is detected, sort returns `violation` (with details on stderr) and the cycle halts.
|
|
88
|
+
|
|
89
|
+
A violation is a hard stop. The foundry cycle sets artefact status to `blocked` and surfaces the issue to the human.
|
|
90
|
+
|
|
91
|
+
## Feedback states
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
open - [ ] issue #tag → needs generator action
|
|
95
|
+
actioned - [x] issue #tag → needs approval
|
|
96
|
+
wont-fix - [~] issue #tag | wont-fix: <reason> → needs approval (appraisal only)
|
|
97
|
+
approved - [x] issue #tag | approved → resolved
|
|
98
|
+
approved - [~] issue #tag | wont-fix: <reason> | approved → resolved
|
|
99
|
+
rejected - [x] issue #tag | rejected: <reason> → re-opened
|
|
100
|
+
rejected - [~] issue #tag | wont-fix: <reason> | rejected → re-opened
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Tag types: `#validation` (from quench), `#law:<law-id>` (from appraise), `#hitl` (from human) — indicates the source and category of feedback.
|
|
104
|
+
|
|
105
|
+
## What you do NOT do
|
|
106
|
+
|
|
107
|
+
- You do not make routing decisions — sort does that
|
|
108
|
+
- You do not change the laws mid-cycle
|
|
109
|
+
- You do not decide the artefact is "close enough" — it passes or it doesn't
|
|
110
|
+
- You do not proceed past a file modification violation
|
|
111
|
+
- You do not modify input artefacts — they are read-only
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flow
|
|
3
|
+
type: composite
|
|
4
|
+
description: Orchestrates foundry cycles on a work branch, driven by a foundry flow definition.
|
|
5
|
+
composes: [cycle]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Flow
|
|
9
|
+
|
|
10
|
+
A foundry flow reads a flow definition from `foundry/flows/`, creates a work branch, initialises WORK.md, and executes each foundry cycle in sequence.
|
|
11
|
+
|
|
12
|
+
## Starting a foundry flow
|
|
13
|
+
|
|
14
|
+
1. Read the flow definition from `foundry/flows/<flow-id>.md`
|
|
15
|
+
2. Create a branch off main: `work/<flow-id>-<short-description>`
|
|
16
|
+
3. Create `WORK.md` in the root following the spec in `docs/work-spec.md`:
|
|
17
|
+
- Set frontmatter: flow id, first cycle id, first stage
|
|
18
|
+
- Write the goal (from flow definition + human context)
|
|
19
|
+
- Empty artefacts table
|
|
20
|
+
- Empty feedback section
|
|
21
|
+
4. Execute each foundry cycle in order by reading its definition from `foundry/cycles/<cycle-id>.md`
|
|
22
|
+
5. Update the frontmatter cursor as each foundry cycle starts (set `cycle` to the new cycle id)
|
|
23
|
+
6. When all foundry cycles are done, delete WORK.md — the artefacts and git history are the record
|
|
24
|
+
|
|
25
|
+
## Completing a foundry flow
|
|
26
|
+
|
|
27
|
+
When the foundry flow is complete, the branch contains:
|
|
28
|
+
- The finished artefacts
|
|
29
|
+
- The full git history of micro commits showing every stage
|
|
30
|
+
|
|
31
|
+
The human decides whether to merge, open a PR, or discard.
|
|
32
|
+
|
|
33
|
+
## What you do NOT do
|
|
34
|
+
|
|
35
|
+
- You do not skip foundry cycles
|
|
36
|
+
- You do not reorder foundry cycles
|
|
37
|
+
- You do not modify artefacts directly — only foundry cycles modify artefacts
|
|
38
|
+
- You do not delete or rewrite feedback history in WORK.md during the foundry flow
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: forge
|
|
3
|
+
type: atomic
|
|
4
|
+
description: Produces or revises an artefact, guided by WORK.md and the foundry cycle definition.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Forge
|
|
8
|
+
|
|
9
|
+
You produce or revise artefacts. You read WORK.md to understand the goal and feedback, and the foundry cycle definition to understand what you're producing and what inputs you can read.
|
|
10
|
+
|
|
11
|
+
## Protocol
|
|
12
|
+
|
|
13
|
+
### First generation (no artefact registered in WORK.md yet)
|
|
14
|
+
|
|
15
|
+
1. Read `WORK.md` — understand the goal
|
|
16
|
+
2. Read the foundry cycle definition from `foundry/cycles/<cycle-id>.md` — understand what to produce and what inputs are available
|
|
17
|
+
3. Read the output artefact type definition from `foundry/artefacts/<type>/definition.md`
|
|
18
|
+
4. Read all files in `foundry/laws/` for global laws
|
|
19
|
+
5. Read `foundry/artefacts/<type>/laws.md` for type-specific laws (if it exists)
|
|
20
|
+
6. If the foundry cycle has inputs, read the input artefacts (read-only context)
|
|
21
|
+
7. Produce the artefact, respecting all applicable laws from the start
|
|
22
|
+
8. Write the artefact to the location specified in the artefact type definition
|
|
23
|
+
9. Register the artefact in the WORK.md artefacts table (file, type, cycle, status: draft)
|
|
24
|
+
|
|
25
|
+
### Revision (feedback exists in WORK.md)
|
|
26
|
+
|
|
27
|
+
1. Read `WORK.md` — find unresolved feedback items for the artefact
|
|
28
|
+
2. Read the artefact
|
|
29
|
+
3. If the foundry cycle has inputs, read the input artefacts (read-only context)
|
|
30
|
+
4. For each unresolved feedback item, either:
|
|
31
|
+
- Address it and mark as `[x]` (actioned)
|
|
32
|
+
- Mark as `[~]` with justification if you believe the feedback should not be actioned: `- [~] <issue> #law:<id> | wont-fix: <reason>`
|
|
33
|
+
5. Update the artefact file
|
|
34
|
+
6. Wont-fix is only available for `#law:` feedback (subjective appraisal). Validation feedback (`#validation`) must be actioned — deterministic rules are not negotiable.
|
|
35
|
+
|
|
36
|
+
## Unresolved feedback
|
|
37
|
+
|
|
38
|
+
An item is unresolved if it is:
|
|
39
|
+
- `[ ]` — open, not yet addressed
|
|
40
|
+
- `[x] ... | rejected: ...` — actioned but rejected by appraiser, effectively re-opened
|
|
41
|
+
- `[~] ... | rejected` — wont-fix rejected by appraiser, effectively re-opened
|
|
42
|
+
|
|
43
|
+
An item is resolved if it is:
|
|
44
|
+
- `[x] ... | approved`
|
|
45
|
+
- `[~] ... | approved`
|
|
46
|
+
|
|
47
|
+
## History
|
|
48
|
+
|
|
49
|
+
After completing your work (first generation or revision), append an entry to `WORK.history.yaml`:
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
- timestamp: "<ISO 8601 UTC>"
|
|
53
|
+
cycle: <current-cycle-id>
|
|
54
|
+
stage: <alias>
|
|
55
|
+
iteration: <n>
|
|
56
|
+
comment: <brief description of what you did>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The `<alias>` is the full alias received from sort (e.g., `forge:write-haiku`). Use it exactly as given.
|
|
60
|
+
|
|
61
|
+
The iteration number is one more than the count of existing `forge` entries for this cycle in the history.
|
|
62
|
+
|
|
63
|
+
## Feedback tagged `#hitl`
|
|
64
|
+
|
|
65
|
+
Feedback tagged `#hitl` (human-in-the-loop) is treated the same as any other open feedback. Address it or wont-fix it using the same rules as other feedback items.
|
|
66
|
+
|
|
67
|
+
## What you do NOT do
|
|
68
|
+
|
|
69
|
+
- You do not evaluate or score the artefact
|
|
70
|
+
- You do not add feedback — that is the quench skill's and appraise skill's job
|
|
71
|
+
- You do not mark feedback as actioned unless you actually changed the artefact to address it
|
|
72
|
+
- You do not wont-fix validation feedback
|
|
73
|
+
- You do not modify input artefacts — they are read-only
|