-
Notifications
You must be signed in to change notification settings - Fork 4.6k
feat: add validation gate and lesson retrieval to propose skill #1688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,7 +44,19 @@ ${STORE_SELECTION_GUIDANCE} | |
|
|
||
| If the request contains ambiguity that would materially affect scope, externally observable behavior, compatibility, or acceptance criteria, ask the user before creating the change. For minor details, make a reasonable assumption and record it in the planning artifacts. | ||
|
|
||
| 2. **Determine the workflow schema** | ||
| 2. **Load prior lessons** | ||
|
|
||
| <!-- LOCAL PATCH (iwe-lesson-retrieval): re-apply after openspec upgrades that regenerate skills --> | ||
|
|
||
| Before creating artifacts, retrieve the repo's prior lessons for this topic: run | ||
| \`iwe find --lexical "<topic>" --limit 5 --add-fields 'body=$content' --max-document-tokens 400\` | ||
| over \`docs/retros/\` and fold the surfaced lessons (titles/paths + capped content) into the | ||
| proposal context. When \`iwe\` is absent OR fails on the host (e.g. a projection/quoting | ||
| error), fall back to \`rg -l -i "<topic>" docs/retros\` and NOTE the fallback: report | ||
| the iwe error and the fallback in your summary — never fall back silently (2026-08-17 | ||
|
Comment on lines
+51
to
+56
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win Do not interpolate raw A user-controlled topic can contain
📍 Affects 1 file
🤖 Prompt for AI Agents
Comment on lines
+54
to
+56
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Read fallback lesson files before building proposal context.
📍 Affects 1 file
🤖 Prompt for AI Agents |
||
| lesson: a silent fallback hides retrieval-pipeline health from the human). | ||
|
|
||
| 3. **Determine the workflow schema** | ||
|
|
||
| Use the configured default schema unless the user explicitly requests a different workflow. | ||
|
|
||
|
|
@@ -54,7 +66,7 @@ ${STORE_SELECTION_GUIDANCE} | |
|
|
||
| Otherwise, omit \`--schema\` to preserve the configured default. | ||
|
|
||
| 3. **Create the change directory** | ||
| 4. **Create the change directory** | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Complete the step renumbering. In the skill template, “Get the artifact build order” still uses step 4 and artifact creation still uses step 5. The validation and final-status labels must shift accordingly. In the command template, line 354 refers to step 6, but the validation gate is step 7.
📍 Affects 1 file
🤖 Prompt for AI Agents |
||
|
|
||
| Choose one schema form below. If a registered store is selected, append \`--store "<store-id>"\` to that command and each later OpenSpec command shown below that accepts \`--store\`. | ||
|
|
||
|
|
@@ -117,7 +129,23 @@ ${STORE_SELECTION_GUIDANCE} | |
| - Ask the user to clarify | ||
| - Then continue with creation | ||
|
|
||
| 6. **Show final status** | ||
| 6. **Run the validation and coherence gate** — do NOT claim the artifacts are ready until this step is green | ||
| <!-- LOCAL PATCH (proposal-validation-gate): re-apply after openspec upgrades that regenerate skills --> | ||
| a. **Change-scoped validation gate.** Run: | ||
| \`\`\`bash | ||
| openspec validate "<name>" --type change --strict --json --no-interactive | ||
| \`\`\` | ||
| (append \`--store "<id>"\` when a store is selected. The item name is positional — \`validate\` has NO \`--change\` flag. \`--no-interactive\` is required so an agent-driven run can't hang on an interactive prompt — upstream Fission-AI/OpenSpec#492.) | ||
| - Parse the JSON: the change passes when the item reports \`"valid": true\` (equivalently \`summary.totals.failed === 0\`). On failure, fix the reported issues in the artifacts and re-run before proceeding. | ||
| - \`openspec validate --all\` is informational only — an unrelated failing change elsewhere must NOT block this proposal's summary. | ||
| b. **Deterministic coherence gate.** Run, and re-run until it exits 0: | ||
| \`\`\`bash | ||
| bun scripts/check-proposal-coherence.ts "<name>" | ||
| \`\`\` | ||
| The checker verifies mechanically: every \`file:line\` anchor cited in design/tasks resolves against the real file; every grep/regression-guard string in tasks matches the prescribed phrasing verbatim; delta-spec requirement names do not collide with the main spec; every deliverable named in proposal.md (What Changes/Impact) has a delivering task or is declared a non-goal. Fix any violation in the artifacts, then re-run. | ||
|
Comment on lines
+141
to
+145
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
fd -a '^check-proposal-coherence\.ts$' . | while IFS= read -r file; do
ast-grep outline "$file" --items all
rg -n -C 5 'process\.argv|--store|planningHome|changeRoot|openspec context' "$file"
doneRepository: Fission-AI/OpenSpec Length of output: 157 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(propose\.ts|check-proposal-coherence\.ts|proposal-coherence|root-selection|store|context)' | head -200
printf '%s\n' '--- proposal references ---'
rg -n -C 8 'check-proposal-coherence|STORE_SELECTION|--store|selected store|change root|changeRoot|planningHome' src/core/templates/workflows/propose.ts src scripts docs 2>/dev/null | head -300
printf '%s\n' '--- propose outline ---'
ast-grep outline src/core/templates/workflows/propose.ts --items allRepository: Fission-AI/OpenSpec Length of output: 37064 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- script files and package commands ---'
git ls-files | rg '(^|/)(scripts/|package\.json$|bun\.lockb?$|package-lock\.json$|yarn\.lock$|pnpm-lock\.yaml$)' | head -300
rg -n -C 3 'coherence|check-proposal|proposal coherence|bun scripts/' . \
-g '!openspec/**' -g '!node_modules/**' -g '!dist/**' -g '!build/**' | head -300
printf '%s\n' '--- physical candidate files ---'
find . -type f \( -name '*coherence*' -o -name 'check-proposal-coherence.ts' \) -print
printf '%s\n' '--- store guidance ---'
cat -n src/core/templates/workflows/store-selection.ts | sed -n '1,180p'
printf '%s\n' '--- reported template blocks ---'
cat -n src/core/templates/workflows/propose.ts | sed -n '125,151p;304,330p'Repository: Fission-AI/OpenSpec Length of output: 20278 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- verify workflow and command implementation ---'
git ls-files | rg '(^|/)(verify|commands|workflows)' | head -250
rg -n -C 6 'getOpsxVerify|/opsx:verify|verify.*workflow|coherence|proposal' \
src/core/templates src/commands src/cli package.json docs/commands.md 2>/dev/null | head -400
printf '%s\n' '--- package scripts ---'
node -e '
const p = JSON.parse(require("fs").readFileSync("package.json", "utf8"));
console.log(JSON.stringify(p.scripts ?? {}, null, 2));
'
printf '%s\n' '--- all references to the missing path ---'
rg -n -F 'scripts/check-proposal-coherence.ts' . --hidden \
-g '!node_modules/**' -g '!dist/**' -g '!build/**'Repository: Fission-AI/OpenSpec Length of output: 33041 Add the coherence checker or remove the mandatory gate. Both proposal templates invoke 📍 Affects 1 file
🤖 Prompt for AI Agents |
||
| c. Only after both gates are green, proceed to the final status step. \`status: "done"\` (or an artifact showing \`done\`) means the FILE exists — it does NOT mean the artifact is correct; this step is the mechanical correctness check, and the depth-pass review remains the semantic check for high-stakes changes (see Output). | ||
|
|
||
| 7. **Show final status** | ||
| \`\`\`bash | ||
| openspec status --change "<name>" | ||
| \`\`\` | ||
|
|
@@ -127,6 +155,7 @@ ${STORE_SELECTION_GUIDANCE} | |
| After completing all artifacts, summarize: | ||
| - Change name and location | ||
| - List of artifacts created with brief descriptions, plus any conditional artifact you skipped and why | ||
| - Gate result: state that the proposal passed \`openspec validate --strict\` (change-scoped) and the coherence checker (\`bun scripts/check-proposal-coherence.ts\`) | ||
| - What's ready: "All artifacts needed for implementation are ready." | ||
| - Prompt: "The artifacts are ready for review. When you are ready, run \`/opsx:apply\` or ask me to apply this change." | ||
|
|
||
|
|
@@ -143,6 +172,7 @@ After completing all artifacts, summarize: | |
|
|
||
| **Guardrails** | ||
| - The request that invoked this workflow authorizes planning only. Any implementation or apply instruction in that request does not carry forward. Do NOT implement the change, start the apply workflow, or edit project code during this workflow. After presenting the artifacts, stop and wait for a new user request to start the apply workflow | ||
| - \`status: "done"\` on an artifact means the FILE exists, NOT that it is correct — the validation + coherence gate (step 6) is the mechanical correctness check and MUST be green before presenting the "ready for review" summary. The depth-pass review remains the semantic check for high-stakes changes | ||
| - Create every artifact the apply phase transitively depends on, not just the ids listed in \`apply.requires\` | ||
| - Always read dependency artifacts before creating a new one - re-read from disk, not from conversation memory (files may have changed since you last saw them) | ||
| - Ask about ambiguities that would materially change scope, externally observable behavior, compatibility, or acceptance criteria; for minor details, make reasonable assumptions and record them | ||
|
|
@@ -193,7 +223,19 @@ ${STORE_SELECTION_GUIDANCE} | |
|
|
||
| If the request contains ambiguity that would materially affect scope, externally observable behavior, compatibility, or acceptance criteria, ask the user before creating the change. For minor details, make a reasonable assumption and record it in the planning artifacts. | ||
|
|
||
| 2. **Determine the workflow schema** | ||
| 2. **Load prior lessons** | ||
|
|
||
| <!-- LOCAL PATCH (iwe-lesson-retrieval): re-apply after openspec upgrades that regenerate skills --> | ||
|
|
||
| Before creating artifacts, retrieve the repo's prior lessons for this topic: run | ||
| \`iwe find --lexical "<topic>" --limit 5 --add-fields 'body=$content' --max-document-tokens 400\` | ||
| over \`docs/retros/\` and fold the surfaced lessons (titles/paths + capped content) into the | ||
| proposal context. When \`iwe\` is absent OR fails on the host (e.g. a projection/quoting | ||
| error), fall back to \`rg -l -i "<topic>" docs/retros\` and NOTE the fallback: report | ||
| the iwe error and the fallback in your summary — never fall back silently (2026-08-17 | ||
| lesson: a silent fallback hides retrieval-pipeline health from the human). | ||
|
|
||
| 3. **Determine the workflow schema** | ||
|
|
||
| Use the configured default schema unless the user explicitly requests a different workflow. | ||
|
|
||
|
|
@@ -203,7 +245,7 @@ ${STORE_SELECTION_GUIDANCE} | |
|
|
||
| Otherwise, omit \`--schema\` to preserve the configured default. | ||
|
|
||
| 3. **Create the change directory** | ||
| 4. **Create the change directory** | ||
|
|
||
| Choose one schema form below. If a registered store is selected, append \`--store "<store-id>"\` to that command and each later OpenSpec command shown below that accepts \`--store\`. | ||
|
|
||
|
|
@@ -218,7 +260,7 @@ ${STORE_SELECTION_GUIDANCE} | |
| \`\`\` | ||
| This creates a scaffolded change in the planning home resolved by the CLI with \`.openspec.yaml\`. | ||
|
|
||
| 4. **Get the artifact build order** | ||
| 5. **Get the artifact build order** | ||
| \`\`\`bash | ||
| openspec status --change "<name>" --json | ||
| \`\`\` | ||
|
|
@@ -227,7 +269,7 @@ ${STORE_SELECTION_GUIDANCE} | |
| - \`artifacts\`: list of all artifacts, each with its \`status\` and its \`requires\` edges (the artifact IDs it directly depends on) | ||
| - \`planningHome\`, \`changeRoot\`, \`artifactPaths\`, and \`actionContext\`: path and scope context. Use these instead of assuming repo-local paths. | ||
|
|
||
| 5. **Create every artifact in the required set** | ||
| 6. **Create every artifact in the required set** | ||
|
|
||
| Use a todo list to track progress through the artifacts. | ||
|
|
||
|
|
@@ -266,7 +308,23 @@ ${STORE_SELECTION_GUIDANCE} | |
| - Ask the user to clarify | ||
| - Then continue with creation | ||
|
|
||
| 6. **Show final status** | ||
| 7. **Run the validation and coherence gate** — do NOT claim the artifacts are ready until this step is green | ||
| <!-- LOCAL PATCH (proposal-validation-gate): re-apply after openspec upgrades that regenerate skills --> | ||
| a. **Change-scoped validation gate.** Run: | ||
| \`\`\`bash | ||
| openspec validate "<name>" --type change --strict --json --no-interactive | ||
| \`\`\` | ||
| (append \`--store "<id>"\` when a store is selected. The item name is positional — \`validate\` has NO \`--change\` flag. \`--no-interactive\` is required so an agent-driven run can't hang on an interactive prompt — upstream Fission-AI/OpenSpec#492.) | ||
| - Parse the JSON: the change passes when the item reports \`"valid": true\` (equivalently \`summary.totals.failed === 0\`). On failure, fix the reported issues in the artifacts and re-run before proceeding. | ||
| - \`openspec validate --all\` is informational only — an unrelated failing change elsewhere must NOT block this proposal's summary. | ||
| b. **Deterministic coherence gate.** Run, and re-run until it exits 0: | ||
| \`\`\`bash | ||
| bun scripts/check-proposal-coherence.ts "<name>" | ||
| \`\`\` | ||
| The checker verifies mechanically: every \`file:line\` anchor cited in design/tasks resolves against the real file; every grep/regression-guard string in tasks matches the prescribed phrasing verbatim; delta-spec requirement names do not collide with the main spec; every deliverable named in proposal.md (What Changes/Impact) has a delivering task or is declared a non-goal. Fix any violation in the artifacts, then re-run. | ||
| c. Only after both gates are green, proceed to the final status step. \`status: "done"\` (or an artifact showing \`done\`) means the FILE exists — it does NOT mean the artifact is correct; this step is the mechanical correctness check, and the depth-pass review remains the semantic check for high-stakes changes (see Output). | ||
|
|
||
| 8. **Show final status** | ||
| \`\`\`bash | ||
| openspec status --change "<name>" | ||
| \`\`\` | ||
|
|
@@ -276,6 +334,7 @@ ${STORE_SELECTION_GUIDANCE} | |
| After completing all artifacts, summarize: | ||
| - Change name and location | ||
| - List of artifacts created with brief descriptions, plus any conditional artifact you skipped and why | ||
| - Gate result: state that the proposal passed \`openspec validate --strict\` (change-scoped) and the coherence checker (\`bun scripts/check-proposal-coherence.ts\`) | ||
| - What's ready: "All artifacts needed for implementation are ready." | ||
| - Prompt: "The artifacts are ready for review. When you are ready, run \`/opsx:apply\`." | ||
|
|
||
|
|
@@ -292,6 +351,7 @@ After completing all artifacts, summarize: | |
|
|
||
| **Guardrails** | ||
| - The request that invoked this workflow authorizes planning only. Any implementation or apply instruction in that request does not carry forward. Do NOT implement the change, start the apply workflow, or edit project code during this workflow. After presenting the artifacts, stop and wait for a new user request to start the apply workflow | ||
| - \`status: "done"\` on an artifact means the FILE exists, NOT that it is correct — the validation + coherence gate (step 6) is the mechanical correctness check and MUST be green before presenting the "ready for review" summary. The depth-pass review remains the semantic check for high-stakes changes | ||
| - Create every artifact the apply phase transitively depends on, not just the ids listed in \`apply.requires\` | ||
| - Always read dependency artifacts before creating a new one - re-read from disk, not from conversation memory (files may have changed since you last saw them) | ||
| - Ask about ambiguities that would materially change scope, externally observable behavior, compatibility, or acceptance criteria; for minor details, make reasonable assumptions and record them | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Use separate, valid Bash permission patterns and restrict Bun access.
Bash(openspec:*,bun:*)is a single malformed rule rather than separate permissions, and it grants broader Bun access than the templates require. Use separate patterns with the actual command syntax, for example:Adjust the exact separator to the repository's permission format, but ensure the OpenSpec CLI and the specific coherence-check command are authorized independently.
📍 Affects 1 file
src/core/shared/allowed-tools.ts#L11-L11(this comment)src/core/shared/allowed-tools.ts#L11-L11🤖 Prompt for AI Agents