scene-capability-engine 3.4.5 → 3.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/CHANGELOG.md CHANGED
@@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.5.0] - 2026-03-02
11
+
12
+ ### Added
13
+ - Studio automatic intake + spec governance baseline:
14
+ - new policy: `.sce/config/studio-intake-policy.json` (template/adopt/takeover managed)
15
+ - `studio plan` now auto-detects goal intent and resolves spec by bind/create strategy
16
+ - new commands:
17
+ - `sce studio intake`
18
+ - `sce studio portfolio`
19
+ - plan stage now auto-writes scene portfolio governance artifacts:
20
+ - `.sce/spec-governance/scene-portfolio.latest.json`
21
+ - `.sce/spec-governance/scene-index.json`
22
+ - New intake/governance module:
23
+ - `lib/studio/spec-intake-governor.js`
24
+ - scene-level duplicate/overflow/stale spec governance summary for portfolio management
25
+
26
+ ### Changed
27
+ - Takeover/adoption managed config baseline now includes `config/studio-intake-policy.json` by default.
28
+ - README/README.zh/command reference updated for auto intake and scene-organized spec governance workflow.
29
+
30
+ ## [3.4.6] - 2026-03-02
31
+
32
+ ### Added
33
+ - Default problem-closure gate and policy baseline:
34
+ - new script: `scripts/problem-closure-gate.js`
35
+ - new managed config: `.sce/config/problem-closure-policy.json` (and template counterpart)
36
+ - `studio verify/release` standard profiles now execute `problem-closure-gate` when spec context is available
37
+ - Spec domain modeling now includes a mandatory machine-readable problem contract artifact:
38
+ - `.sce/specs/<spec>/custom/problem-contract.json`
39
+ - generated via spec domain init/refresh/bootstrap flow
40
+
41
+ ### Changed
42
+ - Problem evaluation policy and runtime now enforce stronger closure dimensions by default:
43
+ - mandatory dimensions: `problem_contract`, `ontology_alignment`, `convergence`
44
+ - stage-level block policy tightened for plan/apply/release closure control
45
+ - Errorbook record contract now captures structured attempt context (`attempt_contract`) for better trial/verification traceability.
46
+ - Errorbook release gate now incorporates quality policy checks (`min_quality`) for unresolved verified entries.
47
+ - Takeover/adoption baseline and file classification now manage `problem-closure-policy.json` as first-class config.
48
+ - README/README.zh/command reference updated to document problem-domain closed loop, two-failed-round debug escalation, and closure gate workflows.
49
+
10
50
  ## [3.4.5] - 2026-03-02
11
51
 
12
52
  ### Fixed
package/README.md CHANGED
@@ -26,10 +26,12 @@ SCE is designed for teams that want AI agents to deliver software end-to-end wit
26
26
  | Capability | What SCE Provides | Outcome |
27
27
  | --- | --- | --- |
28
28
  | Scene + Spec model | Scene-governed sessions and Spec lifecycle (`requirements/design/tasks`) | Stable context across long AI runs |
29
+ | Auto intake + Spec governance | Goal intent detection, auto spec bind/create, scene portfolio governance | Automatic scene-to-spec tracking with bounded spec growth |
29
30
  | Studio workflow | `studio plan -> generate -> apply -> verify -> release` | Structured chat-to-release execution |
30
31
  | Autonomous delivery | `auto close-loop`, `close-loop-program`, `close-loop-controller` | Unattended bounded convergence |
31
32
  | Multi-agent orchestration | DAG scheduling, retries, 429 adaptive parallel control | Reliable parallel execution at scale |
32
33
  | Domain/ontology governance | problem-domain chain + scene template + gate validation | Fewer semantic regressions |
34
+ | Problem closure loop | problem-domain map + chain + `problem-contract` + closure gate | Root-cause-first fixes with bounded convergence |
33
35
  | Problem evaluation routing | Stage-level risk/evidence/readiness scoring with mandatory policy | Adaptive execution strategy with guarded apply/release |
34
36
  | Local timeline safety | `timeline save/auto/list/show/restore/push` + key-event auto checkpoints | Recoverable local history |
35
37
  | Errorbook-driven repair | Local + registry-backed error patterns and release gates | Faster diagnosis and safer fixes |
@@ -94,6 +96,21 @@ git push origin vX.Y.Z
94
96
 
95
97
  ---
96
98
 
99
+ ## Default Problem-Solving Loop
100
+
101
+ SCE now enforces a domain-closed diagnosis and repair route by default:
102
+
103
+ 1. Scope the problem first with scene artifacts (`problem-domain-map.md`, `scene-spec.md`, `problem-domain-chain.json`, `problem-contract.json`).
104
+ 2. Keep trial-and-error history in incident staging (`.sce/errorbook/staging/incidents/`) to avoid repeating failed attempts.
105
+ 3. Use problem evaluation to prioritize likely impact areas before applying/releasing changes.
106
+
107
+ Hard rule defaults:
108
+ - After two failed rounds on the same problem fingerprint, debug evidence is required in subsequent attempts.
109
+ - `studio verify/release` run `problem-closure-gate` by default when a spec is bound.
110
+ - `studio plan` auto-runs goal intake (`bind existing spec` or `create spec`) and writes scene portfolio governance snapshots by default.
111
+
112
+ ---
113
+
97
114
  ## AI Agent Compatibility
