@chenmk/superflow 0.2.4 → 0.3.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.
Files changed (61) hide show
  1. package/README.md +4 -1
  2. package/README.zh-CN.md +1 -0
  3. package/assets/manifest.json +3 -1
  4. package/assets/prompts/superflow-clarify.md +6 -0
  5. package/assets/prompts/superflow-pipeline.md +8 -0
  6. package/assets/scripts/superflow-archive-command-hook.sh +80 -0
  7. package/assets/scripts/superflow-delivery-check.sh +23 -4
  8. package/assets/skills/superflow-archive/SKILL.md +5 -0
  9. package/assets/skills/superflow-clarify/SKILL.md +26 -7
  10. package/assets/skills/superflow-design/SKILL.md +46 -5
  11. package/assets/skills/superflow-docs/SKILL.md +27 -0
  12. package/assets/skills/superflow-implement/SKILL.md +17 -0
  13. package/assets/skills/superflow-pipeline/SKILL.md +47 -0
  14. package/assets/skills/superflow-pipeline/references/api-design-template.md +11 -0
  15. package/assets/skills/superflow-pipeline/references/batch-prompt-template.md +44 -0
  16. package/assets/skills/superflow-pipeline/references/implementation-prompt-template.md +48 -0
  17. package/assets/skills/superflow-pipeline/references/money-precision-algorithms.md +85 -0
  18. package/assets/skills/superflow-pipeline/references/quality-gate.md +3 -0
  19. package/assets/skills/superflow-pipeline/references/reviewer-checklist.md +17 -1
  20. package/assets/skills/superflow-pipeline/references/superpower-technical-design-template.md +90 -0
  21. package/assets/skills/superflow-pipeline/references/test-execution-template.md +26 -0
  22. package/assets/skills/superflow-pipeline/scripts/superflow-guard.sh +231 -0
  23. package/assets/skills/superflow-verify/SKILL.md +23 -1
  24. package/assets/skills-en/superflow-archive/SKILL.md +6 -0
  25. package/assets/skills-en/superflow-clarify/SKILL.md +26 -7
  26. package/assets/skills-en/superflow-design/SKILL.md +45 -4
  27. package/assets/skills-en/superflow-docs/SKILL.md +27 -0
  28. package/assets/skills-en/superflow-implement/SKILL.md +10 -0
  29. package/assets/skills-en/superflow-pipeline/SKILL.md +38 -0
  30. package/assets/skills-en/superflow-pipeline/references/api-design-template.md +13 -0
  31. package/assets/skills-en/superflow-pipeline/references/batch-prompt-template.md +28 -0
  32. package/assets/skills-en/superflow-pipeline/references/implementation-prompt-template.md +33 -0
  33. package/assets/skills-en/superflow-pipeline/references/money-precision-algorithms.md +96 -0
  34. package/assets/skills-en/superflow-pipeline/references/quality-gate.md +26 -0
  35. package/assets/skills-en/superflow-pipeline/references/reviewer-checklist.md +15 -0
  36. package/assets/skills-en/superflow-pipeline/references/superpower-technical-design-template.md +95 -0
  37. package/assets/skills-en/superflow-pipeline/references/test-execution-template.md +30 -0
  38. package/assets/skills-en/superflow-pipeline/scripts/superflow-guard.sh +231 -0
  39. package/assets/skills-en/superflow-verify/SKILL.md +24 -1
  40. package/dist/app/commands/archive.js +7 -3
  41. package/dist/app/commands/archive.js.map +1 -1
  42. package/dist/app/commands/change-guard.js +27 -0
  43. package/dist/app/commands/change-guard.js.map +1 -0
  44. package/dist/app/commands/design.js +2 -20
  45. package/dist/app/commands/design.js.map +1 -1
  46. package/dist/app/commands/init.js +1 -5
  47. package/dist/app/commands/init.js.map +1 -1
  48. package/dist/app/commands/update.js +2 -5
  49. package/dist/app/commands/update.js.map +1 -1
  50. package/dist/app/commands/verify.js +7 -3
  51. package/dist/app/commands/verify.js.map +1 -1
  52. package/dist/domains/config/context.js +1 -5
  53. package/dist/domains/config/context.js.map +1 -1
  54. package/dist/domains/deps.js +1 -5
  55. package/dist/domains/deps.js.map +1 -1
  56. package/dist/domains/hook.js +1 -0
  57. package/dist/domains/hook.js.map +1 -1
  58. package/dist/platform/assets.js +9 -0
  59. package/dist/platform/assets.js.map +1 -0
  60. package/package.json +3 -2
  61. package/scripts/release-notes-check.js +102 -0
@@ -59,6 +59,52 @@ orchestrator unless the OpenSpec/SDD contract explicitly says that module owns
59
59
  the new entry point and records the owner approval. If the correct owner is
60
60
  unclear, mark the design blocked.
61
61
 
