@chenmk/superflow 0.3.0 → 0.5.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/INSTALL.en.md +54 -12
- package/INSTALL.md +59 -33
- package/README.md +192 -49
- package/README.zh-CN.md +166 -46
- package/assets/brand/managed-review-loop.png +0 -0
- package/assets/manifest.json +15 -9
- package/assets/prompts/superflow-design.md +3 -0
- package/assets/prompts/superflow-docs.md +4 -1
- package/assets/scripts/superflow-coding-ready.mjs +135 -0
- package/assets/scripts/superflow-dependency-update-hook.sh +81 -8
- package/assets/scripts/superflow-document-audit.mjs +240 -0
- package/assets/scripts/superflow-environment-preflight.mjs +398 -0
- package/assets/scripts/superflow-hook-guard.sh +40 -1
- package/assets/scripts/superflow-managed-command-guard.py +309 -0
- package/assets/scripts/superflow-managed-executor-preflight.mjs +421 -0
- package/assets/scripts/superflow-managed-owner-verification.sh +117 -0
- package/assets/scripts/superflow-managed-work-check.mjs +455 -0
- package/assets/scripts/superflow-managed-work-guard.sh +17 -0
- package/assets/skills/openspec-propose/SKILL.md +11 -0
- package/assets/skills/superflow-clarify/SKILL.md +14 -0
- package/assets/skills/superflow-design/SKILL.md +46 -12
- package/assets/skills/superflow-docs/SKILL.md +109 -2
- package/assets/skills/superflow-pipeline/SKILL.md +205 -2
- package/assets/skills/superflow-pipeline/references/batch-prompt-template.md +17 -9
- package/assets/skills/superflow-pipeline/references/document-readiness.md +157 -0
- package/assets/skills/superflow-pipeline/references/document-templates.md +17 -5
- package/assets/skills/superflow-pipeline/references/feature-gated-workflow.md +14 -0
- package/assets/skills/superflow-pipeline/references/implementation-prompt-template.md +20 -11
- package/assets/skills/superflow-pipeline/references/managed-work.md +166 -0
- package/assets/skills/superflow-pipeline/references/orchestration.md +2 -2
- package/assets/skills/superflow-pipeline/references/p0-baseline-template.md +3 -2
- package/assets/skills/superflow-pipeline/references/quality-gate.md +8 -5
- package/assets/skills/superflow-pipeline/references/reviewer-checklist.md +7 -0
- package/assets/skills/superflow-pipeline/references/superpower-technical-design-template.md +10 -0
- package/assets/skills/superflow-pipeline/scripts/superflow-archive.sh +1 -1
- package/assets/skills/superflow-pipeline/scripts/superflow-guard.sh +282 -16
- package/assets/skills/superflow-pipeline/scripts/superflow-handoff.sh +7 -4
- package/assets/skills/superflow-requirement-review/SKILL.md +178 -0
- package/assets/skills/superflow-requirement-review/agents/openai.yaml +4 -0
- package/assets/skills-en/openspec-propose/SKILL.md +14 -0
- package/assets/skills-en/superflow-clarify/SKILL.md +17 -0
- package/assets/skills-en/superflow-design/SKILL.md +40 -11
- package/assets/skills-en/superflow-docs/SKILL.md +115 -0
- package/assets/skills-en/superflow-pipeline/SKILL.md +202 -0
- package/assets/skills-en/superflow-pipeline/references/batch-prompt-template.md +4 -0
- package/assets/skills-en/superflow-pipeline/references/document-readiness.md +125 -0
- package/assets/skills-en/superflow-pipeline/references/document-templates.md +15 -0
- package/assets/skills-en/superflow-pipeline/references/feature-gated-workflow.md +7 -0
- package/assets/skills-en/superflow-pipeline/references/implementation-prompt-template.md +7 -0
- package/assets/skills-en/superflow-pipeline/references/managed-work.md +184 -0
- package/assets/skills-en/superflow-pipeline/references/quality-gate.md +20 -0
- package/assets/skills-en/superflow-pipeline/references/reviewer-checklist.md +7 -0
- package/assets/skills-en/superflow-pipeline/references/superpower-technical-design-template.md +11 -0
- package/assets/skills-en/superflow-pipeline/scripts/superflow-archive.sh +1 -1
- package/assets/skills-en/superflow-pipeline/scripts/superflow-guard.sh +279 -14
- package/assets/skills-en/superflow-pipeline/scripts/superflow-handoff.sh +7 -4
- package/assets/skills-en/superflow-requirement-review/SKILL.md +99 -0
- package/assets/skills-en/superflow-requirement-review/agents/openai.yaml +4 -0
- package/dist/app/cli.js +176 -103
- package/dist/app/cli.js.map +1 -1
- package/dist/app/commands/change-guard.js +19 -2
- package/dist/app/commands/change-guard.js.map +1 -1
- package/dist/app/commands/check.js +107 -45
- package/dist/app/commands/check.js.map +1 -1
- package/dist/app/commands/docs.js +7 -3
- package/dist/app/commands/docs.js.map +1 -1
- package/dist/app/commands/doctor.js +174 -198
- package/dist/app/commands/doctor.js.map +1 -1
- package/dist/app/commands/eval.js +64 -0
- package/dist/app/commands/eval.js.map +1 -0
- package/dist/app/commands/implement.js +7 -3
- package/dist/app/commands/implement.js.map +1 -1
- package/dist/app/commands/init.js +16 -24
- package/dist/app/commands/init.js.map +1 -1
- package/dist/app/commands/managed-service.js +5 -0
- package/dist/app/commands/managed-service.js.map +1 -0
- package/dist/app/commands/mcp.js +167 -0
- package/dist/app/commands/mcp.js.map +1 -0
- package/dist/app/commands/pipeline.js +757 -3
- package/dist/app/commands/pipeline.js.map +1 -1
- package/dist/app/commands/requirement-review.js +6 -0
- package/dist/app/commands/requirement-review.js.map +1 -0
- package/dist/app/commands/status.js +262 -77
- package/dist/app/commands/status.js.map +1 -1
- package/dist/app/commands/uninstall.js +8 -5
- package/dist/app/commands/uninstall.js.map +1 -1
- package/dist/app/commands/update.js +114 -15
- package/dist/app/commands/update.js.map +1 -1
- package/dist/domains/agent.js +3 -11
- package/dist/domains/agent.js.map +1 -1
- package/dist/domains/config/cli-help.js +145 -73
- package/dist/domains/config/cli-help.js.map +1 -1
- package/dist/domains/config/i18n.js +6 -8
- package/dist/domains/config/i18n.js.map +1 -1
- package/dist/domains/config/manifest.js +0 -3
- package/dist/domains/config/manifest.js.map +1 -1
- package/dist/domains/deps.js +70 -8
- package/dist/domains/deps.js.map +1 -1
- package/dist/domains/hook.js +71 -38
- package/dist/domains/hook.js.map +1 -1
- package/dist/domains/managed-work/completion-policy.js +174 -0
- package/dist/domains/managed-work/completion-policy.js.map +1 -0
- package/dist/domains/managed-work/context-manifest.js +208 -0
- package/dist/domains/managed-work/context-manifest.js.map +1 -0
- package/dist/domains/managed-work/contract.js +349 -0
- package/dist/domains/managed-work/contract.js.map +1 -0
- package/dist/domains/managed-work/control-signals.js +34 -0
- package/dist/domains/managed-work/control-signals.js.map +1 -0
- package/dist/domains/managed-work/control.js +628 -0
- package/dist/domains/managed-work/control.js.map +1 -0
- package/dist/domains/managed-work/evaluation.js +497 -0
- package/dist/domains/managed-work/evaluation.js.map +1 -0
- package/dist/domains/managed-work/evidence-path.js +14 -0
- package/dist/domains/managed-work/evidence-path.js.map +1 -0
- package/dist/domains/managed-work/execution-contract.js +167 -0
- package/dist/domains/managed-work/execution-contract.js.map +1 -0
- package/dist/domains/managed-work/executor-policy.js +65 -0
- package/dist/domains/managed-work/executor-policy.js.map +1 -0
- package/dist/domains/managed-work/failure.js +65 -0
- package/dist/domains/managed-work/failure.js.map +1 -0
- package/dist/domains/managed-work/host-review.js +77 -0
- package/dist/domains/managed-work/host-review.js.map +1 -0
- package/dist/domains/managed-work/human-messages.js +31 -0
- package/dist/domains/managed-work/human-messages.js.map +1 -0
- package/dist/domains/managed-work/i18n.js +12 -0
- package/dist/domains/managed-work/i18n.js.map +1 -0
- package/dist/domains/managed-work/input.js +137 -0
- package/dist/domains/managed-work/input.js.map +1 -0
- package/dist/domains/managed-work/journal.js +196 -0
- package/dist/domains/managed-work/journal.js.map +1 -0
- package/dist/domains/managed-work/lock.js +106 -0
- package/dist/domains/managed-work/lock.js.map +1 -0
- package/dist/domains/managed-work/notifications.js +38 -0
- package/dist/domains/managed-work/notifications.js.map +1 -0
- package/dist/domains/managed-work/pair-admission.js +108 -0
- package/dist/domains/managed-work/pair-admission.js.map +1 -0
- package/dist/domains/managed-work/paths.js +18 -0
- package/dist/domains/managed-work/paths.js.map +1 -0
- package/dist/domains/managed-work/prompts.js +453 -0
- package/dist/domains/managed-work/prompts.js.map +1 -0
- package/dist/domains/managed-work/redaction.js +90 -0
- package/dist/domains/managed-work/redaction.js.map +1 -0
- package/dist/domains/managed-work/review-convergence.js +41 -0
- package/dist/domains/managed-work/review-convergence.js.map +1 -0
- package/dist/domains/managed-work/review-facts.js +181 -0
- package/dist/domains/managed-work/review-facts.js.map +1 -0
- package/dist/domains/managed-work/rule-selection.js +84 -0
- package/dist/domains/managed-work/rule-selection.js.map +1 -0
- package/dist/domains/managed-work/runner.js +2418 -0
- package/dist/domains/managed-work/runner.js.map +1 -0
- package/dist/domains/managed-work/schemas.js +155 -0
- package/dist/domains/managed-work/schemas.js.map +1 -0
- package/dist/domains/managed-work/service.js +190 -0
- package/dist/domains/managed-work/service.js.map +1 -0
- package/dist/domains/managed-work/state.js +280 -0
- package/dist/domains/managed-work/state.js.map +1 -0
- package/dist/domains/managed-work/storage.js +223 -0
- package/dist/domains/managed-work/storage.js.map +1 -0
- package/dist/domains/managed-work/types.js +19 -0
- package/dist/domains/managed-work/types.js.map +1 -0
- package/dist/domains/managed-work/verification-categories.js +39 -0
- package/dist/domains/managed-work/verification-categories.js.map +1 -0
- package/dist/domains/managed-work/verification-policy.js +116 -0
- package/dist/domains/managed-work/verification-policy.js.map +1 -0
- package/dist/domains/managed-work/wait.js +58 -0
- package/dist/domains/managed-work/wait.js.map +1 -0
- package/dist/domains/managed-work/workspace-binding.js +133 -0
- package/dist/domains/managed-work/workspace-binding.js.map +1 -0
- package/dist/domains/sdd-readiness.js +44 -0
- package/dist/domains/sdd-readiness.js.map +1 -0
- package/dist/domains/skill/deploy.js +0 -6
- package/dist/domains/skill/deploy.js.map +1 -1
- package/dist/domains/skill/scripts.js +0 -8
- package/dist/domains/skill/scripts.js.map +1 -1
- package/dist/domains/state.js +1 -2
- package/dist/domains/state.js.map +1 -1
- package/dist/mcp/runtime-identity.js +21 -0
- package/dist/mcp/runtime-identity.js.map +1 -0
- package/dist/mcp/server.js +369 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/platform/agent-process.js +769 -0
- package/dist/platform/agent-process.js.map +1 -0
- package/dist/platform/executable.js +28 -0
- package/dist/platform/executable.js.map +1 -0
- package/dist/platform/paths.js +1 -17
- package/dist/platform/paths.js.map +1 -1
- package/dist/platform/process-liveness.js +10 -0
- package/dist/platform/process-liveness.js.map +1 -0
- package/dist/platform/process-tree.js +44 -0
- package/dist/platform/process-tree.js.map +1 -0
- package/dist/platform/process.js +1 -1
- package/dist/platform/process.js.map +1 -1
- package/dist/platform/version-check.js +30 -9
- package/dist/platform/version-check.js.map +1 -1
- package/package.json +16 -7
- package/scripts/check-design-principles.mjs +107 -0
- package/scripts/check-managed-work-design.mjs +507 -0
- package/scripts/clean-dist.js +9 -0
- package/scripts/ensure-bin-modes.js +11 -0
- package/dist/cli/index.js +0 -193
- package/dist/cli/index.js.map +0 -1
- package/dist/commands/archive.js +0 -6
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/clarify.js +0 -6
- package/dist/commands/clarify.js.map +0 -1
- package/dist/commands/design.js +0 -28
- package/dist/commands/design.js.map +0 -1
- package/dist/commands/docs.js +0 -6
- package/dist/commands/docs.js.map +0 -1
- package/dist/commands/doctor.js +0 -494
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/implement.js +0 -6
- package/dist/commands/implement.js.map +0 -1
- package/dist/commands/init.js +0 -520
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/pipeline.js +0 -6
- package/dist/commands/pipeline.js.map +0 -1
- package/dist/commands/scan.js +0 -63
- package/dist/commands/scan.js.map +0 -1
- package/dist/commands/status.js +0 -173
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/uninstall.js +0 -214
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/commands/update.js +0 -193
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/verify.js +0 -6
- package/dist/commands/verify.js.map +0 -1
- package/dist/core/assets.js +0 -27
- package/dist/core/assets.js.map +0 -1
- package/dist/core/cli-help.js +0 -98
- package/dist/core/cli-help.js.map +0 -1
- package/dist/core/context.js +0 -123
- package/dist/core/context.js.map +0 -1
- package/dist/core/dependencies.js +0 -146
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/detect.js +0 -64
- package/dist/core/detect.js.map +0 -1
- package/dist/core/i18n.js +0 -105
- package/dist/core/i18n.js.map +0 -1
- package/dist/core/integrity.js +0 -46
- package/dist/core/integrity.js.map +0 -1
- package/dist/core/manifest.js +0 -21
- package/dist/core/manifest.js.map +0 -1
- package/dist/core/prompts.js +0 -20
- package/dist/core/prompts.js.map +0 -1
- package/dist/core/registry.js +0 -134
- package/dist/core/registry.js.map +0 -1
- package/dist/core/rules.js +0 -17
- package/dist/core/rules.js.map +0 -1
- package/dist/core/scripts.js +0 -48
- package/dist/core/scripts.js.map +0 -1
- package/dist/core/skill-check.js +0 -32
- package/dist/core/skill-check.js.map +0 -1
- package/dist/core/skills.js +0 -62
- package/dist/core/skills.js.map +0 -1
- package/dist/core/state.js +0 -54
- package/dist/core/state.js.map +0 -1
- package/dist/utils/path.js +0 -11
- package/dist/utils/path.js.map +0 -1
- package/dist/utils/shell.js +0 -29
- package/dist/utils/shell.js.map +0 -1
|
@@ -9,10 +9,28 @@
|
|
|
9
9
|
- Handoff files exist and hash is current.
|
|
10
10
|
- design.md records OpenSpec/SDD as WHAT and Superpowers as HOW.
|
|
11
11
|
- sdd-quality-gate.md records guard command and result.
|
|
12
|
+
- design.md and sdd-quality-gate.md include a Minimal Design Review with reuse
|
|
13
|
+
evidence, necessity, simplest implementation, removed/rejected complexity,
|
|
14
|
+
counts of new tables/fields/APIs/services/caches/async flows/jobs/compatibility
|
|
15
|
+
layers, and a PASS/BLOCKED verdict. Only PASS may leave docs/design.
|
|
16
|
+
- Full existing-system, DB/table, cross-repository, or real-entry changes have
|
|
17
|
+
`source-code-audit.md` with a Source Fact Freeze Card, all writers and real
|
|
18
|
+
callers, current/legacy/unmounted/data-model-only/owner-confirmed/blocked
|
|
19
|
+
classifications, DB check or skip reason, conflict audit, and owner boundary.
|
|
20
|
+
- Database changes have `release-sql.md` with `database_change: true`, an exact
|
|
21
|
+
placeholder-free `target_sql_path`, `copy_policy: verbatim`, a valid
|
|
22
|
+
`sql_sha256`, and exactly one complete executable SQL block with required
|
|
23
|
+
prechecks, DDL/DML, migration, and post-verification. Design, tasks, and the
|
|
24
|
+
quality gate state that implementation agents may only copy it verbatim;
|
|
25
|
+
omissions return to docs.
|
|
12
26
|
|
|
13
27
|
## Design Gate
|
|
14
28
|
|
|
15
29
|
- Technical design exists for full workflow.
|
|
30
|
+
- Technical design repeats the Minimal Design Review at source level. It extends
|
|
31
|
+
existing modules first and rejects speculative abstractions, parallel APIs or
|
|
32
|
+
models, derivable persistence, premature caches, and async compensation when
|
|
33
|
+
a direct synchronous design satisfies the contract.
|
|
16
34
|
- Field/status reverse impact matrix exists when risky fields or states change.
|
|
17
35
|
- Architecture boundary and call-direction matrix exists for cross-service or
|
|
18
36
|
external flows.
|
|
@@ -43,6 +61,8 @@
|
|
|
43
61
|
sum(other components)` instead of calculating and rounding every component
|
|
44
62
|
independently.
|
|
45
63
|
- SQL risk review exists for DB changes.
|
|
64
|
+
- Source-level design does not author or defer release SQL; it consumes the
|
|
65
|
+
already frozen `release-sql.md` contract.
|
|
46
66
|
- No fallback or guesswork is allowed without explicit owner approval.
|
|
47
67
|
|
|
48
68
|
## Implementation Gate
|
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
rounding explicit, without early rate rounding or synthesized inverses?
|
|
23
23
|
- Are SQL changes reviewed and tied to total version SQL when needed?
|
|
24
24
|
- Are RED/GREEN evidence and real-entry evidence present?
|
|
25
|
+
- For L3/L4 negative controls, does the raw malformed or forbidden payload reach
|
|
26
|
+
the intended parser/validation branch, rather than merely returning the same
|
|
27
|
+
status code?
|
|
28
|
+
- For task-owned resource cleanup, are every frozen identity field (nonce, PID,
|
|
29
|
+
port, signature, etc.) compared and mismatch refusal proven? An unchanged
|
|
30
|
+
certified helper needs integrity, task parameters, one failure cleanup, and
|
|
31
|
+
final zero residue only.
|
|
25
32
|
- Are mock-only results clearly labeled?
|
|
26
33
|
- Did workers stay inside allowed file boundaries?
|
|
27
34
|
- Did hooks and guard scripts pass?
|
package/assets/skills-en/superflow-pipeline/references/superpower-technical-design-template.md
CHANGED
|
@@ -35,6 +35,17 @@ canonical_sources:
|
|
|
35
35
|
|---|---|---|---|---|---|
|
|
36
36
|
| <R1/S1> | `<file>:<line>` | <observed fact> | <implementation approach> | <files> | <risk> |
|
|
37
37
|
|
|
38
|
+
## Minimal Design Review
|
|
39
|
+
|
|
40
|
+
| Design item | Existing capability/reuse evidence | Necessary? | Simplest implementation | Removed/rejected complexity | Evidence/blocker |
|
|
41
|
+
| ----------- | ---------------------------------- | ---------- | ----------------------- | --------------------------- | ---------------- |
|
|
42
|
+
| `<table/API/service/component/sync>` | `<existing source/API/table/dependency>` | `keep/remove/blocked` | `<minimum implementation>` | `<no parallel abstraction/cache/async/compat layer>` | `<anchor or blocker>` |
|
|
43
|
+
|
|
44
|
+
New-item counts: tables 0; fields 0; APIs 0; services/components 0; caches 0; MQ/events 0; scheduled jobs 0; compatibility layers 0. Replace each count with the actual design total. Extend existing modules first. Do not persist values
|
|
45
|
+
that can be derived safely, and do not add async compensation or caching when a
|
|
46
|
+
single synchronous transaction closes the contract. Every retained item must
|
|
47
|
+
explain why a simpler option fails; remove it when there is no evidence.
|
|
48
|
+
|
|
38
49
|
## Architecture Boundary And Call Direction
|
|
39
50
|
|
|
40
51
|
Use this whenever the change crosses repositories, services, SDKs, MQ,
|
|
@@ -131,7 +131,7 @@ GUARD="$SCRIPT_DIR/superflow-guard.sh"
|
|
|
131
131
|
VALIDATE="$SCRIPT_DIR/superflow-yaml-validate.sh"
|
|
132
132
|
CHANGE_DIR="$(cd "$CHANGE_DIR" && pwd)"
|
|
133
133
|
CHANGE_NAME="$(basename "$CHANGE_DIR")"
|
|
134
|
-
PROJECT_ROOT="$(cd "$CHANGE_DIR
|
|
134
|
+
PROJECT_ROOT="$(cd "$CHANGE_DIR/../../.." && pwd)"
|
|
135
135
|
ARCHIVE_ROOT="$PROJECT_ROOT/openspec/changes/archive"
|
|
136
136
|
ARCHIVE_NAME="$CHANGE_NAME"
|
|
137
137
|
|
|
@@ -24,6 +24,7 @@ VALIDATE="$SCRIPT_DIR/superflow-yaml-validate.sh"
|
|
|
24
24
|
CHANGE_DIR="${1:-}"
|
|
25
25
|
PHASE="${2:-}"
|
|
26
26
|
MODE="${3:-}"
|
|
27
|
+
CHANGE_DIR_INPUT="${CHANGE_DIR%/}"
|
|
27
28
|
|
|
28
29
|
[[ -n "$CHANGE_DIR" && -n "$PHASE" ]] || {
|
|
29
30
|
usage
|
|
@@ -35,6 +36,25 @@ MODE="${3:-}"
|
|
|
35
36
|
CHANGE_DIR="$(cd "$CHANGE_DIR" && pwd)"
|
|
36
37
|
issues=()
|
|
37
38
|
|
|
39
|
+
require_canonical_change_layout() {
|
|
40
|
+
local suffix
|
|
41
|
+
|
|
42
|
+
if [[ -L "$CHANGE_DIR_INPUT" ]]; then
|
|
43
|
+
issues+=("symlinked OpenSpec change directory is forbidden; keep one physical openspec/changes/<change-name> directory")
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
[[ "$CHANGE_DIR" == */openspec/changes/* ]] || return 0
|
|
47
|
+
suffix="${CHANGE_DIR#*/openspec/changes/}"
|
|
48
|
+
case "$suffix" in
|
|
49
|
+
archive/*|*/embedded-changes/*) return 0 ;;
|
|
50
|
+
esac
|
|
51
|
+
if [[ "$suffix" == */* ]]; then
|
|
52
|
+
issues+=("non-canonical OpenSpec change directory: encode the version in <change-name> and use openspec/changes/<change-name>")
|
|
53
|
+
fi
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
require_canonical_change_layout
|
|
57
|
+
|
|
38
58
|
require_file() {
|
|
39
59
|
local path="$1"
|
|
40
60
|
[[ -f "$CHANGE_DIR/$path" ]] || issues+=("missing file: $path")
|
|
@@ -302,18 +322,141 @@ change_has_field_status_risk() {
|
|
|
302
322
|
"$CHANGE_DIR"/*.md "$CHANGE_DIR"/**/*.md 2>/dev/null
|
|
303
323
|
}
|
|
304
324
|
|
|
305
|
-
|
|
325
|
+
change_has_database_change() {
|
|
326
|
+
if grep -Eiq '^[[:space:]]*database:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
327
|
+
return 1
|
|
328
|
+
fi
|
|
329
|
+
if grep -Eiq '^[[:space:]]*database:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
330
|
+
return 0
|
|
331
|
+
fi
|
|
306
332
|
grep -RIEiq \
|
|
307
|
-
'
|
|
333
|
+
'database_change[[:space:]]*:[[:space:]]*true|database[ -]change.{0,12}(required|true|yes)|ALTER[[:space:]]+TABLE|CREATE[[:space:]]+TABLE|ADD[[:space:]]+(COLUMN|INDEX|KEY|CONSTRAINT)|schema[ -]migration|database[ -]migration|historical data.{0,12}(migration|backfill)|seed data.{0,12}(migration|backfill)|add.{0,12}(table|column|index|constraint)' \
|
|
308
334
|
"$CHANGE_DIR/proposal.md" \
|
|
309
335
|
"$CHANGE_DIR/api.md" \
|
|
310
336
|
"$CHANGE_DIR/design.md" \
|
|
311
|
-
"$CHANGE_DIR/
|
|
337
|
+
"$CHANGE_DIR/tasks.md" \
|
|
338
|
+
"$CHANGE_DIR/database-contract.md" \
|
|
312
339
|
"$CHANGE_DIR/spec.md" \
|
|
313
340
|
"$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
|
|
314
341
|
}
|
|
315
342
|
|
|
343
|
+
require_frozen_release_sql() {
|
|
344
|
+
local release_sql="$CHANGE_DIR/release-sql.md"
|
|
345
|
+
local output
|
|
346
|
+
|
|
347
|
+
require_file release-sql.md
|
|
348
|
+
[[ -f "$release_sql" ]] || return 0
|
|
349
|
+
|
|
350
|
+
output="$(mktemp)"
|
|
351
|
+
if ! python3 - "$release_sql" >"$output" 2>&1 <<'PY'
|
|
352
|
+
import hashlib
|
|
353
|
+
import re
|
|
354
|
+
import sys
|
|
355
|
+
from pathlib import Path
|
|
356
|
+
|
|
357
|
+
path = Path(sys.argv[1])
|
|
358
|
+
text = path.read_text(encoding="utf-8")
|
|
359
|
+
errors = []
|
|
360
|
+
|
|
361
|
+
front_match = re.match(r"\A---\n(.*?)\n---(?:\n|\Z)", text, re.S)
|
|
362
|
+
front = front_match.group(1) if front_match else ""
|
|
363
|
+
if not front_match:
|
|
364
|
+
errors.append("front matter is missing")
|
|
365
|
+
|
|
366
|
+
def field(name):
|
|
367
|
+
match = re.search(rf"(?m)^{re.escape(name)}:\s*(.*?)\s*$", front)
|
|
368
|
+
return match.group(1).strip().strip('"\'') if match else ""
|
|
369
|
+
|
|
370
|
+
if field("database_change").lower() != "true":
|
|
371
|
+
errors.append("database_change must be true")
|
|
372
|
+
|
|
373
|
+
target = field("target_sql_path")
|
|
374
|
+
if not target or not target.lower().endswith(".sql"):
|
|
375
|
+
errors.append("target_sql_path must be an exact .sql path")
|
|
376
|
+
if re.search(r"[<>{}]|testN|version|pending|TBD", target, re.I):
|
|
377
|
+
errors.append("target_sql_path contains a placeholder")
|
|
378
|
+
|
|
379
|
+
if field("copy_policy").lower() != "verbatim":
|
|
380
|
+
errors.append("copy_policy must be verbatim")
|
|
381
|
+
|
|
382
|
+
declared_hash = field("sql_sha256").lower()
|
|
383
|
+
if not re.fullmatch(r"[0-9a-f]{64}", declared_hash):
|
|
384
|
+
errors.append("sql_sha256 must be a 64-character lowercase SHA-256")
|
|
385
|
+
|
|
386
|
+
blocks = re.findall(r"```sql[^\n]*\n(.*?)\n```", text, re.S | re.I)
|
|
387
|
+
if len(blocks) != 1:
|
|
388
|
+
errors.append("release-sql.md must contain exactly one sql code block")
|
|
389
|
+
else:
|
|
390
|
+
payload = blocks[0].replace("\r\n", "\n").replace("\r", "\n").rstrip("\n") + "\n"
|
|
391
|
+
actual_hash = hashlib.sha256(payload.encode("utf-8")).hexdigest()
|
|
392
|
+
if declared_hash and actual_hash != declared_hash:
|
|
393
|
+
errors.append(
|
|
394
|
+
f"sql_sha256 mismatch: declared={declared_hash} actual={actual_hash}"
|
|
395
|
+
)
|
|
396
|
+
executable = re.sub(r"/\*.*?\*/|--[^\n]*", "", payload, flags=re.S)
|
|
397
|
+
if not re.search(
|
|
398
|
+
r"\b(CREATE|ALTER|DROP|INSERT|UPDATE|DELETE|MERGE|TRUNCATE|CALL)\b",
|
|
399
|
+
executable,
|
|
400
|
+
re.I,
|
|
401
|
+
):
|
|
402
|
+
errors.append("sql block has no executable schema/data change statement")
|
|
403
|
+
if not re.search(r"\b(SELECT|SHOW|CALL)\b", executable, re.I):
|
|
404
|
+
errors.append("sql block has no executable verification statement")
|
|
405
|
+
|
|
406
|
+
if errors:
|
|
407
|
+
print("; ".join(errors))
|
|
408
|
+
sys.exit(1)
|
|
409
|
+
PY
|
|
410
|
+
then
|
|
411
|
+
issues+=("frozen release SQL invalid: $(tr '\n' ' ' < "$output" | sed -E 's/[[:space:]]+/ /g')")
|
|
412
|
+
fi
|
|
413
|
+
rm -f "$output"
|
|
414
|
+
|
|
415
|
+
require_grep 'release-sql\.md' design.md "frozen release SQL design reference"
|
|
416
|
+
require_grep 'release-sql\.md' tasks.md "frozen release SQL task reference"
|
|
417
|
+
require_grep 'release-sql\.md' sdd-quality-gate.md "frozen release SQL quality-gate reference"
|
|
418
|
+
require_grep 'verbatim' tasks.md "verbatim SQL copy task"
|
|
419
|
+
require_grep 'verbatim' sdd-quality-gate.md "verbatim SQL copy quality gate"
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
change_contract_docs_without_complexity_budget() {
|
|
423
|
+
local path
|
|
424
|
+
for path in proposal.md api.md design.md tests.md spec.md; do
|
|
425
|
+
[[ -f "$CHANGE_DIR/$path" ]] || continue
|
|
426
|
+
sed -E '/New-item counts|Complexity budget/d' "$CHANGE_DIR/$path"
|
|
427
|
+
done
|
|
428
|
+
if [[ -d "$CHANGE_DIR/specs" ]]; then
|
|
429
|
+
find "$CHANGE_DIR/specs" -path '*/spec.md' -type f \
|
|
430
|
+
-exec sed -E '/New-item counts|Complexity budget/d' {} +
|
|
431
|
+
fi
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
change_all_docs_without_complexity_budget() {
|
|
435
|
+
find "$CHANGE_DIR" -maxdepth 2 -name '*.md' -type f \
|
|
436
|
+
-exec sed -E '/New-item counts|Complexity budget/d' {} +
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
change_has_external_config_risk() {
|
|
440
|
+
if grep -Eiq '^[[:space:]]*external_config:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
441
|
+
return 1
|
|
442
|
+
fi
|
|
443
|
+
if grep -Eiq '^[[:space:]]*external_config:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
444
|
+
return 0
|
|
445
|
+
fi
|
|
446
|
+
local content
|
|
447
|
+
content="$(change_contract_docs_without_complexity_budget)"
|
|
448
|
+
grep -Eiq \
|
|
449
|
+
'third[- ]party|external (platform|tool|integration|system)|SDK|MQ|Kafka|RocketMQ|TDMQ|callback|webhook|payment gateway|cloud service' \
|
|
450
|
+
<<< "$content"
|
|
451
|
+
}
|
|
452
|
+
|
|
316
453
|
change_has_concurrency_idempotency_risk() {
|
|
454
|
+
if grep -Eiq '^[[:space:]]*concurrency:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
455
|
+
return 1
|
|
456
|
+
fi
|
|
457
|
+
if grep -Eiq '^[[:space:]]*concurrency:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
458
|
+
return 0
|
|
459
|
+
fi
|
|
317
460
|
grep -RIEiq \
|
|
318
461
|
'concurren|idempoten|race condition|duplicate (request|callback|consumption|delivery)|atomic claim|batch (issue|activate|renew)' \
|
|
319
462
|
"$CHANGE_DIR/proposal.md" \
|
|
@@ -325,6 +468,12 @@ change_has_concurrency_idempotency_risk() {
|
|
|
325
468
|
}
|
|
326
469
|
|
|
327
470
|
change_has_money_precision_risk() {
|
|
471
|
+
if grep -Eiq '^[[:space:]]*money:[[:space:]]*false([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
472
|
+
return 1
|
|
473
|
+
fi
|
|
474
|
+
if grep -Eiq '^[[:space:]]*money:[[:space:]]*true([[:space:]]*#.*)?$' "$CHANGE_DIR/.openspec.yaml" 2>/dev/null; then
|
|
475
|
+
return 0
|
|
476
|
+
fi
|
|
328
477
|
grep -RIEiq \
|
|
329
478
|
'(^|[^[:alnum:]_])(amount|fee|fees|price|discount|deduction|refund|payment|invoice|balance|proration|allocation|reconciliation|residual|precision|rounding)([^[:alnum:]_]|$)|revenue sharing|profit sharing|split payment|electricity fee|service fee|package settlement|serviceFee|chargeFee|totalAmount|actualAmount|payAmount|refundAmount|discountAmount|invoiceAmount|balanceAmount' \
|
|
330
479
|
"$CHANGE_DIR/proposal.md" \
|
|
@@ -335,6 +484,53 @@ change_has_money_precision_risk() {
|
|
|
335
484
|
"$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
|
|
336
485
|
}
|
|
337
486
|
|
|
487
|
+
change_has_source_fact_risk() {
|
|
488
|
+
grep -RIEiq \
|
|
489
|
+
'existing|current behavior|legacy|database|table relationship|Mapper|XML|cross[- ](repo|service)|crosses services|real entry|mini[- ]program|H5' \
|
|
490
|
+
"$CHANGE_DIR/proposal.md" \
|
|
491
|
+
"$CHANGE_DIR/api.md" \
|
|
492
|
+
"$CHANGE_DIR/design.md" \
|
|
493
|
+
"$CHANGE_DIR/tests.md" \
|
|
494
|
+
"$CHANGE_DIR/spec.md" \
|
|
495
|
+
"$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
change_has_cardinality_conflict_signal() {
|
|
499
|
+
grep -RIEiq \
|
|
500
|
+
'List[<(]|orderIds|batchInsert|one[- ]to[- ]many|relation table' \
|
|
501
|
+
"$CHANGE_DIR"/*.md "$CHANGE_DIR"/**/*.md 2>/dev/null
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
require_source_fact_audit() {
|
|
505
|
+
require_file source-code-audit.md
|
|
506
|
+
require_grep 'Source Fact Freeze Card' source-code-audit.md "source fact freeze card"
|
|
507
|
+
require_grep 'Business conclusion' source-code-audit.md "source fact business conclusion"
|
|
508
|
+
require_grep 'understand.*locator' source-code-audit.md "understand-anything locator evidence"
|
|
509
|
+
require_grep 'Data model' source-code-audit.md "source fact data model"
|
|
510
|
+
require_grep 'All writers' source-code-audit.md "all writers inventory"
|
|
511
|
+
require_grep 'Real user entr' source-code-audit.md "real user entry"
|
|
512
|
+
require_grep 'Current callers' source-code-audit.md "current callers"
|
|
513
|
+
require_grep 'Legacy conflict' source-code-audit.md "legacy conflict"
|
|
514
|
+
require_grep 'DB (check|required|skip|reason)' source-code-audit.md "DB check or skip reason"
|
|
515
|
+
require_grep 'Conclusion level' source-code-audit.md "conclusion level"
|
|
516
|
+
require_grep 'owner.*decision' source-code-audit.md "owner decision boundary"
|
|
517
|
+
require_grep 'current' source-code-audit.md "current evidence classification"
|
|
518
|
+
require_grep 'legacy' source-code-audit.md "legacy evidence classification"
|
|
519
|
+
require_grep 'unmounted' source-code-audit.md "unmounted evidence classification"
|
|
520
|
+
require_grep 'data-model-only' source-code-audit.md "data-model-only evidence classification"
|
|
521
|
+
require_grep 'owner-confirmed' source-code-audit.md "owner-confirmed evidence classification"
|
|
522
|
+
require_grep 'blocked' source-code-audit.md "blocked evidence classification"
|
|
523
|
+
require_grep 'Evidence classifications.*current.*legacy.*unmounted.*data-model-only.*owner-confirmed.*blocked' source-code-audit.md "complete evidence classification set"
|
|
524
|
+
require_grep 'Question Eligibility Gate' source-code-audit.md "question eligibility gate"
|
|
525
|
+
require_grep 'Source search' source-code-audit.md "source search evidence"
|
|
526
|
+
require_grep 'Mapper.*SQL|SQL.*Mapper' source-code-audit.md "Mapper and SQL search evidence"
|
|
527
|
+
require_grep 'Frontend.*mini[- ]program.*H5' source-code-audit.md "frontend mini-program H5 caller search"
|
|
528
|
+
require_grep 'sibling.*repo' source-code-audit.md "sibling repository search"
|
|
529
|
+
if change_has_cardinality_conflict_signal; then
|
|
530
|
+
require_grep 'Conflict Audit' source-code-audit.md "cardinality conflict audit"
|
|
531
|
+
fi
|
|
532
|
+
}
|
|
533
|
+
|
|
338
534
|
change_has_fx_precision_risk() {
|
|
339
535
|
grep -RIEiq \
|
|
340
536
|
'(^|[^[:alnum:]_])(exchange rate|fx rate|currency conversion|cross.currency|base currency|quote currency)([^[:alnum:]_]|$)' \
|
|
@@ -347,13 +543,17 @@ change_has_fx_precision_risk() {
|
|
|
347
543
|
}
|
|
348
544
|
|
|
349
545
|
change_has_architecture_boundary_risk() {
|
|
350
|
-
|
|
546
|
+
local content
|
|
547
|
+
content="$(change_all_docs_without_complexity_budget)"
|
|
548
|
+
grep -Eiq \
|
|
351
549
|
'cross-repo|cross-service|sibling|SDK|MQ|topic|consumer|scheduler|scheduled|device|callback|third[- ]party|mini[- ]program|gateway|adapter|protocol|interconnect|call chain|entry|exit' \
|
|
352
|
-
|
|
550
|
+
<<< "$content"
|
|
353
551
|
}
|
|
354
552
|
|
|
355
|
-
|
|
356
|
-
find "$CHANGE_DIR" -path '*/prompt/*.md' -type f
|
|
553
|
+
prompt_rels() {
|
|
554
|
+
find "$CHANGE_DIR" -path '*/prompt/*.md' -type f -print \
|
|
555
|
+
| LC_ALL=C sort \
|
|
556
|
+
| sed "s#^$CHANGE_DIR/##"
|
|
357
557
|
}
|
|
358
558
|
|
|
359
559
|
require_any_prompt() {
|
|
@@ -363,7 +563,7 @@ require_any_prompt() {
|
|
|
363
563
|
}
|
|
364
564
|
|
|
365
565
|
require_prompt_set() {
|
|
366
|
-
local task_count prompt_count non_index_prompt_count
|
|
566
|
+
local task_count prompt_count non_index_prompt_count prompt_rel document
|
|
367
567
|
require_file prompt/implementation.md
|
|
368
568
|
task_count="$(grep -E '^[[:space:]]*-[[:space:]]+\[[ xX]\]' "$CHANGE_DIR/tasks.md" 2>/dev/null | wc -l | tr -d ' ')"
|
|
369
569
|
prompt_count="$(find "$CHANGE_DIR/prompt" -maxdepth 1 -type f -name '*.md' 2>/dev/null | wc -l | tr -d ' ')"
|
|
@@ -374,9 +574,15 @@ require_prompt_set() {
|
|
|
374
574
|
if [[ "$prompt_count" -eq 0 ]]; then
|
|
375
575
|
issues+=("missing prompt/*.md files")
|
|
376
576
|
fi
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
577
|
+
for document in tasks.md traceability-matrix.md sdd-quality-gate.md test-report.md; do
|
|
578
|
+
[[ -f "$CHANGE_DIR/$document" ]] || continue
|
|
579
|
+
while IFS= read -r prompt_rel; do
|
|
580
|
+
if ! grep -Fq "]($prompt_rel)" "$CHANGE_DIR/$document" \
|
|
581
|
+
&& ! grep -Fq "](./$prompt_rel)" "$CHANGE_DIR/$document"; then
|
|
582
|
+
issues+=("$document does not link $prompt_rel")
|
|
583
|
+
fi
|
|
584
|
+
done < <(prompt_rels)
|
|
585
|
+
done
|
|
380
586
|
}
|
|
381
587
|
|
|
382
588
|
require_money_precision_contract() {
|
|
@@ -460,6 +666,29 @@ require_money_precision_evidence() {
|
|
|
460
666
|
fi
|
|
461
667
|
}
|
|
462
668
|
|
|
669
|
+
require_minimal_design_review() {
|
|
670
|
+
local path="$1"
|
|
671
|
+
local label="$2"
|
|
672
|
+
require_grep 'Minimal Design Review|Complexity Reduction Review' "$path" "$label"
|
|
673
|
+
require_grep 'reuse|existing capability|existing module' "$path" "$label reuse evidence"
|
|
674
|
+
require_grep 'simplest|minimum design|minimal implementation' "$path" "$label simplest implementation"
|
|
675
|
+
require_grep 'removed|rejected|do not add|out of scope' "$path" "$label removed or rejected complexity"
|
|
676
|
+
require_grep 'New-item counts|Complexity budget' "$path" "$label complexity budget"
|
|
677
|
+
require_grep 'table' "$path" "$label table count"
|
|
678
|
+
require_grep 'field' "$path" "$label field count"
|
|
679
|
+
require_grep 'API' "$path" "$label API count"
|
|
680
|
+
require_grep 'service|component' "$path" "$label service/component count"
|
|
681
|
+
require_grep 'cache' "$path" "$label cache count"
|
|
682
|
+
require_grep 'MQ|event|async' "$path" "$label async/event count"
|
|
683
|
+
require_grep 'scheduled job|scheduler' "$path" "$label scheduled-job count"
|
|
684
|
+
require_grep 'compatibility layer' "$path" "$label compatibility-layer count"
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
require_minimal_design_pass() {
|
|
688
|
+
local path="$1"
|
|
689
|
+
require_grep '(Minimal Design Review|Complexity Reduction Review).*PASS|PASS.*(Minimal Design Review|Complexity Reduction Review)' "$path" "complexity reduction review PASS verdict"
|
|
690
|
+
}
|
|
691
|
+
|
|
463
692
|
transition_event=""
|
|
464
693
|
|
|
465
694
|
if [[ -x "$VALIDATE" && -f "$CHANGE_DIR/.sdd/state.yaml" ]]; then
|
|
@@ -489,6 +718,28 @@ case "$PHASE" in
|
|
|
489
718
|
require_grep 'RED|red-green|GREEN' tests.md "RED/GREEN test contract"
|
|
490
719
|
require_grep 'curl|Postman|Newman|pytest|RestAssured|automation command' tests.md "interface automation command"
|
|
491
720
|
require_grep 'handoff_hash|sdd-context|context package|anti-drift' sdd-quality-gate.md "handoff/context-drift gate"
|
|
721
|
+
if change_has_database_change; then
|
|
722
|
+
require_frozen_release_sql
|
|
723
|
+
fi
|
|
724
|
+
workflow="$(state_get workflow)"
|
|
725
|
+
if [[ "$workflow" == "full" ]]; then
|
|
726
|
+
require_file requirement-review.md
|
|
727
|
+
require_grep '^review_verdict:[[:space:]]*PASS[[:space:]]*$' requirement-review.md "requirement reverse review PASS verdict"
|
|
728
|
+
require_grep '^implementation_readiness:[[:space:]]*READY[[:space:]]*$' requirement-review.md "requirement review implementation readiness"
|
|
729
|
+
require_grep '^open_blockers:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement reverse review has no open blockers"
|
|
730
|
+
require_grep '^open_external_contracts:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement review has no open external contracts"
|
|
731
|
+
require_grep '^open_source_investigations:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement review has no open source investigations"
|
|
732
|
+
require_grep '^open_owner_decisions:[[:space:]]*0[[:space:]]*$' requirement-review.md "requirement review has no open owner decisions"
|
|
733
|
+
require_grep 'Closure Matrix' requirement-review.md "requirement review closure matrix"
|
|
734
|
+
require_grep 'Review Findings' requirement-review.md "requirement review findings"
|
|
735
|
+
require_grep 'Open Blockers' requirement-review.md "requirement review open blocker ledger"
|
|
736
|
+
require_minimal_design_review design.md "complexity reduction review"
|
|
737
|
+
require_grep 'Minimal Design Review|Complexity Reduction Review' sdd-quality-gate.md "complexity reduction quality gate"
|
|
738
|
+
require_minimal_design_pass sdd-quality-gate.md
|
|
739
|
+
if change_has_source_fact_risk; then
|
|
740
|
+
require_source_fact_audit
|
|
741
|
+
fi
|
|
742
|
+
fi
|
|
492
743
|
if change_has_money_precision_risk; then
|
|
493
744
|
require_grep 'Money Precision Boundary' sdd-quality-gate.md "money precision quality gate"
|
|
494
745
|
fi
|
|
@@ -518,8 +769,14 @@ case "$PHASE" in
|
|
|
518
769
|
require_handoff_current
|
|
519
770
|
require_beta_handoff_structure
|
|
520
771
|
require_hash_recorded
|
|
772
|
+
if change_has_database_change; then
|
|
773
|
+
require_frozen_release_sql
|
|
774
|
+
fi
|
|
521
775
|
workflow="$(state_get workflow)"
|
|
522
776
|
if [[ "$workflow" == "full" ]]; then
|
|
777
|
+
require_minimal_design_review design.md "complexity reduction review"
|
|
778
|
+
require_grep 'Minimal Design Review|Complexity Reduction Review' sdd-quality-gate.md "complexity reduction quality gate"
|
|
779
|
+
require_minimal_design_pass sdd-quality-gate.md
|
|
523
780
|
require_optional_state_path technical_design "technical_design"
|
|
524
781
|
technical_design_rel="$(state_get technical_design)"
|
|
525
782
|
if [[ -n "${technical_design_rel:-}" && "$technical_design_rel" != "null" ]]; then
|
|
@@ -540,6 +797,7 @@ case "$PHASE" in
|
|
|
540
797
|
if change_has_money_precision_risk; then
|
|
541
798
|
require_money_precision_contract "$technical_design_rel" "money precision boundary"
|
|
542
799
|
fi
|
|
800
|
+
require_minimal_design_review "$technical_design_rel" "technical design minimal design review"
|
|
543
801
|
fi
|
|
544
802
|
fi
|
|
545
803
|
require_grep 'Superpowers Technical Design Handoff|Superpowers Technical Design|technical_design|source-level HOW' design.md "Superpowers technical design handoff"
|
|
@@ -553,11 +811,14 @@ case "$PHASE" in
|
|
|
553
811
|
require_handoff_current
|
|
554
812
|
require_beta_handoff_structure
|
|
555
813
|
require_hash_recorded
|
|
814
|
+
if change_has_database_change; then
|
|
815
|
+
require_frozen_release_sql
|
|
816
|
+
fi
|
|
556
817
|
require_any_prompt
|
|
557
818
|
require_prompt_set
|
|
558
819
|
require_grep 'OpenSpec/SDD|canonical design source|canonical|source of truth' design.md "canonical source boundary"
|
|
559
|
-
prompt_rel
|
|
560
|
-
|
|
820
|
+
while IFS= read -r prompt_rel; do
|
|
821
|
+
[[ -n "${prompt_rel:-}" ]] || continue
|
|
561
822
|
require_grep 'Superpowers Technical Design inheritance|Superpowers execution strategy inheritance|technical_design|source-level HOW' "$prompt_rel" "prompt Superpower strategy inheritance"
|
|
562
823
|
technical_design_rel="$(state_get technical_design)"
|
|
563
824
|
if [[ -n "${technical_design_rel:-}" && "$technical_design_rel" != "null" ]]; then
|
|
@@ -576,7 +837,11 @@ case "$PHASE" in
|
|
|
576
837
|
fi
|
|
577
838
|
fi
|
|
578
839
|
require_grep 'context anti-drift|handoff_hash|sdd-context' "$prompt_rel" "prompt context drift inheritance"
|
|
579
|
-
|
|
840
|
+
if change_has_database_change; then
|
|
841
|
+
require_grep 'release-sql\.md' "$prompt_rel" "prompt frozen release SQL reference"
|
|
842
|
+
require_grep 'verbatim|sql_sha256' "$prompt_rel" "prompt verbatim SQL copy contract"
|
|
843
|
+
fi
|
|
844
|
+
done < <(prompt_rels)
|
|
580
845
|
require_state_value build_mode "build_mode"
|
|
581
846
|
require_state_value isolation "isolation"
|
|
582
847
|
require_state_value tdd_mode "tdd_mode"
|
|
@@ -244,10 +244,13 @@ sync_state() {
|
|
|
244
244
|
"$state_sh" set "$CHANGE_DIR" context_compression "$context_compression"
|
|
245
245
|
"$state_sh" set "$CHANGE_DIR" handoff_context .sdd/handoff/sdd-context.json
|
|
246
246
|
"$state_sh" set "$CHANGE_DIR" handoff_hash "$context_hash"
|
|
247
|
-
technical_design_rel="
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
technical_design_rel=""
|
|
248
|
+
if [[ -d "$CHANGE_DIR/docs/superpowers/specs" ]]; then
|
|
249
|
+
technical_design_rel="$(
|
|
250
|
+
find "$CHANGE_DIR/docs/superpowers/specs" -maxdepth 1 -type f -name '*.md' \
|
|
251
|
+
| sort | head -n 1 | sed "s#^$CHANGE_DIR/##"
|
|
252
|
+
)"
|
|
253
|
+
fi
|
|
251
254
|
if [[ -n "$technical_design_rel" ]]; then
|
|
252
255
|
"$state_sh" set "$CHANGE_DIR" technical_design "$technical_design_rel"
|
|
253
256
|
fi
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: superflow-requirement-review
|
|
3
|
+
description: Perform source-backed reverse review of clarified requirements and OpenSpec/SDD drafts to find closure gaps, factual conflicts, missing scenarios, over-design, under-design, API/UI/DB/test drift, and unverifiable contracts, then drive remediation and re-review. Use for requirement review, reverse review, challenge the design, find omissions, testability review, or pre-design/pre-implementation review.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Superflow Requirement Review
|
|
7
|
+
|
|
8
|
+
Independently challenge the current OpenSpec change with source-backed evidence. This is not
|
|
9
|
+
an advisory side path: blocking findings must repair canonical documents and pass re-review
|
|
10
|
+
before the docs phase can close.
|
|
11
|
+
|
|
12
|
+
## Boundaries
|
|
13
|
+
|
|
14
|
+
- Use after complex requirements are clarified and reviewable drafts exist.
|
|
15
|
+
- Do not replace owner clarification or source/Mapper/DB/real-caller verification.
|
|
16
|
+
- Keep all output inside the current `openspec/changes/<change>/`.
|
|
17
|
+
- Do not stop at a findings list; repair canonical documents and re-review.
|
|
18
|
+
- Do not add speculative tables, APIs, services, caches, states, or compatibility layers.
|
|
19
|
+
|
|
20
|
+
## Required Inputs
|
|
21
|
+
|
|
22
|
+
Read the applicable source index, feature gates, proposal, API, specs, design, source audit,
|
|
23
|
+
database contract, frozen release SQL, tasks, tests, traceability, quality gate, test report,
|
|
24
|
+
current source, Mapper/XML, real frontend/mini-program/H5 callers, sibling repositories, and
|
|
25
|
+
read-only database evidence when needed. Missing evidence is a finding, not permission to guess.
|
|
26
|
+
|
|
27
|
+
## Workflow
|
|
28
|
+
|
|
29
|
+
1. Record the change, phase, bounded feature, sources, handoff hash, and confirmed/pending
|
|
30
|
+
decisions. Review one frozen feature at a time.
|
|
31
|
+
2. Establish evidence through platform impact discovery, source, Mapper/SQL, real callers, and
|
|
32
|
+
read-only DB checks. Treat graph output only as a locator. Classify evidence as `current`,
|
|
33
|
+
`legacy`, `unmounted`, `data-model-only`, `owner-confirmed`, or `blocked`.
|
|
34
|
+
Classify every unresolved item by resolution ownership:
|
|
35
|
+
- `SOURCE_INVESTIGATION`: source, dependency, configuration, logs, or read-only DB can resolve
|
|
36
|
+
it. Continue investigating; do not ask the user or exit review.
|
|
37
|
+
- `OWNER_DECISION`: multiple valid product choices remain. Return to clarification and ask one
|
|
38
|
+
decision at a time.
|
|
39
|
+
- `EXTERNAL_CONTRACT`: third-party/cross-service request, response, signing, idempotency,
|
|
40
|
+
enum, callback, or responsibility contract. If it changes API, SQL, state, security, or test
|
|
41
|
+
assertions, it blocks PASS until evidence freezes it; merely documenting `Blocked` is not
|
|
42
|
+
closure.
|
|
43
|
+
- `EXECUTION_EVIDENCE`: implementation contract is frozen and only deployment, migration,
|
|
44
|
+
real-call, or runtime evidence remains. It may block delivery, not requirement review.
|
|
45
|
+
3. Reverse-check six dimensions:
|
|
46
|
+
- business closure: input, trigger, precondition, processing, output, failure, recovery, repeat;
|
|
47
|
+
- source facts: real entry, all writers/readers/filters, legacy behavior, cross-repo consumers;
|
|
48
|
+
- contract consistency: PRD/UI/API/DTO/DB/status/SQL/tests/tasks;
|
|
49
|
+
- failure boundaries: authorization, concurrency, idempotency, timeout, uncertainty, ordering;
|
|
50
|
+
- minimal design: reuse, duplicate fields, parallel APIs, speculative abstractions;
|
|
51
|
+
- deliverability: task, RED/GREEN, real entry, DB/log evidence, acceptance result.
|
|
52
|
+
4. For database-backed changes, invoke `superflow-table-impact-analysis`, or record an equivalent
|
|
53
|
+
downgrade when unavailable.
|
|
54
|
+
5. Create or update `requirement-review.md` with baseline, closure matrix, findings, minimal-design
|
|
55
|
+
review, remediation evidence, and final verdict. Its front matter must record the exact
|
|
56
|
+
machine-readable result. PASS requires `review_verdict: PASS`,
|
|
57
|
+
`implementation_readiness: READY`, `open_blockers: 0`, `open_external_contracts: 0`,
|
|
58
|
+
`open_source_investigations: 0`, and `open_owner_decisions: 0`; otherwise use BLOCKED and real
|
|
59
|
+
counts. Include an `Open Blockers` table with category, affected implementation contract,
|
|
60
|
+
resolution owner, next evidence/question, and status.
|
|
61
|
+
|
|
62
|
+
Use finding levels:
|
|
63
|
+
|
|
64
|
+
- `BLOCKER`: incorrect requirement fact, API/DB/status/security/entry/acceptance contract.
|
|
65
|
+
- `IMPORTANT`: likely omission, rework, or untestable behavior that docs must correct.
|
|
66
|
+
- `SUGGESTION`: non-blocking improvement for owner judgment.
|
|
67
|
+
|
|
68
|
+
Each finding records ID, level, dimension, location, issue, evidence, impact, minimal correction,
|
|
69
|
+
and status.
|
|
70
|
+
|
|
71
|
+
## Remediation And Re-review
|
|
72
|
+
|
|
73
|
+
For every confirmed `BLOCKER/IMPORTANT` finding:
|
|
74
|
+
|
|
75
|
+
1. Repair the canonical source document, not only the review report.
|
|
76
|
+
2. Synchronize affected API, design, spec, SQL, tasks, tests, traceability, and quality gates.
|
|
77
|
+
3. Record `finding -> repaired file -> test/evidence` closure.
|
|
78
|
+
4. Return to `superflow-clarify` if remediation changes an owner-confirmed contract.
|
|
79
|
+
|
|
80
|
+
Re-review from the original sources and code evidence. Pass only when all blocking/important
|
|
81
|
+
findings are closed, contract drift is explained, minimal-design review passes, source
|
|
82
|
+
investigations are exhausted, owner decisions are recorded, and implementation-affecting
|
|
83
|
+
external contracts are evidenced and frozen. Only execution evidence that cannot change the
|
|
84
|
+
implementation contract may remain blocked in tests or release readiness.
|
|
85
|
+
|
|
86
|
+
After remediation, refresh handoff, run the docs guard and strict OpenSpec validation, and record
|
|
87
|
+
the report path and verdict in `sdd-quality-gate.md` and `test-report.md`.
|
|
88
|
+
|
|
89
|
+
## Prohibitions
|
|
90
|
+
|
|
91
|
+
- Do not review product text without source and real-entry evidence.
|
|
92
|
+
- Do not infer current behavior from a permissive data model.
|
|
93
|
+
- Do not accept non-null values, HTTP 200, or compilation as semantic correctness.
|
|
94
|
+
- Do not invent fallbacks, defaults, states, or compatibility layers to close findings.
|
|
95
|
+
- Do not store findings in another workflow namespace.
|
|
96
|
+
- Do not pass docs/design with unresolved blocking findings.
|
|
97
|
+
- Do not close an implementation-affecting external contract because it is documented, assigned
|
|
98
|
+
to an owner, or deferred to integration.
|
|
99
|
+
- Do not combine `review_verdict: PASS` with `implementation_readiness: BLOCKED`.
|