98
115
 
99
116
  SCE is tool-agnostic and works with Codex, Claude Code, Cursor, Windsurf, VS Code Copilot, and other CLI-capable agents.
@@ -103,6 +120,7 @@ SCE is tool-agnostic and works with Codex, Claude Code, Cursor, Windsurf, VS Cod
103
120
  - Spec work is attached as child sessions and auto-archived.
104
121
  - Startup now auto-detects adopted projects and aligns takeover baseline defaults automatically.
105
122
  - Problem evaluation policy is enabled by default (`.sce/config/problem-eval-policy.json`) and evaluates every Studio stage.
123
+ - Problem closure policy is enabled by default (`.sce/config/problem-closure-policy.json`) and blocks verify/release bypass when required domain/problem evidence is missing.
106
124
  - Error handling now follows a full incident loop by default: every record attempt is staged first and auto-closed on verified/promoted outcomes.
107
125
  - You can inspect or force-align baseline explicitly:
108
126
  - `sce workspace takeover-audit --json`
@@ -110,6 +128,18 @@ SCE is tool-agnostic and works with Codex, Claude Code, Cursor, Windsurf, VS Cod
110
128
 
111
129
  ---
112
130
 
131
+ ## Important Version Changes
132
+
133
+ - `3.5.0`: Added Studio automatic goal intake + scene spec portfolio governance (`sce studio intake`, `sce studio portfolio`), including default intake policy baseline and governance artifacts for bounded scene spec growth.
134
+ - `3.4.6`: Added default `problem-closure-gate` + `problem-contract` baseline and strengthened mandatory problem evaluation dimensions (`problem_contract`/`ontology_alignment`/`convergence`) for verify/release convergence control.
135
+ - `3.4.5`: `git-managed-gate` now treats worktree checks as advisory in default relaxed CI mode (`CI/GITHUB_ACTIONS`, non-strict), preventing false release blocking.
136
+ - `3.4.4`: Added `SCE_GIT_MANAGEMENT_ALLOW_UNTRACKED=1` / `--allow-untracked`; release workflow uses it for npm publish after generating release evidence artifacts.
137
+ - `3.4.3`: Introduced mandatory problem evaluation across Studio stages (`plan/generate/apply/verify/release`) with policy file `.sce/config/problem-eval-policy.json` and stage report artifacts.
138
+ - `3.4.2`: Errorbook incident flow moved to full staging closed-loop (attempt history, incident inspection, resolved archive).
139
+ - `3.4.1`: Added workspace takeover baseline automation (`takeover-audit` / `takeover-apply`) and startup alignment defaults.
140
+
141
+ ---
142
+
113
143
  ## Documentation Map
114
144
 
115
145
  Start here:
@@ -147,5 +177,5 @@ MIT. See [LICENSE](LICENSE).
147
177
 
148
178
  ---
149
179
 
150
- **Version**: 3.4.5
180
+ **Version**: 3.5.0
151
181
  **Last Updated**: 2026-03-02
package/README.zh.md CHANGED
@@ -26,10 +26,12 @@ SCE 面向希望让 AI Agent 端到端推进交付、同时保持治理可控的
26
26
  | 能力 | SCE 提供什么 | 结果 |
27
27
  | --- | --- | --- |
28
28
  | Scene + Spec 模型 | 场景主会话治理 + Spec 生命周期(需求/设计/任务) | 长周期 AI 上下文稳定 |
29
+ | 自动 intake + Spec 治理 | 目标意图识别、自动绑定/创建 spec、按 scene 组合治理 | 场景需求自动纳管,spec 增长可控 |
29
30
  | Studio 工作流 | `studio plan -> generate -> apply -> verify -> release` | 对话到发布路径结构化 |
30
31
  | 自动闭环交付 | `auto close-loop`、`close-loop-program`、`close-loop-controller` | 无人值守有界收敛 |
31
32
  | 多 Agent 编排 | DAG 调度、重试、429 自适应并行 | 并行执行稳定可控 |
32
33
  | 领域/本体治理 | problem-domain chain + scene template + gate 校验 | 降低语义回归 |
34
+ | 问题闭环治理 | problem-domain map + chain + `problem-contract` + closure gate | 根因优先修复,过程有界收敛 |
33
35
  | 问题评估路由 | 分阶段风险/证据/就绪度评分 + 强制策略 | `apply/release` 可控阻断,执行路径自适应 |
34
36
  | 本地时间线安全 | `timeline save/auto/list/show/restore/push` + 关键节点自动打点 | 本地历史可回放可恢复 |
35
37
  | Errorbook 修复体系 | 本地 + 注册表错题库 + 发布门禁 | 定位更快、修复更稳 |
@@ -94,6 +96,21 @@ git push origin vX.Y.Z
94
96
 
95
97
  ---
96
98
 
99
+ ## 默认问题解决闭环
100
+
101
+ SCE 默认按“问题域闭环”推进诊断与修复:
102
+
103
+ 1. 先收敛问题域边界:`problem-domain-map.md`、`scene-spec.md`、`problem-domain-chain.json`、`problem-contract.json`。
104
+ 2. 试错过程进入 incident staging(`.sce/errorbook/staging/incidents/`),避免重复犯错。
105
+ 3. 由 problem evaluation 在变更前优先排序高相关区域,再进入 apply/release。
106
+
107
+ 默认硬规则:
108
+ - 同一问题指纹失败两轮后,后续尝试必须补充 debug 证据。
109
+ - 当 spec 绑定时,`studio verify/release` 默认执行 `problem-closure-gate`。
110
+ - `studio plan` 默认执行目标 intake(自动绑定已有 spec 或新建 spec),并自动写入 scene 维度的 spec 治理快照。
111
+
112
+ ---
113
+
97
114
  ## AI Agent 适配