62
+ ## External Integration Configuration And Deployment Contract
63
+
64
+ Use this whenever the change integrates with a third-party platform/tool, SDK,
65
+ MQ/Kafka, callback, payment gateway, cloud service, or other external system.
66
+
67
+ | External dependency/resource | Config/resource item | Local source/provisioning | Test source/provisioning | Production source/provisioning | Injection/creation method | Runtime owner | Provisioning owner/time | Readiness evidence | Rollback | Secret handling | Blocker |
68
+ | ---------------------------- | -------------------- | ------------------------- | ------------------------ | ------------------------------ | ------------------------- | ------------- | ----------------------- | ------------------ | -------- | --------------- | ------- |
69
+ | `<TDMQ>` | `<Consumer Group>` | `<auto/manual/IaC>` | `<existing resource>` | `<pre-created by ops>` | `<config/secret/IaC/console>` | `<service>` | `<owner + before deploy>` | `<console/API/trace>` | `<disable/rollback>` | `<secret reference only>` | `<none/blocker>` |
70
+
71
+ Required checks:
72
+
73
+ ```bash
74
+ rg -ni "https?://|endpoint|base.?url|app.?id|tenant|project.?id|topic|tag|consumer.?group|namespace|webhook|acl|role|secret|token|password|timeout" <source-and-config-paths>
75
+ rg -ni "@.*Listener|new.*Client|builder\(|System\.getenv|ConfigurationProperties|Value\(" <source-and-config-paths>
76
+ ```
77
+
78
+ Do not hard-code environment-dependent endpoints, resource names, identifiers,
79
+ credentials, ACLs, or operational switches in annotations, constants, or
80
+ business code. Stable protocol constants may remain code constants only when
81
+ the design proves they are not environment-specific and no server-side
82
+ resource must be provisioned. Test auto-creation, a successful local startup,
83
+ or an already-existing test resource is not evidence that production is
84
+ ready. Every server-side resource must have an explicit production owner,
85
+ creation timing, readiness check, and rollback path. Missing production
86
+ provisioning evidence is a blocker.
87
+
88
+ ## Concurrency And Idempotency Ownership
89
+
90
+ Complete this section for concurrent requests, batch issue/activation/renewal,
91
+ duplicate callbacks, duplicate consumption, or repeated external delivery.
92
+
93
+ | Scenario | Business idempotency key | Claim owner/resource | Application-layer atomic claim | Short transaction boundary | State machine | Retry code reuse | External-call boundary | Uncertain-result handling | Unique-index role | Test evidence |
94
+ | -------- | ------------------------ | -------------------- | ------------------------------ | -------------------------- | ------------- | ---------------- | ---------------------- | ------------------------- | ----------------- | ------------- |
95
+ | `<batch issue>` | `<package+vehicle+period>` | `<period row>` | `<lock owner then persist PENDING>` | `<commit claim independently>` | `PENDING/SUCCESS/FAILED` | `<reuse original business code>` | `<call after commit>` | `<block duplicates and reconcile>` | `<not default; optional fallback>` | `<concurrent/duplicate/retry cases>` |
96
+
97
+ Application-layer atomic claim is the default: use a stable business
98
+ idempotency key, lock an explicit owner resource in a short transaction,
99
+ persist `PENDING`, commit, and release the database lock before the external
100
+ call. Update the state after the call; every retry reuses the original business
101
+ code. An uncertain result blocks duplicate delivery and remains reconcilable.
102
+ Do not use check-then-insert, process-local locks, or random IDs as cross-instance
103
+ idempotency, and do not hold a database lock across an external call. A unique
104
+ index is not the default; it is only an optional database fallback when natural
105
+ uniqueness, historical cleanup, NULL/soft-delete behavior, and conflict handling
106
+ are explicitly contracted.
107
+
62
108
  ## Field And Status Reverse Impact
63
109
 
64
110
  Use this whenever changing field values, enum/status values, derived fields,
@@ -83,6 +129,52 @@ third-party adapters, and sibling repos when the table or DTO is shared.
83
129
  The technical design must say which references are intentionally unchanged and
84
130
  why. A change is not ready when only the direct setter/writer is designed.
85
131
 
