@really-knows-ai/foundry 3.4.0 → 3.5.2
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/dist/.opencode/plugins/foundry-tools/artefact-tools.js +32 -43
- package/dist/.opencode/plugins/foundry-tools/attestation-tools.js +9 -2
- package/dist/.opencode/plugins/foundry-tools/config-create-tools.js +2 -2
- package/dist/.opencode/plugins/foundry-tools/orchestrate-tool.js +0 -13
- package/dist/CHANGELOG.md +29 -0
- package/dist/docs/architecture.md +1 -1
- package/dist/docs/tools.md +5 -28
- package/dist/docs/work-spec.md +2 -2
- package/dist/scripts/appraise-module.js +17 -5
- package/dist/scripts/lib/artefacts.js +134 -131
- package/dist/scripts/lib/attestation/attest.js +10 -18
- package/dist/scripts/lib/attestation/payload.js +36 -10
- package/dist/scripts/lib/finalize.js +5 -5
- package/dist/scripts/lib/validation.js +20 -6
- package/dist/scripts/lib/workfile.js +0 -3
- package/dist/scripts/orchestrate-cycle.js +5 -34
- package/dist/scripts/orchestrate-phases.js +63 -40
- package/dist/scripts/orchestrate.js +4 -5
- package/dist/scripts/quench-module.js +29 -20
- package/dist/scripts/sort.js +0 -1
- package/dist/skills/add-cycle/SKILL.md +6 -2
- package/dist/skills/add-flow/SKILL.md +5 -2
- package/dist/skills/appraise/SKILL.md +3 -3
- package/dist/skills/human-appraise/SKILL.md +6 -7
- package/dist/skills/orchestrate/SKILL.md +4 -5
- package/dist/skills/quench/SKILL.md +4 -4
- package/package.json +1 -1
|
@@ -40,6 +40,10 @@ When invoked with pre-filled fields matching the `foundry_config_create_cycle` t
|
|
|
40
40
|
|
|
41
41
|
Context fields: `{id, name, outputType, description, inputs?, targets?, humanAppraise?, deadlockAppraise?, deadlockIterations?, maxIterations?, assay?, memory?, models?}`
|
|
42
42
|
|
|
43
|
+
`inputs` is optional. A source cycle that starts from the user's run goal and has no upstream artefact dependency omits `inputs` entirely. Empty input contracts are invalid: do not pass `inputs: {type: "any-of", artefacts: []}`.
|
|
44
|
+
|
|
45
|
+
`models` is a map of stage names to model IDs. Preserve user-selected model overrides exactly, for example `{forge: "opencode-go/deepseek-v4-flash", appraise: "opencode-go/qwen3.6-plus"}`.
|
|
46
|
+
|
|
43
47
|
When invoked with a context:
|
|
44
48
|
- If all required fields are present, skip the Understand phase and proceed to Plan → Confirm → Build.
|
|
45
49
|
- If only some fields are present, ask only for the missing ones.
|
|
@@ -80,7 +84,7 @@ If the parent flow or required artefact type is missing and the user's goal clea
|
|
|
80
84
|
|
|
81
85
|
**Optional clusters** — After each cluster, ask whether the user wants to configure it; if not, skip:
|
|
82
86
|
|
|
83
|
-
- **Routing**: `inputs` (input contract: `{type: "any-of"|"all-of", artefacts: string[]}
|
|
87
|
+
- **Routing**: `inputs` (input contract: `{type: "any-of"|"all-of", artefacts: string[]}`; omit for source cycles with no upstream artefact dependency), `targets` (cycle IDs to route to after completion), `maxIterations` (maximum iterations before forced progression)
|
|
84
88
|
- **Human-appraise**: `humanAppraise` (boolean, default false) — human reviews every iteration; `deadlockAppraise` (boolean, default true) — human is pulled in when LLM appraisers deadlock; `deadlockIterations` (number, default 5) — deadlock threshold. Only applies when either appraise is enabled.
|
|
85
89
|
- **Memory and models**: `assay` (assay configuration), `memory` (memory configuration), `models` (stage-specific model overrides, e.g. `{forge: "openai/gpt-4o", appraise: "openai/gpt-4o"}`). For models, offer each stage (forge, quench, appraise) individually. If the user has no preference, omit the `models` map and use the session defaults.
|
|
86
90
|
|
|
@@ -98,7 +102,7 @@ Ask: "Proceed with this plan?" — wait for user answer before building. If the
|
|
|
98
102
|
|
|
99
103
|
1. **Validate**: Call `foundry_config_validate_cycle({ name: "<id>", body: "<assembled markdown>" })`. Assemble the body from the fields using the frontmatter format the tool produces internally. If the result is `{ ok: false, errors: [...] }`, address each error and re-run until `{ ok: true }`. Common issues: missing required frontmatter keys, references to artefact types or flows that do not exist yet.
|
|
100
104
|
|
|
101
|
-
2. **Create**: Call `foundry_config_create_cycle({ id: "<id>", name: "<name>", outputType: "<type>", description: "<description>",
|
|
105
|
+
2. **Create**: Call `foundry_config_create_cycle({ id: "<id>", name: "<name>", outputType: "<type>", description: "<description>", targets: ..., humanAppraise: ..., deadlockAppraise: ..., deadlockIterations: ..., maxIterations: ..., assay: ..., memory: ..., models: ... })`. Include `inputs` only when the cycle reads upstream artefacts, and include `models` whenever the user selected stage-specific model overrides. The tool:
|
|
102
106
|
- re-validates the body (TOCTOU);
|
|
103
107
|
- writes `foundry/cycles/<id>.md`;
|
|
104
108
|
- produces one git commit on the current `config/*` branch.
|
|
@@ -69,7 +69,7 @@ Create missing dependencies in validation order:
|
|
|
69
69
|
|
|
70
70
|
3. **Appraisers** (may reference models): For each new appraiser, gather `id`, `name`, `description`, and optional `model` preference. Context object: `{id, name, description, model?}`.
|
|
71
71
|
|
|
72
|
-
4. **Cycles** (reference artefact types, laws, appraisers): For each new cycle, gather `id`, `name`, `outputType`, `description`, and any optional settings (inputs, targets, appraise, assay, memory, models). Context object: `{id, name, outputType, description, inputs?, targets?, humanAppraise?, deadlockAppraise?, deadlockIterations?, maxIterations?, assay?, memory?, models?}`.
|
|
72
|
+
4. **Cycles** (reference artefact types, laws, appraisers): For each new cycle, gather `id`, `name`, `outputType`, `description`, and any optional settings (inputs, targets, appraise, assay, memory, models). Context object: `{id, name, outputType, description, inputs?, targets?, humanAppraise?, deadlockAppraise?, deadlockIterations?, maxIterations?, assay?, memory?, models?}`. For a source cycle that starts from the user's run goal and has no upstream artefact dependency, omit `inputs` entirely; never pass `inputs` with an empty `artefacts` array.
|
|
73
73
|
|
|
74
74
|
For the haiku example, default to a `haiku` artefact type, `haikus/*.md` file pattern, laws for form, imagery, and mood, a deterministic syllable validator where project dependencies allow it, two or three distinct appraisers, one cycle, and one flow.
|
|
75
75
|
|
|
@@ -92,6 +92,7 @@ Flow: <id> — <name>
|
|
|
92
92
|
· <id> — <description>
|
|
93
93
|
Cycles:
|
|
94
94
|
· <id> → <outputType> — <description>
|
|
95
|
+
inputs/models: <omitted or explicit settings>
|
|
95
96
|
```
|
|
96
97
|
|
|
97
98
|
Ask "Proceed with this plan?" — do not build anything until the user confirms.
|
|
@@ -121,9 +122,11 @@ Build order (dependency order):
|
|
|
121
122
|
|
|
122
123
|
4. **Cycles**: For each new cycle, invoke the `add-cycle` protocol with the captured context.
|
|
123
124
|
|
|
124
|
-
> Invoke the add-cycle protocol with context: `{id: "haiku-cycle", name: "Haiku Cycle", outputType: "haiku", description: "Generates haiku poems"}`.
|
|
125
|
+
> Invoke the add-cycle protocol with context: `{id: "haiku-cycle", name: "Haiku Cycle", outputType: "haiku", description: "Generates haiku poems", models: {forge: "opencode-go/deepseek-v4-flash", appraise: "opencode-go/qwen3.6-plus"}}`.
|
|
125
126
|
> If all required fields are present, proceed directly to Build. Otherwise ask for missing required fields only.
|
|
126
127
|
|
|
128
|
+
Preserve every user-selected stage model in the cycle context. If the cycle has no upstream artefact input, leave `inputs` absent from the context.
|
|
129
|
+
|
|
127
130
|
**Build-only mode**: When all required fields for a sub-skill are present in the context, the sub-skill skips Understand, Plan, and Confirm — proceeding directly to validate → create → commit. When only some required fields are present, the sub-skill enters its Understand phase to ask only for those missing required fields, then proceeds to Build (still skipping Plan and Confirm since the parent's combined plan already handled confirmation). Optional fields that are missing are silently skipped.
|
|
128
131
|
|
|
129
132
|
**Error handling during build**: If a sub-skill's Build phase fails (validation error or tool error), surface the error to the user:
|
|
@@ -40,9 +40,9 @@ Appraise makes **no disk writes**. Feedback output flows through `foundry_feedba
|
|
|
40
40
|
> 3. Investigate and fix the root cause of the failure before restarting.
|
|
41
41
|
|
|
42
42
|
Then return control to the user and stop.
|
|
43
|
-
- `foundry_artefacts_list({
|
|
44
|
-
- For each
|
|
45
|
-
- `foundry_config_laws` with the
|
|
43
|
+
- `foundry_artefacts_list({})` — enumerate the current cycle's branch artefact changes as `[{ file, state }]` entries.
|
|
44
|
+
- For each artefact change, gather its type-specific context:
|
|
45
|
+
- `foundry_config_laws` with the cycle's output type — applicable laws (global + type-specific)
|
|
46
46
|
- `foundry_config_artefact_type` with the type ID — the artefact type definition
|
|
47
47
|
- `foundry_appraisers_select` with the type ID — selected appraiser personalities with their raw model IDs
|
|
48
48
|
|
|
@@ -23,7 +23,7 @@ Human-appraise runs inside an enforced stage. Your **first** and **last** tool c
|
|
|
23
23
|
|
|
24
24
|
Human-appraise makes **no disk writes**. All output flows through `foundry_feedback_add` and `foundry_feedback_resolve`. `foundry_stage_end` flags unexpected writes as a violation.
|
|
25
25
|
|
|
26
|
-
Human-appraise **cannot** call `foundry_feedback_action
|
|
26
|
+
Human-appraise **cannot** call `foundry_feedback_action` or `foundry_feedback_wontfix` — the tools reject those calls during a human-appraise stage (action/wontfix are forge-only forward transitions). See "Feedback handling" below for the legal transitions available to human-appraise.
|
|
27
27
|
|
|
28
28
|
## Input
|
|
29
29
|
|
|
@@ -54,7 +54,7 @@ Your LAST tool call must be `foundry_stage_end({summary: '<one-sentence descript
|
|
|
54
54
|
> 3. Investigate and fix the root cause of the failure before restarting.
|
|
55
55
|
|
|
56
56
|
Then call `foundry_stage_end({summary: 'Flow is failed; no human appraisal performed'})`, return control to the user, and stop.
|
|
57
|
-
- `foundry_artefacts_list({
|
|
57
|
+
- `foundry_artefacts_list({})` — this cycle's branch artefact changes as `[{ file, state }]` entries
|
|
58
58
|
- `foundry_feedback_list` — all existing feedback
|
|
59
59
|
- `foundry_history_list({cycle: <current-cycle>})` — what has happened so far
|
|
60
60
|
|
|
@@ -75,7 +75,7 @@ Your LAST tool call must be `foundry_stage_end({summary: '<one-sentence descript
|
|
|
75
75
|
- **Approve** — "looks good" / "continue" — no feedback added, sort will advance.
|
|
76
76
|
- **Provide feedback** — `foundry_feedback_add({ file, text, tag: 'human' })`. Sort will route back to forge.
|
|
77
77
|
- **Resolve feedback** — `foundry_feedback_resolve({ id, resolution, reason? })` for items in `{actioned, wont-fix, deadlocked}`. See "Feedback handling" below for the legal transitions and authority rules.
|
|
78
|
-
- **Abort** — human-appraise cannot directly mark the artefact `blocked` (the
|
|
78
|
+
- **Abort** — human-appraise cannot directly mark the artefact `blocked` (the repository no longer has a per-artefact status tool or table). To abort: end the stage with a summary explaining the abort, then either (a) instruct the user to call `foundry_workfile_delete({ confirm: true })` to discard the cycle, or (b) reject outstanding feedback so routing exhausts iterations and sort blocks the cycle on its own.
|
|
79
79
|
|
|
80
80
|
7. `foundry_stage_end({summary})` — describe what the human decided so sort can log it.
|
|
81
81
|
|
|
@@ -96,10 +96,9 @@ What human-appraise can NOT do:
|
|
|
96
96
|
`{actioned, wont-fix}` — that is forge's lane (spec §5.1 rule 1) and
|
|
97
97
|
the tools reject calls from any non-forge stage. If an open or rejected
|
|
98
98
|
item needs work, sort will route to forge after this stage ends.
|
|
99
|
-
- **No artefact status writes.**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
routing.
|
|
99
|
+
- **No artefact status writes.** The repository no longer has a per-artefact
|
|
100
|
+
status tool or table. Status is owned by the cycle state machine through
|
|
101
|
+
sort and orchestrate routing.
|
|
103
102
|
|
|
104
103
|
What human-appraise CAN do:
|
|
105
104
|
|
|
@@ -87,21 +87,20 @@ When it returns, call `foundry_orchestrate({lastResult: {ok: true}})`.
|
|
|
87
87
|
|
|
88
88
|
Payload: `{cycle, artefact_file, next_cycles}`.
|
|
89
89
|
|
|
90
|
-
1.
|
|
91
|
-
2.
|
|
92
|
-
3. Return control to the flow skill.
|
|
90
|
+
1. Report to the user: "Cycle `<cycle>` complete. Output: `<artefact_file>`. Next cycles available: `<next_cycles>`."
|
|
91
|
+
2. Return control to the flow skill.
|
|
93
92
|
|
|
94
93
|
### `blocked`
|
|
95
94
|
|
|
96
95
|
Payload: `{cycle, artefact_file, reason}`.
|
|
97
96
|
|
|
98
|
-
Report to the user: "Cycle `<cycle>` blocked on `<artefact_file>`: `<reason>`." Return control to the flow skill. The
|
|
97
|
+
Report to the user: "Cycle `<cycle>` blocked on `<artefact_file>`: `<reason>`." Return control to the flow skill. The cycle is blocked.
|
|
99
98
|
|
|
100
99
|
### `violation`
|
|
101
100
|
|
|
102
101
|
Payload: `{details, affected_files}`.
|
|
103
102
|
|
|
104
|
-
Report to the user: "Cycle halted (violation): `<details>`. Affected files: `<affected_files>`." Return control to the flow skill.
|
|
103
|
+
Report to the user: "Cycle halted (violation): `<details>`. Affected files: `<affected_files>`." Return control to the flow skill. The cycle is halted by the violation; no per-artefact status is written.
|
|
105
104
|
|
|
106
105
|
## What you do NOT do
|
|
107
106
|
|
|
@@ -39,14 +39,14 @@ Quench makes **no disk writes**. You produce feedback via `foundry_feedback_add`
|
|
|
39
39
|
> 3. Investigate and fix the root cause of the failure before restarting.
|
|
40
40
|
|
|
41
41
|
Then return control to the user and stop.
|
|
42
|
-
3. `foundry_artefacts_list({
|
|
43
|
-
4. For each
|
|
42
|
+
3. `foundry_artefacts_list({})` — enumerate the current cycle's branch artefact changes as `[{ file, state }]` entries.
|
|
43
|
+
4. For each artefact change:
|
|
44
44
|
a. `foundry_validate_run({ typeId: '<type-id>' })` — executes all law-based validators for the artefact type. The tool returns `{ ok, validatorsRun, items, errors }`. `items` is the array of parsed feedback items; each entry carries `lawId`, `validatorId`, `file`, and `text` (plus optional `location` and `severity`). `errors` carries validator-level failures with `lawId`, `validatorId`, `type` (`parse` or `pattern-mismatch`), and `message`.
|
|
45
45
|
b. For each entry in `items`: call `foundry_feedback_add` with `{ file: item.file, text: item.text, tag: 'law:' + item.lawId + ':' + item.validatorId }`. The tag uses the law ID and validator ID returned by the tool so operators reading `WORK.feedback.yaml` can identify exactly which validator produced each item.
|
|
46
46
|
c. If `errors` is non-empty, the validators themselves misbehaved (malformed JSONL or files outside the artefact type's `file-patterns`). Report these to the user via `foundry_stage_end` summary; do not convert them to law-tagged feedback.
|
|
47
47
|
5. Call `foundry_feedback_list`. For items whose `source` matches your stage id and whose state is `actioned` or `wont-fix`, use the validation results from step 4 to resolve them by id: approve when the relevant validation now passes or the deterministic issue is gone; reject with a reason when it still fails.
|
|
48
|
-
6. If every command passes for every
|
|
49
|
-
7. If the artefact
|
|
48
|
+
6. If every command passes for every artefact change, add no new feedback.
|
|
49
|
+
7. If the artefact list is empty, `foundry_stage_end({summary: 'SKIP: no files'})` and stop.
|
|
50
50
|
8. `foundry_stage_end({summary})`.
|
|
51
51
|
|
|
52
52
|
## Feedback handling
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@really-knows-ai/foundry",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.2",
|
|
4
4
|
"description": "A skill-driven framework for governed artefact generation with AI coding tools. Define your own artefact types, laws, and flows — Foundry handles the forge → quench → appraise pipeline with deterministic routing, quality gates, and iterative refinement.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/.opencode/plugins/foundry.js",
|