98
115
 
99
116
  SCE 对工具无锁定,可接入 Codex、Claude Code、Cursor、Windsurf、VS Code Copilot 等。
@@ -103,6 +120,7 @@ SCE 对工具无锁定,可接入 Codex、Claude Code、Cursor、Windsurf、VS
103
120
  - Spec 执行作为子会话自动归档,支持跨轮次追踪。
104
121
  - 启动时会自动识别已接管项目并对齐接管基线默认配置。
105
122
  - 问题评估策略默认启用(`.sce/config/problem-eval-policy.json`),Studio 各阶段都会执行评估。
123
+ - 问题闭环策略默认启用(`.sce/config/problem-closure-policy.json`),缺失必要问题/领域证据时会在 verify/release 阶段阻断。
106
124
  - 错误处理默认进入完整 incident 闭环:每次记录先落到 staging 试错链路,verified/promoted 后自动收束归档。
107
125
  - 也可显式审计/修正接管基线:
108
126
  - `sce workspace takeover-audit --json`
@@ -110,6 +128,18 @@ SCE 对工具无锁定,可接入 Codex、Claude Code、Cursor、Windsurf、VS
110
128
 
111
129
  ---
112
130
 
131
+ ## 重要版本变更
132
+
133
+ - `3.5.0`:新增 Studio 目标自动 intake + 场景 spec 组合治理(`sce studio intake`、`sce studio portfolio`),并默认启用 intake 策略基线与治理快照产物,控制场景内 spec 无序增长。
134
+ - `3.4.6`:新增默认 `problem-closure-gate` + `problem-contract` 基线,并强化问题评估强制维度(`problem_contract`/`ontology_alignment`/`convergence`),提升 verify/release 收敛控制。
135
+ - `3.4.5`:`git-managed-gate` 在默认 CI 放宽模式下(`CI/GITHUB_ACTIONS` 且非 strict)对工作区变更改为告警,不再误阻断发布。
136
+ - `3.4.4`:新增 `SCE_GIT_MANAGEMENT_ALLOW_UNTRACKED=1` / `--allow-untracked`;发布工作流在 npm publish 前生成证据资产时可放行未跟踪文件。
137
+ - `3.4.3`:Studio 全阶段接入强制问题评估(`plan/generate/apply/verify/release`),并引入策略文件 `.sce/config/problem-eval-policy.json` 与评估报告落盘。
138
+ - `3.4.2`:Errorbook 升级为完整 incident staging 闭环(尝试记录、incident 查询、resolved 归档)。
139
+ - `3.4.1`:新增 workspace takeover baseline 自动化(`takeover-audit` / `takeover-apply`)与启动对齐能力。
140
+
141
+ ---
142
+
113
143
  ## 文档导航
114
144
 
115
145
  建议先看:
@@ -147,5 +177,5 @@ MIT,见 [LICENSE](LICENSE)。
147
177
 
148
178
  ---
149
179
 
150
- **版本**:3.4.5
180
+ **版本**:3.5.0
151
181
  **最后更新**:2026-03-02
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Quick reference for all `sce` commands
4
4
 
5
- **Version**: 3.4.5
5
+ **Version**: 3.5.0
6
6
  **Last Updated**: 2026-03-02
7
7
 
8
8
  ---
@@ -11,7 +11,7 @@
11
11
 
12
12
  The CLI provides three command aliases:
13
13
  - `sce` - **Recommended primary command** (use this in all documentation)
14
- - `sce` - Legacy short alias (compatible)
14
+ - `sco` - Legacy short alias (compatible)
15
15
  - `scene-capability-engine` - Legacy full alias (compatible)
16
16
 
17
17
  **Always use `sce` in new examples and documentation.**
@@ -24,7 +24,7 @@ The CLI provides three command aliases:
24
24
  npm install -g scene-capability-engine