132
+ ## Money Precision Boundary
133
+
134
+ Use this whenever the change involves amount, fee, discount, deduction, refund,
135
+ sharing, payment, invoice, balance, electricity fee, service fee, package
136
+ settlement, proration, allocation, reconciliation, or financial display.
137
+
138
+ | Amount identity | Authoritative total | Exact type/construction | Currency and unit | Calculation-state source | Rounding level/boundary | Scale/mode/source | Allocation strategy/tie-breaker | Complement derivation | Audit evidence | Test evidence |
139
+ |---|---|---|---|---|---|---|---|---|---|---|
140
+ | `original = discount + actual` | `original` | `<BigDecimal from string>` | `<currency; internal scale; provider minor unit>` | `<rate * quantity>` | `<order/payment adapter>` | `<scale/mode/contract>` | `<largest remainder/business key>` | `actual = original - discount` | `<pre/post round; residual recipient>` | `<positive/zero/refund/half-unit/tied residual IDs>` |
141
+
142
+ Use `money-precision-algorithms.md` to complete the contract. State exact
143
+ representation and construction; currency and ISO/provider minor-unit boundary;
144
+ rounding level, mode, and policy source; residual strategy and stable
145
+ tie-breaker; negative/refund symmetry; persistence precision/scale and overflow
146
+ checks. Never assume every currency has two decimals or treat implicit database
147
+ conversion as the rounding policy.
148
+
149
+ For FX changes, additionally record:
150
+
151
+ | Base/quote | Rate source/time | Rate precision | Canonical path | Target unit/rounding | Round-trip tolerance | Evidence |
152
+ |---|---|---|---|---|---|---|
153
+ | `<base/quote>` | `<source/timestamp>` | `<scale>` | `<direct/triangulated order>` | `<currency/provider rule>` | `<contract tolerance>` | `<case IDs>` |
154
+
155
+ Required precision checks:
156
+
157
+ ```bash
158
+ rg -ni "setScale|round|RoundingMode|BigDecimal|double|float|money\\(" <source-and-test-paths>
159
+ rg -ni "amount|fee|price|discount|deduction|refund|pay|invoice|balance|serviceFee|chargeFee" <source-and-test-paths>
160
+ ```
161
+
162
+ The design must separate calculation-state money from settlement/display-state
163
+ money. Intermediate calculations must keep original rate, product, proportion,
164
+ process evidence, and allocation precision. Round only at explicit outbound
165
+ boundaries such as settlement posting, persistence fields that require cents,
166
+ payment/fiscal interfaces, invoices, exports, or display. For multi-detail
167
+ allocation, compute the high-precision target first, then distribute the final
168
+ rounded amount deterministically so totals match and identities such as
169
+ `original = discount + actual` hold. When an additive identity exists and its
170
+ total is the authoritative source, calculate only the required N-1 components
171
+ independently and derive the final complement as `authoritative total - sum(other
172
+ components)`. Do not independently calculate and round every component and then
173
+ rebuild the authoritative total. If complement derivation is not applicable,
174
+ record why, identify the actual source of truth, and provide owner evidence.
175
+ Do not calculate later slices, discounts, ratios, or unit prices from
176
+ already-rounded money.
177
+
86
178
  ## Execution Architecture
87
179
 
88
180
  - Worker boundaries:
@@ -119,6 +211,9 @@ why. A change is not ready when only the direct setter/writer is designed.
119
211
  that only shows "can call through this module" is not ready.
120
212
  - For field/status changes, prove reverse impact before coding: writers,
121
213
  readers, filters, derived sync paths, external consumers, and tests.
214
+ - For money changes, prove the precision boundary before coding: calculation
215
+ state, settlement/display state, final rounding point, allocation rule, and
216
+ half-cent/residual tests.
122
217
  - Do not invent API fields, DB columns, status semantics, fallback behavior, or
123
218
  acceptance criteria.
124
219
  - Keep unresolved source facts as blockers. Do not convert them to guesses.
@@ -20,3 +20,33 @@
20
20
  - Result:
21
21
  - Evidence:
22
22
  - Blocker if not executed:
23
+
24
+ ## Money Precision Boundary Evidence
25
+
26
+ Required when monetary calculation, settlement, proration, allocation,
27
+ reconciliation, or financial display changes:
28
+
29
+ | Case | Identity/authoritative total | Currency/minor unit | Complement | Pre/post round | Strategy/residual recipient | Positive/zero/refund/tied residual | Reconciliation |
30
+ |---|---|---|---|---|---|---|---|
31
+ | TC-M01 | `original = discount + actual` / `original` | CNY/minor unit | `actual = original - discount` | | largest remainder / | | pass/blocked |
32
+
33
+ Prove that calculation-state values were not rounded before the confirmed final
34
+ boundary and that original, discount, actual, refund, and allocated totals obey
35
+ the design contract. When an authoritative total exists, prove the final
36
+ component was derived by subtraction instead of independently calculated and
37
+ rounded. Record currency, provider minor unit, pre/post-round values, residual
38
+ recipient, and positive/zero/negative or refund, tied remainder, and idempotent
39
+ recalculation evidence. FX cases also record base/quote, rate source, and target
40
+ settlement rounding. A two-decimal display assertion alone is insufficient.
41
+
42
+ ## Closeout
43
+
44
+ Verification Result: PASS / FAIL / BLOCKED / PARTIALLY_VERIFIED
45
+ Archive Readiness: PASS / BLOCKED
46
+
47
+ Required for `verify_mode: full`:
48
+
49
+ - Test environment:
50
+ - Branch/commit/build number or image:
51
+ - Base URL:
52
+ - Verification timestamp:
@@ -178,6 +178,60 @@ require_state_file() {
178
178
  require_file .sdd/state.yaml
179
179
  }
180
180
 
