@farmslot/skills 0.2.0 → 0.4.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/CHANGELOG.md +9 -0
- package/package.json +2 -2
- package/scripts/run-cooking-lane.cjs +49 -27
- package/skills/recipe-cook/SKILL.md +6 -6
- package/skills/recipe-cook/TASK.md +5 -6
- package/skills/recipe-cook/references/TASK.md +6 -11
- package/skills/recipe-cook/repos/example-browser.md +1 -2
- package/skills/recipe-cook/repos/example-mobile.md +2 -2
- package/skills/recipe-harness/SKILL.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,15 @@ All notable changes to `@farmslot/skills` are tracked here.
|
|
|
6
6
|
|
|
7
7
|
- Active-development baseline; add user-facing changes here before release or package publication.
|
|
8
8
|
|
|
9
|
+
## 0.4.0 - 2026-09-17
|
|
10
|
+
|
|
11
|
+
- Recipe Cook lane: the runner envelope reports `terminal_status` (`done|blocked|failed`) and `terminal_reason`; the lane no longer reads or rewrites a `STATUS:` line in the run-local TASK.md, and `meta.json` records `terminal_reason`. Templates and skill text drop the field. An envelope without a valid `terminal_status`, or a blocked/failed one without `terminal_reason`, fails the run; the model output stays in `runner-output.txt`. The `tmux-model-driver` launcher and watcher stop mentioning or parsing the field.
|
|
12
|
+
|
|
13
|
+
## 0.3.0 - 2026-08-03
|
|
14
|
+
|
|
15
|
+
- Teach recipe authors to start from existing parameterized recipes and compose them node by node before adding new capabilities.
|
|
16
|
+
- Active-development baseline; add user-facing changes here before release or package publication.
|
|
17
|
+
|
|
9
18
|
## 0.2.0 - 2026-07-19
|
|
10
19
|
|
|
11
20
|
- Teach recipe authors to inspect declared actions and reusable flows before creating new capabilities
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farmslot/skills",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"prepublishOnly": "node ../../scripts/quality/check-farmslot-package-readiness.mjs --publish --packages @farmslot/skills"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@farmslot/agent-runtime": "0.
|
|
36
|
+
"@farmslot/agent-runtime": "0.10.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^22.0.0",
|
|
@@ -222,9 +222,7 @@ function resolveRepoLocalContext({ startDir, repoName }) {
|
|
|
222
222
|
const repoRoot = findUp(startDir, (candidate) => {
|
|
223
223
|
if (!fs.existsSync(path.join(candidate, '.git'))) return false;
|
|
224
224
|
if (repoName === 'example-browser') {
|
|
225
|
-
return (
|
|
226
|
-
findFilesByBasename(candidate, ['validate-recipe.js', 'validate-flow-schema.js']).length > 0
|
|
227
|
-
);
|
|
225
|
+
return findFilesByBasename(candidate, ['validate-recipe.js']).length > 0;
|
|
228
226
|
}
|
|
229
227
|
if (repoName === 'example-mobile') {
|
|
230
228
|
return findFilesByBasename(candidate, ['validate-recipe.sh']).length > 0;
|
|
@@ -431,7 +429,9 @@ function buildPrompt({
|
|
|
431
429
|
'',
|
|
432
430
|
'## Required output JSON schema',
|
|
433
431
|
'{',
|
|
434
|
-
' "task_markdown": "full TASK.md content based on the provided template.
|
|
432
|
+
' "task_markdown": "full TASK.md content based on the provided template. Inside ## Validation Evidence include the exact standalone token RECIPE_COOK_VALIDATION_PENDING.",',
|
|
433
|
+
' "terminal_status": "done|blocked|failed",',
|
|
434
|
+
' "terminal_reason": "one sentence naming the concrete blocker or failure; null when done",',
|
|
435
435
|
' "recipe_json": { "valid": "json object" },',
|
|
436
436
|
' "recipe_cook_json": { "valid": "json object" } or null,',
|
|
437
437
|
' "evidence_verdict": "good|ok|bad",',
|
|
@@ -453,7 +453,8 @@ function buildPrompt({
|
|
|
453
453
|
'',
|
|
454
454
|
'The JSON object you return is the final serialized payload for those files.',
|
|
455
455
|
'Emit the JSON last, after you have fully reasoned through:',
|
|
456
|
-
'- the rewritten TASK.md contents
|
|
456
|
+
'- the rewritten TASK.md contents',
|
|
457
|
+
'- the terminal_status (done, blocked, or failed) and, for blocked or failed, its concrete terminal_reason',
|
|
457
458
|
'- the recipe artifact contents',
|
|
458
459
|
'- the learning artifact contents',
|
|
459
460
|
'- what validation commands should run',
|
|
@@ -661,17 +662,11 @@ function discoverValidationSteps({ repoName, repoRoot, recipePath, artifactsDir,
|
|
|
661
662
|
}
|
|
662
663
|
|
|
663
664
|
if (repoName === 'example-browser') {
|
|
664
|
-
const schemaValidator = findFilesByBasename(repoRoot, ['validate-flow-schema.js'])[0];
|
|
665
665
|
const recipeValidator = findFilesByBasename(repoRoot, ['validate-recipe.js'])[0];
|
|
666
|
-
if (!
|
|
666
|
+
if (!recipeValidator) {
|
|
667
667
|
return [];
|
|
668
668
|
}
|
|
669
669
|
const steps = [
|
|
670
|
-
{
|
|
671
|
-
name: 'schema_validation',
|
|
672
|
-
command: ['node', schemaValidator, recipePath],
|
|
673
|
-
cwd: repoRoot,
|
|
674
|
-
},
|
|
675
670
|
{
|
|
676
671
|
name: 'dry_run',
|
|
677
672
|
command: ['node', recipeValidator, '--recipe', recipePath, '--dry-run'],
|
|
@@ -777,26 +772,47 @@ function renderValidationEvidence(validationResults, cdpPort, repoRoot) {
|
|
|
777
772
|
return lines.join('\n');
|
|
778
773
|
}
|
|
779
774
|
|
|
780
|
-
|
|
775
|
+
// Terminal state comes from the runner's explicit envelope field, never from
|
|
776
|
+
// status text in the task markdown. Two evidence-based overrides remain: an
|
|
777
|
+
// UNRESOLVED proof target blocks, and a failed validation step fails.
|
|
778
|
+
function deriveTerminalState(envelope, taskMarkdown, validationResults) {
|
|
781
779
|
const text = String(taskMarkdown || '');
|
|
782
|
-
|
|
783
|
-
|
|
780
|
+
// A reason only travels with a non-done envelope; a note attached to a done
|
|
781
|
+
// envelope must not be presented as the blocker or failure cause. The two
|
|
782
|
+
// evidence overrides below are reachable only for done envelopes, so they
|
|
783
|
+
// synthesize their own reason.
|
|
784
|
+
const reason =
|
|
785
|
+
envelope.terminal_status !== 'done' &&
|
|
786
|
+
typeof envelope.terminal_reason === 'string' &&
|
|
787
|
+
envelope.terminal_reason.trim()
|
|
788
|
+
? envelope.terminal_reason.trim()
|
|
789
|
+
: null;
|
|
790
|
+
if (envelope.terminal_status === 'blocked') {
|
|
791
|
+
return { status: 'blocked', outcome: 'partial', reason };
|
|
784
792
|
}
|
|
785
|
-
if (
|
|
786
|
-
return { status: 'failed', outcome: 'failure' };
|
|
793
|
+
if (envelope.terminal_status === 'failed') {
|
|
794
|
+
return { status: 'failed', outcome: 'failure', reason };
|
|
787
795
|
}
|
|
788
796
|
if (/^\s*[-*]\s+.*:\s*UNRESOLVED\b/m.test(text)) {
|
|
789
|
-
return {
|
|
797
|
+
return {
|
|
798
|
+
status: 'blocked',
|
|
799
|
+
outcome: 'partial',
|
|
800
|
+
reason: 'a required proof target remains UNRESOLVED',
|
|
801
|
+
};
|
|
790
802
|
}
|
|
791
803
|
|
|
792
|
-
const failingStep = Object.
|
|
793
|
-
(result) => result.exit_code !== 0 && result.exit_code !== -1,
|
|
804
|
+
const failingStep = Object.entries(validationResults || {}).find(
|
|
805
|
+
([, result]) => result.exit_code !== 0 && result.exit_code !== -1,
|
|
794
806
|
);
|
|
795
807
|
if (failingStep) {
|
|
796
|
-
return {
|
|
808
|
+
return {
|
|
809
|
+
status: 'failed',
|
|
810
|
+
outcome: 'failure',
|
|
811
|
+
reason: `validation step ${failingStep[0]} exited ${failingStep[1].exit_code}`,
|
|
812
|
+
};
|
|
797
813
|
}
|
|
798
814
|
|
|
799
|
-
return { status: 'done', outcome: 'success' };
|
|
815
|
+
return { status: 'done', outcome: 'success', reason: null };
|
|
800
816
|
}
|
|
801
817
|
|
|
802
818
|
function injectValidationEvidence(taskMarkdown, evidenceBlock) {
|
|
@@ -995,6 +1011,15 @@ async function main() {
|
|
|
995
1011
|
typeof envelope.next_delta === 'string' && envelope.next_delta.trim(),
|
|
996
1012
|
'Runner output missing next_delta',
|
|
997
1013
|
);
|
|
1014
|
+
assert(
|
|
1015
|
+
['done', 'blocked', 'failed'].includes(envelope.terminal_status),
|
|
1016
|
+
`Runner output missing terminal_status (done|blocked|failed). See ${path.join(runDir, 'runner-output.txt')}`,
|
|
1017
|
+
);
|
|
1018
|
+
assert(
|
|
1019
|
+
envelope.terminal_status === 'done' ||
|
|
1020
|
+
(typeof envelope.terminal_reason === 'string' && envelope.terminal_reason.trim()),
|
|
1021
|
+
`Runner output missing terminal_reason for terminal_status ${envelope.terminal_status}. See ${path.join(runDir, 'runner-output.txt')}`,
|
|
1022
|
+
);
|
|
998
1023
|
writeJson(path.join(runDir, 'runner-response.json'), envelope);
|
|
999
1024
|
|
|
1000
1025
|
const recipePath = path.join(artifactsDir, 'recipe.json');
|
|
@@ -1017,11 +1042,7 @@ async function main() {
|
|
|
1017
1042
|
const evidenceBlock = renderValidationEvidence(validationResults, effectiveCdpPort, projectRoot);
|
|
1018
1043
|
const normalizedTask = normalizeTaskArtifactDir(envelope.task_markdown, artifactsDir);
|
|
1019
1044
|
let finalTask = injectValidationEvidence(normalizedTask, evidenceBlock);
|
|
1020
|
-
const terminalState = deriveTerminalState(finalTask, validationResults);
|
|
1021
|
-
finalTask = finalTask.replace(
|
|
1022
|
-
/STATUS:\s*(pending|working|done|blocked|failed)/i,
|
|
1023
|
-
`STATUS: ${terminalState.status}`,
|
|
1024
|
-
);
|
|
1045
|
+
const terminalState = deriveTerminalState(envelope, finalTask, validationResults);
|
|
1025
1046
|
writeFile(path.join(runDir, 'TASK.md'), finalTask);
|
|
1026
1047
|
|
|
1027
1048
|
const verdict = mapVerdict(envelope.evidence_verdict, validationResults);
|
|
@@ -1044,6 +1065,7 @@ async function main() {
|
|
|
1044
1065
|
: terminalState.outcome === 'partial'
|
|
1045
1066
|
? 'blocked'
|
|
1046
1067
|
: 'completed',
|
|
1068
|
+
terminal_reason: terminalState.reason,
|
|
1047
1069
|
});
|
|
1048
1070
|
writeJson(path.join(artifactsDir, 'grade.json'), {
|
|
1049
1071
|
recipe_semantic: verdict,
|
|
@@ -93,7 +93,7 @@ Completion requires:
|
|
|
93
93
|
- unresolved-target audit written
|
|
94
94
|
- validation evidence recorded
|
|
95
95
|
- all required proof targets either `PROVEN` or explicitly non-applicable by contract
|
|
96
|
-
- `
|
|
96
|
+
- `terminal_status: done` in the run envelope; `blocked` and `failed` carry a concrete `terminal_reason`
|
|
97
97
|
|
|
98
98
|
## Hard Rules
|
|
99
99
|
|
|
@@ -101,7 +101,7 @@ Completion requires:
|
|
|
101
101
|
- Do not emit canonical success output if every target is unresolved
|
|
102
102
|
- Do not prefer screenshots when state proof is enough
|
|
103
103
|
- Do not skip screenshots when the claim is visual or review-sensitive
|
|
104
|
-
- Do not rebuild known
|
|
104
|
+
- Do not rebuild known recipes as raw steps when `call` exists
|
|
105
105
|
- Do not stop after printing a recipe or JSON payload if writable artifacts and validation surfaces still exist
|
|
106
106
|
- Do not leave the copied `TASK.md` as the untouched template
|
|
107
107
|
- Do not write `SIGNAL.json` with `complete/success` when a required validation failed or when a required proof target remains `UNRESOLVED`
|
|
@@ -112,14 +112,14 @@ Completion requires:
|
|
|
112
112
|
|
|
113
113
|
| Pitfall | Correct Pattern |
|
|
114
114
|
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
|
|
115
|
-
| Treating cooking as deterministic templating | Treat it as LLM synthesis constrained by repo
|
|
115
|
+
| Treating cooking as deterministic templating | Treat it as LLM synthesis constrained by repo journeys/recipes/evals and honest proof |
|
|
116
116
|
| Using the whole PR description as one target | Extract small executable proof targets |
|
|
117
117
|
| Defaulting every UI claim to screenshots only | choose `visual` or `mixed` deliberately |
|
|
118
118
|
| Defaulting every non-visual claim to a screenshot anyway | prefer state/log/trace proof |
|
|
119
|
-
| Rewriting long repeated setup chains | reuse `call`
|
|
119
|
+
| Rewriting long repeated setup chains | reuse parameterized recipes through `call` |
|
|
120
120
|
| Forcing a canonical recipe when the claim is unresolved | stop or emit only resolved targets with explicit gaps |
|
|
121
121
|
| Treating interactive farmslot execution like chat-only drafting | keep driving the workspace until artifacts + validation evidence exist |
|
|
122
|
-
| Writing recipe artifacts but forgetting the copied `TASK.md` | rewrite the task file and update
|
|
122
|
+
| Writing recipe artifacts but forgetting the copied `TASK.md` | rewrite the task file and update the evidence sections before stopping |
|
|
123
123
|
| Inventing non-canonical runner fields like `timeout` on `wait_for` | use documented runner field names such as `timeout_ms` so live validation honors the intended timing |
|
|
124
124
|
|
|
125
125
|
## Stop Conditions
|
|
@@ -127,7 +127,7 @@ Completion requires:
|
|
|
127
127
|
Stop and report instead of forcing a recipe when:
|
|
128
128
|
|
|
129
129
|
- target text is still too ambiguous to map honestly
|
|
130
|
-
- repo has no viable
|
|
130
|
+
- repo has no viable recipe/eval/native interaction path for the claim
|
|
131
131
|
- current runner context is missing and the missing context changes what should be proven
|
|
132
132
|
- the repo has no validation runner and you already recorded `validation unavailable`
|
|
133
133
|
|
|
@@ -12,7 +12,6 @@ SOURCE_KIND:
|
|
|
12
12
|
SOURCE_REF:
|
|
13
13
|
ARTIFACT_DIR:
|
|
14
14
|
VALIDATION_MODE:
|
|
15
|
-
STATUS: pending
|
|
16
15
|
```
|
|
17
16
|
|
|
18
17
|
## Source Material
|
|
@@ -22,7 +21,7 @@ Paste or summarize:
|
|
|
22
21
|
- PR body
|
|
23
22
|
- linked ticket ACs / expected behavior
|
|
24
23
|
- investigation findings
|
|
25
|
-
- existing
|
|
24
|
+
- existing action / recipe / eval refs
|
|
26
25
|
|
|
27
26
|
## Acceptance Criteria
|
|
28
27
|
|
|
@@ -87,19 +86,19 @@ It must include:
|
|
|
87
86
|
|
|
88
87
|
## Checklist
|
|
89
88
|
|
|
90
|
-
- [ ] **1. Fill the task block** — set `TARGET_REPO`, `SOURCE_KIND`, `SOURCE_REF`, `ARTIFACT_DIR`, `VALIDATION_MODE
|
|
91
|
-
- [ ] **2. Gather the real source of truth** — PR/ticket/investigation text plus existing
|
|
89
|
+
- [ ] **1. Fill the task block** — set `TARGET_REPO`, `SOURCE_KIND`, `SOURCE_REF`, `ARTIFACT_DIR`, `VALIDATION_MODE`.
|
|
90
|
+
- [ ] **2. Gather the real source of truth** — PR/ticket/investigation text plus existing user journeys, recipes, and evals in the target repo.
|
|
92
91
|
- [ ] **3. Enumerate acceptance criteria** — write a numbered canonical list under `## Acceptance Criteria`.
|
|
93
92
|
- [ ] **4. Extract proof targets** — split the work into the smallest executable claims.
|
|
94
93
|
- [ ] **5. Decide proof mode** — choose `state`, `visual`, or `mixed` for every target and justify every `mixed`.
|
|
95
|
-
- [ ] **6. Discover reuse** — list existing
|
|
94
|
+
- [ ] **6. Discover reuse** — list existing actions, recipes, and eval refs before writing new graph steps.
|
|
96
95
|
- [ ] **7. Draft the recipe** — write `artifacts/recipe.json` and, when supported, `artifacts/recipe-cook.json`.
|
|
97
96
|
- [ ] **8. Run schema validation** — if the repo provides a schema validator, run it and record the command + output under `## Validation Evidence`.
|
|
98
97
|
- [ ] **9. Run runner dry-run validation** — if the repo provides a runner, run at least a dry-run and record the command + output.
|
|
99
98
|
- [ ] **10. Handle unavailable validation honestly** — if the repo has no validator or runner, write `validation unavailable` with the reason. Do not fake success.
|
|
100
99
|
- [ ] **11. Write the learning artifact** — write `artifacts/recipe-cook-learning.json` with evidence verdict and proposed next delta.
|
|
101
100
|
- [ ] **12. Audit unresolved targets** — update `## Resolved vs Unresolved` and `## Recipe Coverage Audit` after validation evidence exists.
|
|
102
|
-
- [ ] **13. Final completion gate** —
|
|
101
|
+
- [ ] **13. Final completion gate** — reach the Success outcome only after recipe writing, validation evidence, learning artifact, and unresolved-target audit are all present.
|
|
103
102
|
|
|
104
103
|
## Failure Conditions
|
|
105
104
|
|
|
@@ -11,8 +11,7 @@ Do not edit the template in-place during a cooking run.
|
|
|
11
11
|
Every time you complete a checklist step:
|
|
12
12
|
|
|
13
13
|
1. run `./mark N` if present (1-based); otherwise immediately change `- [ ]` to `- [x]`
|
|
14
|
-
2.
|
|
15
|
-
3. only then move to the next step
|
|
14
|
+
2. only then move to the next step
|
|
16
15
|
|
|
17
16
|
Do not batch checkbox updates.
|
|
18
17
|
Do not leave completed steps unchecked.
|
|
@@ -31,7 +30,6 @@ TASK_DIR: {{TASK_DIR}}
|
|
|
31
30
|
ARTIFACT_DIR: {{ARTIFACT_DIR}}
|
|
32
31
|
SOURCE_BUNDLE_FILE: {{SOURCE_BUNDLE_FILE}}
|
|
33
32
|
VALIDATION_MODE: {{VALIDATION_MODE}}
|
|
34
|
-
STATUS: pending
|
|
35
33
|
```
|
|
36
34
|
|
|
37
35
|
## Source Material
|
|
@@ -43,7 +41,7 @@ Then replace this section with your own summary of:
|
|
|
43
41
|
- PR body
|
|
44
42
|
- linked ticket ACs / expected behavior
|
|
45
43
|
- investigation findings
|
|
46
|
-
- existing
|
|
44
|
+
- existing action / recipe / eval refs
|
|
47
45
|
|
|
48
46
|
## Acceptance Criteria
|
|
49
47
|
|
|
@@ -110,12 +108,12 @@ It must include:
|
|
|
110
108
|
|
|
111
109
|
## Checklist
|
|
112
110
|
|
|
113
|
-
- [ ] **1. Fill the task block** — set `TARGET_REPO`, `SOURCE_KIND`, `SOURCE_REF`, `ARTIFACT_DIR`, `VALIDATION_MODE
|
|
114
|
-
- [ ] **2. Gather the real source of truth** — PR/ticket/investigation text plus existing
|
|
111
|
+
- [ ] **1. Fill the task block** — set `TARGET_REPO`, `SOURCE_KIND`, `SOURCE_REF`, `ARTIFACT_DIR`, `VALIDATION_MODE`.
|
|
112
|
+
- [ ] **2. Gather the real source of truth** — PR/ticket/investigation text plus existing user journeys, recipes, and evals in the target repo.
|
|
115
113
|
- [ ] **3. Enumerate acceptance criteria** — write a numbered canonical list under `## Acceptance Criteria`.
|
|
116
114
|
- [ ] **4. Extract proof targets** — split the work into the smallest executable claims.
|
|
117
115
|
- [ ] **5. Decide proof mode** — choose `state`, `visual`, or `mixed` for every target and justify every `mixed`.
|
|
118
|
-
- [ ] **6. Discover reuse** — list existing
|
|
116
|
+
- [ ] **6. Discover reuse** — list existing actions, recipes, and eval refs before writing new graph steps.
|
|
119
117
|
- [ ] **7. Draft the recipe** — write `artifacts/recipe.json` and, when supported, `artifacts/recipe-cook.json`. Use documented runner field names for nodes (for example `timeout_ms` / `poll_ms` on `wait_for`), not guessed aliases.
|
|
120
118
|
- [ ] **8. Rewrite this copied TASK file** — replace the template placeholders with the real run data and working notes. Leaving the untouched template is a failure.
|
|
121
119
|
- [ ] **9. Run schema validation** — if the repo provides a schema validator, run it and record the command + output under `## Validation Evidence`.
|
|
@@ -124,7 +122,7 @@ It must include:
|
|
|
124
122
|
- [ ] **12. Handle unavailable validation honestly** — if the repo has no validator or runner, write `validation unavailable` with the reason. Do not fake success.
|
|
125
123
|
- [ ] **13. Write the learning artifact** — write `artifacts/recipe-cook-learning.json` with evidence verdict and proposed next delta.
|
|
126
124
|
- [ ] **14. Audit unresolved targets** — update `## Resolved vs Unresolved` and `## Recipe Coverage Audit` after validation evidence exists.
|
|
127
|
-
- [ ] **15. Final completion gate** —
|
|
125
|
+
- [ ] **15. Final completion gate** — reach the Success outcome only after recipe writing, rewritten TASK.md, validation evidence, learning artifact, and unresolved-target audit are all present.
|
|
128
126
|
- [ ] **16. Write terminal signal** — write exactly one terminal `SIGNAL.json` based on the outcome matrix below.
|
|
129
127
|
|
|
130
128
|
## Outcome Matrix
|
|
@@ -134,7 +132,6 @@ Write `SIGNAL.json` only after step 15 is evaluated.
|
|
|
134
132
|
- **Success**:
|
|
135
133
|
- every required validation passed or was explicitly non-applicable by contract
|
|
136
134
|
- no required proof target remains `UNRESOLVED`
|
|
137
|
-
- `STATUS: done`
|
|
138
135
|
- signal:
|
|
139
136
|
```json
|
|
140
137
|
{ "status": "complete", "outcome": "success" }
|
|
@@ -143,7 +140,6 @@ Write `SIGNAL.json` only after step 15 is evaluated.
|
|
|
143
140
|
- **Blocked**:
|
|
144
141
|
- a concrete environment/runtime/tooling blocker prevented required validation
|
|
145
142
|
- or a proof target remains `UNRESOLVED` because a required live/runtime dependency was unavailable
|
|
146
|
-
- `STATUS: blocked`
|
|
147
143
|
- signal:
|
|
148
144
|
```json
|
|
149
145
|
{ "status": "blocked", "outcome": "partial", "reason": "<concrete blocker>" }
|
|
@@ -152,7 +148,6 @@ Write `SIGNAL.json` only after step 15 is evaluated.
|
|
|
152
148
|
- **Failed**:
|
|
153
149
|
- a required validation actually ran and failed
|
|
154
150
|
- or the recipe/proof contradicts the PR claim
|
|
155
|
-
- `STATUS: failed`
|
|
156
151
|
- signal:
|
|
157
152
|
```json
|
|
158
153
|
{ "status": "failed", "outcome": "failure", "reason": "<concrete failure>" }
|
|
@@ -12,7 +12,7 @@ Use this overlay when the target project is a browser or web app and has no more
|
|
|
12
12
|
Start with:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
rg --files | rg 'recipes?/.*\\.json$|
|
|
15
|
+
rg --files | rg 'recipes?/.*\\.json$|validate-recipe\\.(js|mjs|cjs|ts)|playwright|cypress|vitest|agentic-toolkit\\.md'
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Then inspect package scripts for existing validation surfaces:
|
|
@@ -37,7 +37,6 @@ Look for:
|
|
|
37
37
|
Use repo-local commands first. Common shapes include:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
node <validate-flow-schema.js> <recipe.json>
|
|
41
40
|
node <validate-recipe.js> --recipe <recipe.json> --dry-run
|
|
42
41
|
npm test -- --runInBand
|
|
43
42
|
```
|
|
@@ -12,7 +12,7 @@ Use this overlay when the target project is a mobile app and has no more specifi
|
|
|
12
12
|
Start with:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
rg --files | rg 'recipes?/.*\\.json$|
|
|
15
|
+
rg --files | rg 'recipes?/.*\\.json$|validate-recipe\\.(sh|js|mjs|cjs|ts)|detox|maestro|appium|testIds?|accessibility|agentic-toolkit\\.md'
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Then inspect package scripts for local test and validation commands:
|
|
@@ -23,7 +23,7 @@ node -e "const p=require('./package.json'); console.log(p.scripts || {})"
|
|
|
23
23
|
|
|
24
24
|
## Cooking Rules
|
|
25
25
|
|
|
26
|
-
- Prefer stable accessibility labels, test IDs, or existing mobile
|
|
26
|
+
- Prefer stable accessibility labels, test IDs, or existing mobile automation when it exists.
|
|
27
27
|
- Keep proof targets separate from platform mechanics.
|
|
28
28
|
- Do not import web-only selectors or desktop assumptions into mobile recipes.
|
|
29
29
|
- If mobile lacks a repo-owned helper, write a recipe and proof plan, then mark live validation unavailable with the concrete blocker.
|
|
@@ -16,7 +16,7 @@ Use the local recipe runtime when one exists, or recommend the smallest install
|
|
|
16
16
|
|
|
17
17
|
1. Find the project-owned recipe command first.
|
|
18
18
|
2. If no command exists, check for `@farmslot/recipe-harness` or an app-specific harness package.
|
|
19
|
-
3. Before authoring, inspect
|
|
19
|
+
3. Before authoring, inspect the closest recipes with `farmslot-recipe run --list` and `farmslot-recipe run <id> --describe`, then inspect declared actions only if no recipe fits. Prefer project discovery commands; otherwise read only the relevant manifest entries and examples.
|
|
20
20
|
4. Run dry-run or schema validation before live execution when available.
|
|
21
21
|
5. Record artifact paths and validation output.
|
|
22
22
|
6. If no runner exists, stop with a concrete install recommendation.
|
|
@@ -25,7 +25,7 @@ Use the local recipe runtime when one exists, or recommend the smallest install
|
|
|
25
25
|
|
|
26
26
|
- Do not invent runner commands.
|
|
27
27
|
- Do not require Farmslot Gateway, pool files, slots, Command Center, or Companion for first use.
|
|
28
|
-
- Do not bypass project fixtures or user-
|
|
28
|
+
- Do not bypass project fixtures or user-journey validation by directly mutating app state.
|
|
29
29
|
|
|
30
30
|
## Output
|
|
31
31
|
|