25
25
  ```
26
26
 
27
- This creates the `sce` command globally. Legacy aliases `sce` and `scene-capability-engine` are still available.
27
+ This creates the `sce` command globally. Legacy aliases `sco` and `scene-capability-engine` are still available.
28
28
 
29
29
  ---
30
30
 
@@ -61,6 +61,7 @@ sce spec bootstrap --name 01-00-feature-name --scene scene.customer-order-invent
61
61
  # - .sce/specs/<spec>/custom/problem-domain-map.md
62
62
  # - .sce/specs/<spec>/custom/scene-spec.md
63
63
  # - .sce/specs/<spec>/custom/problem-domain-chain.json (machine-readable chain model)
64
+ # - .sce/specs/<spec>/custom/problem-contract.json (problem closure contract)
64
65
 
65
66
  # Run pipeline for one Spec
66
67
  sce spec pipeline run --spec 01-00-feature-name --scene scene.customer-order-inventory
@@ -92,11 +93,12 @@ Spec session governance:
92
93
  - `spec bootstrap|pipeline run|gate run` must bind to an active scene primary session (`--scene <scene-id>` or implicit binding from latest/unique active scene).
93
94
  - When multiple active scenes exist, you must pass `--scene` explicitly.
94
95
  - Multi-Spec orchestrate fallback (`--specs ...`) follows the same scene binding and writes per-spec child-session archive records.
95
- - `spec bootstrap` always generates problem-domain and scene-spec artifacts to force domain-first exploration.
96
+ - `spec bootstrap` always generates problem-domain, scene-spec, and `problem-contract` artifacts to force domain-first exploration.
96
97
  - `spec gate` now hard-fails when either of the following is missing or structurally incomplete:
97
98
  - `.sce/specs/<spec>/custom/problem-domain-map.md`
98
99
  - `.sce/specs/<spec>/custom/scene-spec.md`
99
100
  - `.sce/specs/<spec>/custom/problem-domain-chain.json`
101
+ - `problem-contract.json` is enforced by Studio stage gates (`problem-closure-gate`) during `verify/release`.
100
102
  - Closed-loop scene research baseline is now part of domain modeling artifacts:
101
103
  - `problem-domain-map.md` must include `Closed-Loop Research Coverage Matrix`
102
104
  - `scene-spec.md` must include `Closed-Loop Research Contract`
@@ -521,6 +523,13 @@ Curated quality policy (`宁缺毋滥,优胜略汰`) defaults:
521
523
  sce studio plan --scene scene.customer-order-inventory --from-chat session-20260226 --goal "customer+order+inventory demo" --json
522
524
  # Recommended: bind spec explicitly so Studio can ingest problem-domain-chain deterministically
523
525
  sce studio plan --scene scene.customer-order-inventory --spec 01-00-customer-order-inventory --from-chat session-20260226 --goal "customer+order+inventory demo" --json
526
+ # Disable auto intake for emergency/manual mode
527
+ sce studio plan --scene scene.customer-order-inventory --from-chat session-20260226 --goal "customer+order+inventory demo" --manual-spec --json
528
+
529
+ # Analyze intake decision only (no write by default)
530
+ sce studio intake --scene scene.customer-order-inventory --from-chat session-20260226 --goal "optimize checkout retry flow" --json
531
+ # Apply intake and create spec when decision is create_spec
532
+ sce studio intake --scene scene.customer-order-inventory --from-chat session-20260226 --goal "optimize checkout retry flow" --apply --json
524
533
 
525
534
  # Generate patch bundle metadata (scene is inherited from plan)
526
535
  sce studio generate --target 331 --json
@@ -547,15 +556,26 @@ sce studio events --job <job-id> --limit 50 --json
547
556
  # Rollback a job after apply/release
548
557
  sce studio rollback --job <job-id> --reason "manual-check-failed" --json
549
558
 
559
+ # Build scene-organized spec governance portfolio
560
+ sce studio portfolio --json
561
+ sce studio portfolio --scene scene.customer-order-inventory --strict --json
562
+
550
563
  # Enforce authorization for a protected action
551
564
  SCE_STUDIO_REQUIRE_AUTH=1 SCE_STUDIO_AUTH_PASSWORD=top-secret sce studio apply --job <job-id> --auth-password top-secret --json
552
565
  ```
553
566
 
554
567
  Stage guardrails are enforced by default:
555
568
  - `plan` requires `--scene`; SCE binds one active primary session per scene
569
+ - `plan` runs auto intake by default (`.sce/config/studio-intake-policy.json`):
570
+ - detect goal intent (`change_request` vs `analysis_only`)
571
+ - resolve spec via explicit binding / scene latest / related specs / auto-create
572
+ - auto-create spec artifacts when no suitable spec is found and policy requires tracking
556
573
  - `plan --spec <id>` (recommended) ingests `.sce/specs/<spec>/custom/problem-domain-chain.json` into studio job context
557
574
  - when `--spec` is omitted, `plan` auto-resolves the latest matching spec chain by `scene_id` when available
558
575
  - `plan` auto-searches related historical specs by `scene + goal` and writes top candidates into job metadata (`source.related_specs`)
576
+ - `plan` auto-runs scene spec governance snapshot and writes:
577
+ - `.sce/spec-governance/scene-portfolio.latest.json`
578
+ - `.sce/spec-governance/scene-index.json`
559
579
  - successful `release` auto-archives current scene session and auto-opens the next scene cycle session
560
580
  - `generate` requires `plan`
561
581
  - `generate` consumes the plan-stage domain-chain context and writes chain-aware metadata/report (`.sce/reports/studio/generate-<job-id>.json`)
@@ -567,13 +587,17 @@ Stage guardrails are enforced by default:
567
587
  Problem evaluation mode (default required):
568
588
  - Studio now runs problem evaluation on every stage: `plan`, `generate`, `apply`, `verify`, `release`.
569
589
  - Default policy file: `.sce/config/problem-eval-policy.json` (also provisioned by template/adopt/takeover baseline).
570
- - Default hard-block stages: `apply`, `release`.
590
+ - Mandatory dimensions: `problem_contract`, `ontology_alignment`, `convergence`.
591
+ - Default hard-block behavior:
592
+ - stage block policy: `apply`, `release`
593
+ - dimension block policy: `problem_contract` blocks on `plan/apply/release`; `ontology_alignment` blocks on `apply/release`; `convergence` blocks on `release`
571
594
  - Evaluation combines risk/evidence/readiness and emits adaptive strategy:
572
595
  - `direct-execution`
573
596
  - `controlled-execution`
574
597
  - `evidence-first`
575
598
  - `explore-and-validate`
576
599
  - `debug-first`
600
+ - Default retry rule: after two failed rounds on the same fingerprint, subsequent attempts must include debug evidence.
577
601
  - Evaluation report artifact is written to `.sce/reports/problem-eval/<job-id>-<stage>.json`.
578
602
  - Stage metadata and event payload now include `problem_evaluation` summary plus artifact pointer.
579
603
  - Environment overrides:
@@ -581,11 +605,35 @@ Problem evaluation mode (default required):
581
605
  - `SCE_PROBLEM_EVAL_DISABLED=1`
582
606
 
583
607
  Studio gate execution defaults:
584
- - `verify --profile standard` runs executable gates (unit test script when available, interactive governance report when present, scene package publish-batch dry-run when handoff manifest exists)
585
- - `release --profile standard` runs executable release preflight (npm pack dry-run, git managed gate, errorbook release gate, weekly ops gate when summary exists, release asset integrity when evidence directory exists, scene package publish-batch ontology gate, handoff capability matrix gate)
608
+ - `verify --profile standard` runs executable gates (unit test script when available, interactive governance report when present, scene package publish-batch dry-run when handoff manifest exists, `problem-closure-gate` when spec context is available)
609
+ - `release --profile standard` runs executable release preflight (npm pack dry-run, git managed gate, errorbook release gate, weekly ops gate when summary exists, release asset integrity when evidence directory exists, scene package publish-batch ontology gate, handoff capability matrix gate, `problem-closure-gate` when spec context is available)
586
610
  - `verify/release --profile strict` fails when any required gate step is skipped (for example missing manifest/evidence/scripts)
587
611
  - Required gate failures are auto-recorded into `.sce/errorbook` as `candidate` entries (tagged `release-blocker`) for follow-up triage.
588
612
 
613
+ Problem closure gate (default policy):
614
+ - Script: `node scripts/problem-closure-gate.js`
615
+ - Policy file: `.sce/config/problem-closure-policy.json` (auto-provisioned by `init/adopt/takeover`)
616
+ - Checks:
617
+ - verify stage: `problem-contract` + spec domain validation + domain coverage
618
+ - release stage: verify checks + verify report pass signal + governance high-alert block (configurable)
619
+
620
+ ```bash
621
+ # Verify-stage closure gate
622
+ node scripts/problem-closure-gate.js \
623
+ --stage verify \
624
+ --spec 01-00-customer-order-inventory \
625
+ --fail-on-block \
626
+ --json
627
+
628
+ # Release-stage closure gate
629
+ node scripts/problem-closure-gate.js \
630
+ --stage release \
631
+ --spec 01-00-customer-order-inventory \
632
+ --verify-report .sce/reports/studio/verify-<job-id>.json \
633
+ --fail-on-block \
634
+ --json
635
+ ```
636
+
589
637
  Authorization model (optional, policy-driven):
590
638
  - Enable policy: `SCE_STUDIO_REQUIRE_AUTH=1`
591
639
  - Secret env key: `SCE_STUDIO_AUTH_PASSWORD` (or override key name with `SCE_STUDIO_PASSWORD_ENV`)
@@ -602,6 +650,24 @@ Default policy file (recommended to commit): `.sce/config/studio-security.json`
602
650
  }
603
651
  ```
604
652
 
653
+ Studio intake policy file (default, recommended to commit): `.sce/config/studio-intake-policy.json`
654
+
655
+ ```json
656
+ {
657
+ "enabled": true,
658
+ "auto_create_spec": true,
659
+ "force_spec_for_studio_plan": true,
660
+ "prefer_existing_scene_spec": true,
661
+ "related_spec_min_score": 45,
662
+ "governance": {
663
+ "auto_run_on_plan": true,
664
+ "max_active_specs_per_scene": 3,
665
+ "stale_days": 14,
666
+ "duplicate_similarity_threshold": 0.66
667
+ }
668
+ }
669
+ ```
670
+
605
671
  ### Capability Matrix Utilities
606
672
 
607
673
  ```bash