181
+ require_tasks_complete() {
182
+ local task_count unchecked_count
183
+ require_file tasks.md
184
+ [[ -f "$CHANGE_DIR/tasks.md" ]] || return 0
185
+ task_count="$(grep -Ec '^[[:space:]]*-[[:space:]]+\[[ xX]\]' "$CHANGE_DIR/tasks.md" || true)"
186
+ unchecked_count="$(grep -Ec '^[[:space:]]*-[[:space:]]+\[[[:space:]]\]' "$CHANGE_DIR/tasks.md" || true)"
187
+ [[ "$task_count" -gt 0 ]] || issues+=("tasks.md has no checkbox tasks")
188
+ [[ "$unchecked_count" -eq 0 ]] || issues+=("$unchecked_count unchecked task(s) remain in tasks.md")
189
+ }
190
+
191
+ verification_report_path() {
192
+ local value
193
+ value="$(state_get verification_report)"
194
+ [[ -n "$value" && "$value" != "null" ]] || return 1
195
+ if [[ -f "$CHANGE_DIR/$value" ]]; then
196
+ printf '%s\n' "$CHANGE_DIR/$value"
197
+ return 0
198
+ fi
199
+ if [[ -f "$value" ]]; then
200
+ printf '%s\n' "$value"
201
+ return 0
202
+ fi
203
+ return 1
204
+ }
205
+
206
+ require_closeout_markers() {
207
+ local report="${1:-$CHANGE_DIR/test-report.md}"
208
+ if [[ ! -f "$report" ]]; then
209
+ issues+=("verification report path does not exist: $report")
210
+ return 0
211
+ fi
212
+ if ! grep -Eiq '(Verification Result)[[:space:]:|*-]*(PASS)' "$report"; then
213
+ issues+=("verification result PASS marker not found in verification report")
214
+ fi
215
+ if ! grep -Eiq '(Archive Readiness)[[:space:]:|*-]*(PASS|READY)' "$report"; then
216
+ issues+=("archive readiness PASS marker not found in verification report")
217
+ fi
218
+ }
219
+
220
+ require_branch_handled() {
221
+ local branch_status
222
+ branch_status="$(state_get branch_status)"
223
+ [[ "$branch_status" == "handled" ]] || issues+=("branch_status must be handled before verification closeout")
224
+ }
225
+
226
+ require_full_verification_fingerprint() {
227
+ local report="$CHANGE_DIR/test-report.md"
228
+ [[ "$(state_get verify_mode)" == "full" ]] || return 0
229
+ require_grep 'test environment|staging|sandbox' "$report" "full verification test environment"
230
+ require_grep 'branch|commit|tag|build|image' "$report" "full verification deployment fingerprint"
231
+ require_grep 'https?://|Base URL' "$report" "full verification base URL"
232
+ require_grep 'timestamp|verified[_ -]?at|20[0-9]{2}-[0-9]{2}-[0-9]{2}' "$report" "full verification timestamp"
233
+ }
234
+
181
235
  require_spec_doc() {
182
236
  if [[ -f "$CHANGE_DIR/spec.md" ]]; then
183
237
  return
@@ -248,6 +302,50 @@ change_has_field_status_risk() {
248
302
  "$CHANGE_DIR"/*.md "$CHANGE_DIR"/**/*.md 2>/dev/null
249
303
  }
250
304
 
305
+ change_has_external_config_risk() {
306
+ grep -RIEiq \
307
+ 'third[- ]party|external (platform|tool|integration|system)|SDK|MQ|Kafka|RocketMQ|TDMQ|callback|webhook|payment gateway|cloud service' \
308
+ "$CHANGE_DIR/proposal.md" \
309
+ "$CHANGE_DIR/api.md" \
310
+ "$CHANGE_DIR/design.md" \
311
+ "$CHANGE_DIR/tests.md" \
312
+ "$CHANGE_DIR/spec.md" \
313
+ "$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
314
+ }
315
+
316
+ change_has_concurrency_idempotency_risk() {
317
+ grep -RIEiq \
318
+ 'concurren|idempoten|race condition|duplicate (request|callback|consumption|delivery)|atomic claim|batch (issue|activate|renew)' \
319
+ "$CHANGE_DIR/proposal.md" \
320
+ "$CHANGE_DIR/api.md" \
321
+ "$CHANGE_DIR/design.md" \
322
+ "$CHANGE_DIR/tests.md" \
323
+ "$CHANGE_DIR/spec.md" \
324
+ "$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
325
+ }
326
+
327
+ change_has_money_precision_risk() {
328
+ grep -RIEiq \
329
+ '(^|[^[: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
+ "$CHANGE_DIR/proposal.md" \
331
+ "$CHANGE_DIR/api.md" \
332
+ "$CHANGE_DIR/design.md" \
333
+ "$CHANGE_DIR/tests.md" \
334
+ "$CHANGE_DIR/spec.md" \
335
+ "$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
336
+ }
337
+
338
+ change_has_fx_precision_risk() {
339
+ grep -RIEiq \
340
+ '(^|[^[:alnum:]_])(exchange rate|fx rate|currency conversion|cross.currency|base currency|quote currency)([^[:alnum:]_]|$)' \
341
+ "$CHANGE_DIR/proposal.md" \
342
+ "$CHANGE_DIR/api.md" \
343
+ "$CHANGE_DIR/design.md" \
344
+ "$CHANGE_DIR/tests.md" \
345
+ "$CHANGE_DIR/spec.md" \
346
+ "$CHANGE_DIR"/specs/*/spec.md 2>/dev/null
347
+ }
348
+
251
349
  change_has_architecture_boundary_risk() {
252
350
  grep -RIEiq \
253
351
  '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' \
@@ -281,6 +379,87 @@ require_prompt_set() {
281
379
  fi
282
380
  }
283
381
 
382
+ require_money_precision_contract() {
383
+ local path="$1"
384
+ local label="$2"
385
+ require_grep 'Money Precision Boundary' "$path" "$label"
386
+ require_grep 'calculation.state|calculation source|intermediate precision' "$path" "$label calculation state"
387
+ require_grep 'settlement|display.state|rounding boundary' "$path" "$label settlement/display boundary"
388
+ require_grep 'scale|rounding mode|RoundingMode' "$path" "$label scale and rounding mode"
389
+ require_grep 'allocation|reconciliation|residual' "$path" "$label allocation/reconciliation rule"
390
+ require_grep 'authoritative total|source.of.truth total' "$path" "$label authoritative total"
391
+ require_grep 'authoritative total.*minus|derive.*complement|complement amount' "$path" "$label complement derivation"
392
+ require_grep 'do not.*independently|must not.*calculate.*separately' "$path" "$label independent calculation prohibition"
393
+ require_grep 'forbidden early rounding|do not.*round' "$path" "$label forbidden early rounding"
394
+ require_grep 'half.cent|residual|multi.detail' "$path" "$label boundary test evidence"
395
+ require_grep 'BigDecimal|MonetaryAmount|integer minor unit|exact decimal' "$path" "$label exact representation"
396
+ require_grep 'never.*(float|double)|do not.*(float|double)' "$path" "$label binary floating-point prohibition"
397
+ require_grep 'currency' "$path" "$label currency contract"
398
+ require_grep 'minor unit|provider unit' "$path" "$label minor-unit boundary"
399
+ require_grep 'rounding level|rounding point|line.level.*aggregate' "$path" "$label rounding level"
400
+ require_grep 'policy source|contract source' "$path" "$label rounding policy source"
401
+ require_grep 'largest remainder|stable tie.break|business key' "$path" "$label deterministic residual tie-breaker"
402
+ require_grep 'positive.*zero.*negative|positive.*refund' "$path" "$label signed-value evidence"
403
+ require_grep 'pre.round.*post.round' "$path" "$label rounding audit evidence"
404
+ require_grep 'DECIMAL|NUMERIC|persistence.*not applicable' "$path" "$label persistence precision contract"
405
+ if change_has_fx_precision_risk; then
406
+ require_grep 'base/quote|base currency.*quote currency' "$path" "$label FX direction"
407
+ require_grep 'rate source' "$path" "$label FX source"
408
+ require_grep 'rate.*timestamp|rate.*effective' "$path" "$label FX timestamp"
409
+ require_grep 'canonical conversion path|canonical path' "$path" "$label FX canonical path"
410
+ require_grep 'target.*settlement.*round' "$path" "$label FX target rounding"
411
+ fi
412
+ }
413
+
414
+ require_external_config_contract() {
415
+ local path="$1"
416
+ local label="$2"
417
+ require_grep 'External Integration Configuration And Deployment Contract' "$path" "$label"
418
+ require_grep 'local.*test.*production|local.*staging.*production' "$path" "$label environment matrix"
419
+ require_grep 'provision|injection|IaC|Secret|console' "$path" "$label injection/provisioning"
420
+ require_grep 'provisioning owner|runtime owner|owner.*time' "$path" "$label owner and timing"
421
+ require_grep 'readiness|trace|health' "$path" "$label readiness evidence"
422
+ require_grep 'rollback|disable' "$path" "$label rollback"
423
+ require_grep 'secret|credential' "$path" "$label secret handling"
424
+ require_grep 'not.*hard.?cod|must not.*hard.?cod|do not hard.?code' "$path" "$label no hard-coded external config"
425
+ require_grep 'test.*production|staging.*production' "$path" "$label test-production distinction"
426
+ }
427
+
428
+ require_concurrency_idempotency_contract() {
429
+ local path="$1"
430
+ local label="$2"
431
+ require_grep 'Concurrency And Idempotency Ownership|application.layer atomic claim|atomic claim' "$path" "$label"
432
+ require_grep 'business idempotency key|business key' "$path" "$label business idempotency key"
433
+ require_grep 'application.layer atomic claim|atomic claim' "$path" "$label application-layer atomic claim"
434
+ require_grep 'short transaction|transaction boundary' "$path" "$label short transaction boundary"
435
+ require_grep 'pending|success|failed|state machine' "$path" "$label state machine"
436
+ require_grep 'retry' "$path" "$label retry contract"
437
+ require_grep 'external call|third.party call' "$path" "$label external-call boundary"
438
+ require_grep 'unique index.*not.*default|do not.*default.*unique index' "$path" "$label unique index is not the default"
439
+ }
440
+
441
+ require_money_precision_evidence() {
442
+ local path="$1"
443
+ local label="$2"
444
+ require_grep 'Money Precision Boundary' "$path" "$label"
445
+ require_grep 'half.cent|residual|multi.detail' "$path" "$label boundary cases"
446
+ require_grep 'original.*discount.*actual|allocated total|reconciliation' "$path" "$label reconciliation evidence"
447
+ require_grep 'authoritative total' "$path" "$label authoritative total evidence"
448
+ require_grep 'authoritative total.*minus|derive.*complement|complement amount' "$path" "$label complement derivation evidence"
449
+ require_grep 'currency' "$path" "$label currency evidence"
450
+ require_grep 'minor unit|provider unit' "$path" "$label minor-unit reconciliation"
451
+ require_grep 'positive.*zero.*negative|positive.*refund' "$path" "$label signed-value cases"
452
+ require_grep 'pre.round.*post.round' "$path" "$label rounding audit evidence"
453
+ require_grep 'residual recipient' "$path" "$label residual audit evidence"
454
+ require_grep 'tied remainder' "$path" "$label tied-residual cases"
455
+ require_grep 'idempoten' "$path" "$label allocation idempotence"
456
+ if change_has_fx_precision_risk; then
457
+ require_grep 'base/quote|base currency.*quote currency' "$path" "$label FX direction evidence"
458
+ require_grep 'rate source' "$path" "$label FX source evidence"
459
+ require_grep 'target.*settlement.*round' "$path" "$label FX target rounding evidence"
460
+ fi
461
+ }
462
+
284
463
  transition_event=""
285
464
 
286
465
  if [[ -x "$VALIDATE" && -f "$CHANGE_DIR/.sdd/state.yaml" ]]; then
@@ -310,6 +489,16 @@ case "$PHASE" in
310
489
  require_grep 'RED|red-green|GREEN' tests.md "RED/GREEN test contract"
311
490
  require_grep 'curl|Postman|Newman|pytest|RestAssured|automation command' tests.md "interface automation command"
312
491
  require_grep 'handoff_hash|sdd-context|context package|anti-drift' sdd-quality-gate.md "handoff/context-drift gate"
492
+ if change_has_money_precision_risk; then
493
+ require_grep 'Money Precision Boundary' sdd-quality-gate.md "money precision quality gate"
494
+ fi
495
+ if change_has_external_config_risk; then
496
+ require_external_config_contract api.md "external integration configuration contract"
497
+ require_external_config_contract sdd-quality-gate.md "external integration deployment gate"
498
+ fi
499
+ if change_has_concurrency_idempotency_risk; then
500
+ require_concurrency_idempotency_contract sdd-quality-gate.md "concurrency and idempotency ownership quality gate"
501
+ fi
313
502
  require_markdown_links_valid
314
503
  transition_event="docs-complete"
315
504
  ;;
@@ -342,6 +531,15 @@ case "$PHASE" in
342
531
  if change_has_field_status_risk; then
343
532
  require_grep 'Field And Status Reverse Impact|Field And Status Reverse Impact|write point.*read|read/filter points|derived/sync points' "$technical_design_rel" "field/status reverse impact matrix"
344
533
  fi
534
+ if change_has_external_config_risk; then
535
+ require_external_config_contract "$technical_design_rel" "external integration configuration and deployment contract"
536
+ fi
537
+ if change_has_concurrency_idempotency_risk; then
538
+ require_concurrency_idempotency_contract "$technical_design_rel" "concurrency and idempotency ownership contract"
539
+ fi
540
+ if change_has_money_precision_risk; then
541
+ require_money_precision_contract "$technical_design_rel" "money precision boundary"
542
+ fi
345
543
  fi
346
544
  fi
347
545
  require_grep 'Superpowers Technical Design Handoff|Superpowers Technical Design|technical_design|source-level HOW' design.md "Superpowers technical design handoff"
@@ -367,6 +565,15 @@ case "$PHASE" in
367
565
  if change_has_field_status_risk; then
368
566
  require_grep 'Field And Status Reverse Impact|Field And Status Reverse Impact|read/filter points|derived/sync points' "$prompt_rel" "prompt field/status reverse impact inheritance"
369
567
  fi
568
+ if change_has_external_config_risk; then
569
+ require_external_config_contract "$prompt_rel" "prompt external integration configuration inheritance"
570
+ fi
571
+ if change_has_concurrency_idempotency_risk; then
572
+ require_concurrency_idempotency_contract "$prompt_rel" "prompt concurrency and idempotency ownership inheritance"
573
+ fi
574
+ if change_has_money_precision_risk; then
575
+ require_money_precision_contract "$prompt_rel" "prompt money precision inheritance"
576
+ fi
370
577
  fi
371
578
  require_grep 'context anti-drift|handoff_hash|sdd-context' "$prompt_rel" "prompt context drift inheritance"
372
579
  fi
@@ -386,13 +593,28 @@ case "$PHASE" in
386
593
  ;;
387
594
  verify)
388
595
  require_state_file
596
+ require_tasks_complete
389
597
  require_file test-report.md
390
598
  require_grep 'RED|failure evidence' test-report.md "RED evidence"
391
599
  require_grep 'GREEN|pass evidence' test-report.md "GREEN evidence"
392
600
  require_grep 'interface automation|curl|Postman|Newman|pytest|RestAssured' test-report.md "interface automation evidence"
393
601
  require_grep 'DB|database|SELECT|SHOW CREATE' test-report.md "DB evidence"
394
602
  require_grep 'superflow-verify-integration|superflow-delivery-check|superflow-test-report-lint' test-report.md "SuperBridge Flow hook/script evidence"
603
+ if change_has_money_precision_risk; then
604
+ require_money_precision_evidence test-report.md "money precision runtime evidence"
605
+ fi
606
+ if change_has_external_config_risk; then
607
+ require_grep 'External Integration Configuration And Deployment Contract' test-report.md "external integration configuration runtime evidence"
608
+ require_grep 'production.*ready|provision.*verified|resource.*exists' test-report.md "external production readiness evidence"
609
+ fi
610
+ if change_has_concurrency_idempotency_risk; then
611
+ require_grep 'Concurrency And Idempotency Ownership|application.layer atomic claim|atomic claim' test-report.md "concurrency and idempotency runtime evidence"
612
+ require_grep 'concurren|duplicate|retry' test-report.md "concurrency duplicate and retry cases"
613
+ fi
395
614
  require_test_report_lint
615
+ require_closeout_markers "$CHANGE_DIR/test-report.md"
616
+ require_branch_handled
617
+ require_full_verification_fingerprint
396
618
  require_markdown_links_valid
397
619
  if [[ "$(state_get verification_report)" == "" || "$(state_get verification_report)" == "null" ]]; then
398
620
  "$STATE" set "$CHANGE_DIR" verification_report test-report.md
@@ -401,11 +623,20 @@ case "$PHASE" in
401
623
  ;;
402
624
  archive)
403
625
  require_state_file
626
+ require_tasks_complete
404
627
  verify_result="$(state_get verify_result)"
405
628
  [[ "$verify_result" == "pass" ]] || issues+=("verify_result must be pass before archive")
406
629
  archived="$(state_get archived)"
407
630
  [[ "$archived" != "true" ]] || issues+=("archived is already true")
408
631
  require_state_value verification_report "verification_report"
632
+ report_path="$(verification_report_path || true)"
633
+ if [[ -z "$report_path" ]]; then
634
+ issues+=("verification_report path does not exist")
635
+ else
636
+ require_closeout_markers "$report_path"
637
+ fi
638
+ require_branch_handled
639
+ require_state_value verified_at "verified_at"
409
640
  transition_event="archived"
410
641
  ;;
411
642
  *)
@@ -43,6 +43,16 @@ Use `.sdd/state.yaml` `verify_mode` after `scale`.
43
43
  prove the complete evidence chain: source/Mapper/XML, DB when needed, real
44
44
  entry point, interface automation, logs, SQL sync, and consumer behavior.
45
45
 
46
+ Money-related changes always require full verification of
47
+ `Money Precision Boundary`: original calculation inputs and intermediate precision, the actual
48
+ rounding boundary and mode, half-cent/residual/multi-detail cases, deterministic
49
+ allocation, and reconciliation identities. A final two-decimal display value
50
+ or unit-test-only evidence is not sufficient.
51
+ For additive identities, verification must prove which total was authoritative,
52
+ which N-1 components were calculated independently, and which final complement
53
+ was derived as `authoritative total - sum(other components)`. Evidence that all
54
+ components were independently calculated and rounded is a failure.
55
+
46
56
  ## Required Superpowers
47
57
 
48
58
  Immediately load and apply these Superpowers when available:
@@ -94,8 +104,21 @@ Before pass:
94
104
  delivery or branch closeout.
95
105
  5. Code review findings are either fixed or explicitly recorded with accepted
96
106
  risk.
97
- 6. Branch/worktree status is handled and `.sdd/state.yaml` has:
107
+ 6. For money-related changes, `test-report.md` records the `Money Precision
108
+ Boundary` cases and proves original, discount, actual/refund, and allocated
109
+ totals reconcile without early rounding. For additive identities it also
110
+ records the authoritative total and the subtraction used to derive the final
111
+ complement.
112
+ 7. Branch/worktree status is handled and `.sdd/state.yaml` has:
98
113
  `branch_status: handled`.
114
+ 8. Every checkbox in `tasks.md` is checked. A completed implementation with
115
+ stale task documentation is a verification failure, not an archive-time
116
+ cleanup item.
117
+ 9. `test-report.md` ends with the machine-checkable closeout markers
118
+ `Verification Result: PASS` and `Archive Readiness: PASS`. For
119
+ `verify_mode: full`, it also records the test environment,
120
+ branch/commit/build or image fingerprint, Base URL, and verification
121
+ timestamp.
99
122
 
100
123
  Only then run:
101
124
 
@@ -1,6 +1,10 @@
1
- import { checkSkillDeployment } from '../../domains/skill/check.js';
2
- const SKILL_NAME = 'superflow-archive';
3
- export async function archiveCommand(_change, options = {}) {
1
+ import { checkSkillDeployment, } from "../../domains/skill/check.js";
2
+ import { runArchiveDryRun } from "./change-guard.js";
3
+ const SKILL_NAME = "superflow-archive";
4
+ export async function archiveCommand(change, options = {}) {
5
+ if (change) {
6
+ runArchiveDryRun(change);
7
+ }
4
8
  checkSkillDeployment(SKILL_NAME, options);
5
9
  }
6
10
  //# sourceMappingURL=archive.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/app/commands/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAA0B,MAAM,8BAA8B,CAAC;AAE5F,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgB,EAChB,UAA6B,EAAE;IAE/B,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/app/commands/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAErB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAe,EACf,UAA6B,EAAE;IAE/B,IAAI,MAAM,EAAE,CAAC;QACX,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IACD,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { ASSETS_DIR } from "../../platform/assets.js";
5
+ const PIPELINE_SCRIPTS = path.resolve(ASSETS_DIR, "skills", "superflow-pipeline", "scripts");
6
+ export function resolveChangeDir(change) {
7
+ const direct = path.resolve(change);
8
+ if (existsSync(direct))
9
+ return direct;
10
+ const openspecChange = path.resolve("openspec", "changes", change);
11
+ if (existsSync(openspecChange))
12
+ return openspecChange;
13
+ return direct;
14
+ }
15
+ export function runChangeGuard(change, phase) {
16
+ const guard = path.join(PIPELINE_SCRIPTS, "superflow-guard.sh");
17
+ execFileSync("bash", [guard, resolveChangeDir(change), phase], {
18
+ stdio: "inherit",
19
+ });
20
+ }
21
+ export function runArchiveDryRun(change) {
22
+ const archive = path.join(PIPELINE_SCRIPTS, "superflow-archive.sh");
23
+ execFileSync("bash", [archive, resolveChangeDir(change), "--dry-run"], {
24
+ stdio: "inherit",
25
+ });
26
+ }
27
+ //# sourceMappingURL=change-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change-guard.js","sourceRoot":"","sources":["../../../src/app/commands/change-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CACnC,UAAU,EACV,QAAQ,EACR,oBAAoB,EACpB,SAAS,CACV,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAEtC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACnE,IAAI,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,cAAc,CAAC;IAEtD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,KAA0B;IAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,CAAC;IAChE,YAAY,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE;QAC7D,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,CAAC;IACpE,YAAY,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE;QACrE,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;AACL,CAAC"}
@@ -1,28 +1,10 @@
1
- import { execFileSync } from "node:child_process";
2
- import { existsSync } from "node:fs";
3
- import path from "node:path";
4
- import { fileURLToPath } from "node:url";
5
1
  import { checkSkillDeployment, } from "../../domains/skill/check.js";
2
+ import { runChangeGuard } from "./change-guard.js";
6
3
  const SKILL_NAME = "superflow-design";
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = path.dirname(__filename);
9
- const GUARD = path.resolve(__dirname, "..", "..", "assets", "skills", "superflow-pipeline", "scripts", "superflow-guard.sh");
10
4
  export async function designCommand(change, options = {}) {
11
5
  if (change) {
12
- runDesignGuard(resolveChangeDir(change));
6
+ runChangeGuard(change, "design");
13
7
  }
14
8
  checkSkillDeployment(SKILL_NAME, options);
15
9
  }
16
- function resolveChangeDir(change) {
17
- const direct = path.resolve(change);
18
- if (existsSync(direct))
19
- return direct;
20
- const openspecChange = path.resolve("openspec", "changes", change);
21
- if (existsSync(openspecChange))
22
- return openspecChange;
23
- return direct;
24
- }
25
- function runDesignGuard(changeDir) {
26
- execFileSync("bash", [GUARD, changeDir, "design"], { stdio: "inherit" });
27
- }
28
10
  //# sourceMappingURL=design.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"design.js","sourceRoot":"","sources":["../../../src/app/commands/design.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,oBAAoB,GAErB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,UAAU,GAAG,kBAAkB,CAAC;AACtC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CACxB,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,oBAAoB,EACpB,SAAS,EACT,oBAAoB,CACrB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAe,EACf,UAA6B,EAAE;IAE/B,IAAI,MAAM,EAAE,CAAC;QACX,cAAc,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAc;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAEtC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACnE,IAAI,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,cAAc,CAAC;IAEtD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB;IACvC,YAAY,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"design.js","sourceRoot":"","sources":["../../../src/app/commands/design.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAErB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,UAAU,GAAG,kBAAkB,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAe,EACf,UAA6B,EAAE;IAE/B,IAAI,MAAM,EAAE,CAAC;QACX,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IACD,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import path from 'path';
2
- import { fileURLToPath } from 'url';
3
2
  import { existsSync } from 'fs';
4
3
  import { createInterface } from 'readline/promises';
5
4
  import { stdin as input, stdout as output } from 'process';
@@ -16,10 +15,7 @@ import { loadState, saveState, initState } from '../../domains/state.js';
16
15
  import { scaffoldBusinessContext, checkUnderstandScan, printSoftPrompt } from '../../domains/config/context.js';
17
16
  import { ALL_RULES, ALL_SKILLS, CODEX_PROMPTS, scriptsForAgent, hookScriptsForAgent, } from '../../domains/skill/assets.js';
18
17
  import { normalizeLanguage, t } from '../../domains/config/i18n.js';
19
- const __filename = fileURLToPath(import.meta.url);
20
- const __dirname = path.dirname(__filename);
21
- // dist/commands/init.js → ../../assets
22
- const ASSETS_DIR = path.resolve(__dirname, '..', '..', 'assets');
18
+ import { ASSETS_DIR } from '../../platform/assets.js';
23
19
  export async function initCommand(cmdOptions) {
24
20
  // commander 的 --no-hooks 标志让 options.hooks = false;默认是 true
25
21
  // commander 的 --no-scan 标志让 options.scan = false;默认是 true