chore: harden SDD governance workflow
This commit is contained in:
@@ -21,6 +21,10 @@ write_file() {
|
||||
|
||||
write_file "specs/.openspec-store/store.yaml" $'version: 1\nid: wealth-ledger-specs'
|
||||
mkdir -p "$fixture/specs/openspec"
|
||||
write_file "specs/openspec/.cli-version" '1.10.0'
|
||||
write_file "specs/openspec/config.yaml" 'schema: wealth-ledger-sdd'
|
||||
mkdir -p "$fixture/specs/openspec/schemas"
|
||||
cp -R "$script_dir/../openspec/schemas/wealth-ledger-sdd" "$fixture/specs/openspec/schemas/wealth-ledger-sdd"
|
||||
|
||||
for path in AGENTS.md frontend/AGENTS.md backend/AGENTS.md specs/AGENTS.md docs/AGENTS.md; do
|
||||
write_file "$path" $'OpenSpec store: wealth-ledger-specs\nUse --store wealth-ledger-specs\nSDD artifacts only in specs/openspec\nreferences/** is read-only.'
|
||||
@@ -46,13 +50,36 @@ entrypoints=(
|
||||
)
|
||||
|
||||
for path in "${entrypoints[@]}"; do
|
||||
write_file "$path" 'openspec status --store wealth-ledger-specs'
|
||||
content=$'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs'
|
||||
if [[ "$path" == .opencode/skills/* ]]; then
|
||||
content=$'generatedBy: "1.10.0"\n'"$content"
|
||||
fi
|
||||
if [[ "$path" == *continue* || "$path" == *explore* || "$path" == *propose* ]]; then
|
||||
content="$content"$'\nCreate at most ONE planning artifact per invocation.\nSTOP for explicit Change Owner approval.'
|
||||
fi
|
||||
if [[ "$path" == *apply* || "$path" == *archive* ]]; then
|
||||
content="$content"$'\nRequire explicit Change Owner approval and invalidate dependent approvals after upstream edits.'
|
||||
fi
|
||||
write_file "$path" "$content"
|
||||
done
|
||||
|
||||
archive_gate='openspec status --store wealth-ledger-specs
|
||||
archive_gate='bash specs/scripts/verify-openspec-version.sh
|
||||
openspec status --store wealth-ledger-specs
|
||||
Require affected delivery area gates, semantic verification and independent read-only review.
|
||||
Require explicit Change Owner approval and invalidate dependent approvals after upstream edits.
|
||||
Do not ask for or accept a confirmation override.'
|
||||
write_file ".opencode/commands/opsx-archive.md" "$archive_gate"
|
||||
write_file ".opencode/skills/openspec-archive-change/SKILL.md" "$archive_gate"
|
||||
write_file ".opencode/skills/openspec-archive-change/SKILL.md" $'generatedBy: "1.10.0"\n'"$archive_gate"
|
||||
|
||||
verification_gate='bash specs/scripts/verify-openspec-version.sh
|
||||
openspec status --store wealth-ledger-specs
|
||||
Check every affected delivery area with the workspace verifier and require independent read-only review.'
|
||||
write_file ".opencode/commands/opsx-verify.md" "$verification_gate"
|
||||
write_file ".opencode/skills/openspec-verify-change/SKILL.md" $'generatedBy: "1.10.0"\n'"$verification_gate"
|
||||
|
||||
apply_gate='bash specs/scripts/verify-openspec-version.sh
|
||||
openspec status --store wealth-ledger-specs
|
||||
Require explicit Change Owner approval and invalidate dependent approvals after upstream edits.'
|
||||
|
||||
run_verifier() {
|
||||
WEALTH_LEDGER_WORKSPACE="$fixture" bash "$verifier"
|
||||
@@ -60,6 +87,28 @@ run_verifier() {
|
||||
|
||||
run_verifier
|
||||
|
||||
write_file "specs/openspec/.cli-version" '9.9.9'
|
||||
if run_verifier; then
|
||||
echo "expected wrong OpenSpec version contract to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file "specs/openspec/.cli-version" '1.10.0'
|
||||
|
||||
write_file "specs/openspec/config.yaml" 'schema: spec-driven'
|
||||
if run_verifier; then
|
||||
echo "expected non-project default schema to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file "specs/openspec/config.yaml" 'schema: wealth-ledger-sdd'
|
||||
|
||||
write_file "specs/openspec/schemas/wealth-ledger-sdd/schema.yaml" $'name: wealth-ledger-sdd\nversion: 1'
|
||||
if run_verifier; then
|
||||
echo "expected incomplete project schema graph to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
rm -rf "$fixture/specs/openspec/schemas/wealth-ledger-sdd"
|
||||
cp -R "$script_dir/../openspec/schemas/wealth-ledger-sdd" "$fixture/specs/openspec/schemas/wealth-ledger-sdd"
|
||||
|
||||
mkdir -p "$fixture/frontend/openspec"
|
||||
if run_verifier; then
|
||||
echo "expected additional OpenSpec root to fail" >&2
|
||||
@@ -67,41 +116,62 @@ if run_verifier; then
|
||||
fi
|
||||
rmdir "$fixture/frontend/openspec"
|
||||
|
||||
write_file ".opencode/commands/opsx-apply.md" 'Without a store, commands act on the nearest local openspec root.'
|
||||
write_file ".opencode/commands/opsx-apply.md" $'bash specs/scripts/verify-openspec-version.sh\nWithout a store, commands act on the nearest local openspec root.'
|
||||
if run_verifier; then
|
||||
echo "expected implicit store selection to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-apply.md" 'openspec status --store wealth-ledger-specs'
|
||||
write_file ".opencode/commands/opsx-apply.md" "$apply_gate"
|
||||
|
||||
write_file ".opencode/commands/opsx-apply.md" $'openspec status --store wealth-ledger-specs\nFor another store, append --store "<id>" when applicable.'
|
||||
write_file ".opencode/commands/opsx-apply.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs\nFor another store, append --store "<id>" when applicable.'
|
||||
if run_verifier; then
|
||||
echo "expected conditional store selection to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-apply.md" 'openspec status --store wealth-ledger-specs'
|
||||
write_file ".opencode/commands/opsx-apply.md" "$apply_gate"
|
||||
|
||||
write_file ".opencode/commands/opsx-apply.md" $'openspec status --store wealth-ledger-specs\nRun `openspec status --change "example" --json` before continuing.'
|
||||
write_file ".opencode/commands/opsx-apply.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs\nRun `openspec status --change "example" --json` before continuing.'
|
||||
if run_verifier; then
|
||||
echo "expected unscoped OpenSpec invocation to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-apply.md" 'openspec status --store wealth-ledger-specs'
|
||||
write_file ".opencode/commands/opsx-apply.md" "$apply_gate"
|
||||
|
||||
write_file ".opencode/commands/opsx-apply.md" $'openspec status --store wealth-ledger-specs\nUse artifact graph (openspec status --change "example" --json) before continuing.'
|
||||
write_file ".opencode/commands/opsx-apply.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs\nUse artifact graph (openspec status --change "example" --json) before continuing.'
|
||||
if run_verifier; then
|
||||
echo "expected parenthesized unscoped OpenSpec invocation to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-apply.md" 'openspec status --store wealth-ledger-specs'
|
||||
write_file ".opencode/commands/opsx-apply.md" "$apply_gate"
|
||||
|
||||
write_file ".opencode/commands/opsx-archive.md" $'openspec status --store wealth-ledger-specs\nDon\x27t block archive on warnings - just inform and confirm.'
|
||||
write_file ".opencode/commands/opsx-propose.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs\nCreate every artifact in the required set.\nSTOP for explicit Change Owner approval.'
|
||||
if run_verifier; then
|
||||
echo "expected multi-artifact proposal guidance to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-propose.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs\nCreate at most ONE planning artifact per invocation.\nSTOP for explicit Change Owner approval.'
|
||||
|
||||
write_file ".opencode/commands/opsx-archive.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs\nDon\x27t block archive on warnings - just inform and confirm.'
|
||||
if run_verifier; then
|
||||
echo "expected archive override guidance to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-archive.md" "$archive_gate"
|
||||
|
||||
write_file ".opencode/commands/opsx-archive.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs\nDo not ask for or accept a confirmation override.'
|
||||
if run_verifier; then
|
||||
echo "expected archive without required verification to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-archive.md" "$archive_gate"
|
||||
|
||||
write_file ".opencode/commands/opsx-verify.md" $'bash specs/scripts/verify-openspec-version.sh\nopenspec status --store wealth-ledger-specs'
|
||||
if run_verifier; then
|
||||
echo "expected semantic verifier without affected-area review to fail" >&2
|
||||
exit 1
|
||||
fi
|
||||
write_file ".opencode/commands/opsx-verify.md" "$verification_gate"
|
||||
|
||||
mkdir -p "$fixture/docs/superpowers/plans"
|
||||
if run_verifier; then
|
||||
echo "expected prohibited planning location to fail" >&2
|
||||
|
||||
Reference in New Issue
Block a user