Binary file
@@ -119,6 +119,8 @@ class AdoptionStrategy {
119
119
  'config/session-governance.json',
120
120
  'config/spec-domain-policy.json',
121
121
  'config/problem-eval-policy.json',
122
+ 'config/problem-closure-policy.json',
123
+ 'config/studio-intake-policy.json',
122
124
  'specs/SPEC_WORKFLOW_GUIDE.md',
123
125
  'hooks/sync-tasks-on-edit.sce.hook',
124
126
  'hooks/check-spec-on-create.sce.hook',
@@ -168,6 +168,8 @@ class DetectionEngine {
168
168
  'config/session-governance.json',
169
169
  'config/spec-domain-policy.json',
170
170
  'config/problem-eval-policy.json',
171
+ 'config/problem-closure-policy.json',
172
+ 'config/studio-intake-policy.json',
171
173
  'README.md',
172
174
  'ultrawork-application-guide.md',
173
175
  'ultrawork-integration-summary.md',
@@ -69,7 +69,9 @@ class FileClassifier {
69
69
  'config/takeover-baseline.json',
70
70
  'config/session-governance.json',
71
71
  'config/spec-domain-policy.json',
72
- 'config/problem-eval-policy.json'
72
+ 'config/problem-eval-policy.json',
73
+ 'config/problem-closure-policy.json',
74
+ 'config/studio-intake-policy.json'
73
75
  ];
74
76
 
75
77
  // Generated directory patterns
@@ -289,6 +289,8 @@ class SmartOrchestrator {
289
289
  'config/session-governance.json',
290
290
  'config/spec-domain-policy.json',
291
291
  'config/problem-eval-policy.json',
292
+ 'config/problem-closure-policy.json',
293
+ 'config/studio-intake-policy.json',
292
294
  'README.md'
293
295
  ];
294
296
 
@@ -48,6 +48,7 @@ const ONTOLOGY_TAG_ALIASES = Object.freeze({
48
48
  action_chain: 'execution_flow'
49
49
  });
50
50
  const DEFAULT_PROMOTE_MIN_QUALITY = 75;
51
+ const DEFAULT_RELEASE_GATE_MIN_QUALITY = 70;
51
52
  const ERRORBOOK_RISK_LEVELS = Object.freeze(['low', 'medium', 'high']);
52
53
  const DEBUG_EVIDENCE_TAGS = Object.freeze([
53
54
  'debug-evidence',
@@ -515,11 +516,21 @@ async function writeIncident(paths, incident, fileSystem = fs) {
515
516
  }
516
517
 
517
518
  function createIncidentAttemptSignature(payload = {}) {
519
+ const attemptContract = payload && payload.attempt_contract && typeof payload.attempt_contract === 'object'
520
+ ? payload.attempt_contract
521
+ : {};
518
522
  const basis = JSON.stringify({
519
523
  root_cause: normalizeText(payload.root_cause),
520
524
  fix_actions: normalizeStringList(payload.fix_actions),
521
525
  verification_evidence: normalizeStringList(payload.verification_evidence),
522
526
  notes: normalizeText(payload.notes),
527
+ attempt_contract: {
528
+ hypothesis: normalizeText(attemptContract.hypothesis),
529
+ change_points: normalizeStringList(attemptContract.change_points),
530
+ verification_result: normalizeText(attemptContract.verification_result),
531
+ rollback_point: normalizeText(attemptContract.rollback_point),
532
+ conclusion: normalizeText(attemptContract.conclusion)
533
+ },
523
534
  source: {
524
535
  spec: normalizeText(payload?.source?.spec),
525
536
  files: normalizeStringList(payload?.source?.files),
@@ -600,6 +611,15 @@ async function syncIncidentLoopForRecord(paths, payload = {}, entry = {}, option
600
611
  tags: normalizeStringList(payload.tags || entry.tags),
601
612
  ontology_tags: normalizeOntologyTags(payload.ontology_tags || entry.ontology_tags),
602
613
  notes: normalizeText(payload.notes || entry.notes),
614
+ attempt_contract: {
615
+ hypothesis: normalizeText(payload?.attempt_contract?.hypothesis || entry?.attempt_contract?.hypothesis),
616
+ change_points: normalizeStringList(payload?.attempt_contract?.change_points || entry?.attempt_contract?.change_points),
617
+ verification_result: normalizeText(
618
+ payload?.attempt_contract?.verification_result || entry?.attempt_contract?.verification_result
619
+ ),
620
+ rollback_point: normalizeText(payload?.attempt_contract?.rollback_point || entry?.attempt_contract?.rollback_point),
621
+ conclusion: normalizeText(payload?.attempt_contract?.conclusion || entry?.attempt_contract?.conclusion)
622
+ },
603
623
  source: {
604
624
  spec: normalizeText(payload?.source?.spec || entry?.source?.spec),
605
625
  files: normalizeStringList(payload?.source?.files || entry?.source?.files),
@@ -695,6 +715,19 @@ function scoreQuality(entry = {}) {
695
715
  if (normalizeText(entry.symptom).length >= 24 && normalizeText(entry.root_cause).length >= 24) {
696
716
  score += 2;
697
717
  }
718
+ const attemptContract = entry && typeof entry.attempt_contract === 'object'
719
+ ? entry.attempt_contract
720
+ : {};
721
+ const attemptContractComplete = Boolean(
722
+ normalizeText(attemptContract.hypothesis)
723
+ && normalizeStringList(attemptContract.change_points).length > 0
724
+ && normalizeText(attemptContract.verification_result)
725
+ && normalizeText(attemptContract.rollback_point)
726
+ && normalizeText(attemptContract.conclusion)
727
+ );
728
+ if (attemptContractComplete) {
729
+ score += 5;
730
+ }
698
731
 
699
732
  return Math.max(0, Math.min(100, score));
700
733
  }
@@ -712,6 +745,24 @@ function validateRecordPayload(payload) {
712
745
  if (!Array.isArray(payload.fix_actions) || payload.fix_actions.length === 0) {
713
746
  throw new Error('at least one --fix-action is required');
714
747
  }
748
+ const attemptContract = payload.attempt_contract && typeof payload.attempt_contract === 'object'
749
+ ? payload.attempt_contract
750
+ : {};
751
+ if (!normalizeText(attemptContract.hypothesis)) {
752
+ throw new Error('attempt contract requires hypothesis');
753
+ }
754
+ if (!Array.isArray(attemptContract.change_points) || attemptContract.change_points.length === 0) {
755
+ throw new Error('attempt contract requires change_points');
756
+ }
757
+ if (!normalizeText(attemptContract.verification_result)) {
758
+ throw new Error('attempt contract requires verification_result');
759
+ }
760
+ if (!normalizeText(attemptContract.rollback_point)) {
761
+ throw new Error('attempt contract requires rollback_point');
762
+ }
763
+ if (!normalizeText(attemptContract.conclusion)) {
764
+ throw new Error('attempt contract requires conclusion');
765
+ }
715
766
 
716
767
  const status = normalizeStatus(payload.status, 'candidate');
717
768
  if (status === 'promoted') {
@@ -807,6 +858,42 @@ function normalizeRecordPayload(options = {}, fromFilePayload = {}) {
807
858
  })
808
859
  };
809
860
 
861
+ const attemptContractFromFile = fromFilePayload && typeof fromFilePayload.attempt_contract === 'object'
862
+ ? fromFilePayload.attempt_contract
863
+ : {};
864
+ payload.attempt_contract = {
865
+ hypothesis: normalizeText(
866
+ options.attemptHypothesis
867
+ || attemptContractFromFile.hypothesis
868
+ || payload.root_cause
869
+ ),
870
+ change_points: normalizeStringList(
871
+ options.attemptChangePoints,
872
+ attemptContractFromFile.change_points,
873
+ attemptContractFromFile.changePoints,
874
+ payload.fix_actions
875
+ ),
876
+ verification_result: normalizeText(
877
+ options.attemptVerificationResult
878
+ || attemptContractFromFile.verification_result
879
+ || attemptContractFromFile.verificationResult
880
+ || (payload.verification_evidence[0] || '')
881
+ || 'pending-verification'
882
+ ),
883
+ rollback_point: normalizeText(
884
+ options.attemptRollbackPoint
885
+ || attemptContractFromFile.rollback_point
886
+ || attemptContractFromFile.rollbackPoint
887
+ || 'not-required'
888
+ ),
889
+ conclusion: normalizeText(
890
+ options.attemptConclusion
891
+ || attemptContractFromFile.conclusion
892
+ || payload.notes
893
+ || payload.root_cause
894
+ )
895
+ };
896
+
810
897
  return payload;
811
898
  }
812
899
 
@@ -872,6 +959,30 @@ function mergeEntry(existingEntry, incomingPayload) {
872
959
  ontology_tags: normalizeOntologyTags(existingEntry.ontology_tags, incomingPayload.ontology_tags),
873
960
  status: selectStatus(existingEntry.status, incomingPayload.status),
874
961
  notes: normalizeText(incomingPayload.notes) || existingEntry.notes || '',
962
+ attempt_contract: {
963
+ hypothesis: normalizeText(incomingPayload?.attempt_contract?.hypothesis)
964
+ || normalizeText(existingEntry?.attempt_contract?.hypothesis)
965
+ || normalizeText(incomingPayload.root_cause)
966
+ || normalizeText(existingEntry.root_cause),
967
+ change_points: normalizeStringList(
968
+ existingEntry?.attempt_contract?.change_points,
969
+ incomingPayload?.attempt_contract?.change_points,
970
+ incomingPayload.fix_actions
971
+ ),
972
+ verification_result: normalizeText(incomingPayload?.attempt_contract?.verification_result)
973
+ || normalizeText(existingEntry?.attempt_contract?.verification_result)
974
+ || normalizeStringList(incomingPayload.verification_evidence, existingEntry.verification_evidence)[0]
975
+ || '',
976
+ rollback_point: normalizeText(incomingPayload?.attempt_contract?.rollback_point)
977
+ || normalizeText(existingEntry?.attempt_contract?.rollback_point)
978
+ || 'not-required',
979
+ conclusion: normalizeText(incomingPayload?.attempt_contract?.conclusion)
980
+ || normalizeText(existingEntry?.attempt_contract?.conclusion)
981
+ || normalizeText(incomingPayload.notes)
982
+ || normalizeText(existingEntry.notes)
983
+ || normalizeText(incomingPayload.root_cause)
984
+ || normalizeText(existingEntry.root_cause)
985
+ },
875
986
  source: {
876
987
  spec: normalizeText(incomingPayload?.source?.spec) || normalizeText(existingEntry?.source?.spec),
877
988
  files: normalizeStringList(existingEntry?.source?.files, incomingPayload?.source?.files),
@@ -1395,7 +1506,7 @@ function evaluateEntryRisk(entry = {}) {
1395
1506
  if (hasHighRiskTag) {
1396
1507
  return 'high';
1397
1508
  }
1398
- if (status === 'candidate' && qualityScore >= 85) {
1509
+ if (status === 'candidate' && qualityScore > 85) {
1399
1510
  return 'high';
1400
1511
  }
1401
1512
  if (status === 'candidate' && qualityScore >= 75 && ontologyTags.includes('decision_policy')) {
@@ -1404,7 +1515,7 @@ function evaluateEntryRisk(entry = {}) {
1404
1515
  if (status === 'candidate') {
1405
1516
  return 'medium';
1406
1517
  }
1407
- if (qualityScore >= 85 && ontologyTags.includes('decision_policy')) {
1518
+ if (qualityScore > 85 && ontologyTags.includes('decision_policy')) {
1408
1519
  return 'high';
1409
1520
  }
1410
1521
  return 'medium';
@@ -1417,6 +1528,9 @@ async function evaluateErrorbookReleaseGate(options = {}, dependencies = {}) {
1417
1528
  const index = await readErrorbookIndex(paths, fileSystem);
1418
1529
  const minRisk = normalizeRiskLevel(options.minRisk || options.min_risk || 'high', 'high');
1419
1530
  const includeVerified = options.includeVerified === true;
1531
+ const minQuality = Number.isFinite(Number(options.minQuality || options.min_quality))
1532
+ ? Math.max(0, Math.min(100, Number(options.minQuality || options.min_quality)))
1533
+ : DEFAULT_RELEASE_GATE_MIN_QUALITY;
1420
1534
 
1421
1535
  const inspected = [];
1422
1536
  const mitigationInspected = [];
@@ -1474,6 +1588,14 @@ async function evaluateErrorbookReleaseGate(options = {}, dependencies = {}) {
1474
1588
  block_reasons: ['risk_threshold']
1475
1589
  }));
1476
1590
 
1591
+ const curationBlocked = inspected
1592
+ .filter((item) => item.status === 'verified' && Number(item.quality_score || 0) < minQuality)
1593
+ .map((item) => ({
1594
+ ...item,
1595
+ block_reasons: ['curation_quality'],
1596
+ policy_violations: [`quality_score<${minQuality}`]
1597
+ }));
1598
+
1477
1599
  const blockedById = new Map();
1478
1600
  for (const item of riskBlocked) {
1479
1601
  blockedById.set(item.id, {
@@ -1497,6 +1619,19 @@ async function evaluateErrorbookReleaseGate(options = {}, dependencies = {}) {
1497
1619
  }
1498
1620
  blockedById.set(existing.id, existing);
1499
1621
  }
1622
+ for (const item of curationBlocked) {
1623
+ const existing = blockedById.get(item.id);
1624
+ if (!existing) {
1625
+ blockedById.set(item.id, {
1626
+ ...item,
1627
+ policy_violations: normalizeStringList(item.policy_violations)
1628
+ });
1629
+ continue;
1630
+ }
1631
+ existing.block_reasons = normalizeStringList(existing.block_reasons, item.block_reasons);
1632
+ existing.policy_violations = normalizeStringList(existing.policy_violations, item.policy_violations);
1633
+ blockedById.set(existing.id, existing);
1634
+ }
1500
1635
 
1501
1636
  const blocked = Array.from(blockedById.values())
1502
1637
  .sort((left, right) => {
@@ -1519,12 +1654,14 @@ async function evaluateErrorbookReleaseGate(options = {}, dependencies = {}) {
1519
1654
  mode: 'errorbook-release-gate',
1520
1655
  gate: {
1521
1656
  min_risk: minRisk,
1657
+ min_quality: minQuality,
1522
1658
  include_verified: includeVerified,
1523
1659
  mitigation_policy_enforced: true
1524
1660
  },
1525
1661
  passed: blocked.length === 0,
1526
1662
  inspected_count: inspected.length,
1527
1663
  risk_blocked_count: riskBlocked.length,
1664
+ curation_blocked_count: curationBlocked.length,
1528
1665
  mitigation_inspected_count: mitigationInspected.length,
1529
1666
  mitigation_blocked_count: mitigationBlocked.length,
1530
1667
  blocked_count: blocked.length,
@@ -1609,6 +1746,7 @@ async function runErrorbookRecordCommand(options = {}, dependencies = {}) {
1609
1746
  source: normalized.source,
1610
1747
  temporary_mitigation: mitigationPayload,
1611
1748
  notes: normalized.notes || '',
1749
+ attempt_contract: normalized.attempt_contract,
1612
1750
  occurrences: 1
1613
1751
  };
1614
1752
  entry.quality_score = scoreQuality(entry);
@@ -2823,6 +2961,7 @@ function registerErrorbookCommands(program) {
2823
2961
  .command('release-gate')
2824
2962
  .description('Block release on unresolved high-risk entries and temporary-mitigation policy violations')
2825
2963
  .option('--min-risk <level>', 'Risk threshold (low|medium|high)', 'high')
2964
+ .option('--min-quality <n>', `Minimum quality for unresolved entries (default: ${DEFAULT_RELEASE_GATE_MIN_QUALITY})`, parseInt)
2826
2965
  .option('--include-verified', 'Also inspect verified (non-promoted) entries')
2827
2966
  .option('--fail-on-block', 'Exit with error when gate is blocked')
2828
2967
  .option('--json', 'Emit machine-readable JSON')
@@ -2873,6 +3012,7 @@ module.exports = {
2873
3012
  HIGH_RISK_SIGNAL_TAGS,
2874
3013
  DEBUG_EVIDENCE_TAGS,
2875
3014
  DEFAULT_PROMOTE_MIN_QUALITY,
3015
+ DEFAULT_RELEASE_GATE_MIN_QUALITY,
2876
3016
  ERRORBOOK_INCIDENT_INDEX_API_VERSION,
2877
3017
  ERRORBOOK_INCIDENT_API_VERSION,
2878
3018
  resolveErrorbookPaths,