scene-capability-engine 3.0.8 → 3.2.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 (51) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/docs/331-poc-adaptation-roadmap.md +21 -2
  3. package/docs/331-poc-dual-track-integration-guide.md +10 -6
  4. package/docs/331-poc-weekly-delivery-checklist.md +5 -0
  5. package/docs/README.md +6 -0
  6. package/docs/command-reference.md +262 -4
  7. package/docs/handoff-profile-integration-guide.md +88 -0
  8. package/docs/interactive-customization/331-poc-sce-integration-checklist.md +148 -0
  9. package/docs/interactive-customization/README.md +362 -0
  10. package/docs/interactive-customization/adapter-extension-contract.md +55 -0
  11. package/docs/interactive-customization/adapter-extension-contract.sample.json +59 -0
  12. package/docs/interactive-customization/adapter-extension-contract.schema.json +192 -0
  13. package/docs/interactive-customization/approval-role-policy-baseline.json +36 -0
  14. package/docs/interactive-customization/change-intent.schema.json +72 -0
  15. package/docs/interactive-customization/change-plan.sample.json +41 -0
  16. package/docs/interactive-customization/change-plan.schema.json +125 -0
  17. package/docs/interactive-customization/cross-industry-replication-guide.md +49 -0
  18. package/docs/interactive-customization/dialogue-governance-policy-baseline.json +49 -0
  19. package/docs/interactive-customization/domain-pack-extension-flow.md +71 -0
  20. package/docs/interactive-customization/execution-record.schema.json +62 -0
  21. package/docs/interactive-customization/governance-alert-playbook.md +51 -0
  22. package/docs/interactive-customization/governance-report-template.md +46 -0
  23. package/docs/interactive-customization/governance-threshold-baseline.json +14 -0
  24. package/docs/interactive-customization/guardrail-policy-baseline.json +27 -0
  25. package/docs/interactive-customization/high-risk-action-catalog.json +22 -0
  26. package/docs/interactive-customization/moqui-adapter-interface.md +40 -0
  27. package/docs/interactive-customization/moqui-context-provider.sample.json +72 -0
  28. package/docs/interactive-customization/moqui-copilot-context-contract.json +50 -0
  29. package/docs/interactive-customization/moqui-copilot-integration-guide.md +100 -0
  30. package/docs/interactive-customization/moqui-interactive-template-playbook.md +94 -0
  31. package/docs/interactive-customization/non-technical-usability-report.md +57 -0
  32. package/docs/interactive-customization/page-context.sample.json +73 -0
  33. package/docs/interactive-customization/page-context.schema.json +150 -0
  34. package/docs/interactive-customization/phase-acceptance-evidence.md +110 -0
  35. package/docs/interactive-customization/runtime-mode-policy-baseline.json +99 -0
  36. package/docs/moqui-template-core-library-playbook.md +28 -0
  37. package/docs/release-checklist.md +29 -4
  38. package/docs/security-governance-default-baseline.md +54 -0
  39. package/docs/starter-kit/README.md +50 -0
  40. package/docs/starter-kit/handoff-manifest.starter.json +32 -0
  41. package/docs/starter-kit/handoff-profile-ci.sample.yml +53 -0
  42. package/docs/starter-kit/release.workflow.sample.yml +41 -0
  43. package/docs/zh/README.md +12 -0
  44. package/lib/auto/moqui-recovery-sequence.js +62 -0
  45. package/lib/commands/auto.js +245 -34
  46. package/lib/commands/scene.js +867 -0
  47. package/lib/data/moqui-capability-lexicon.json +14 -1
  48. package/lib/interactive-customization/change-plan-gate-core.js +201 -0
  49. package/lib/interactive-customization/index.js +9 -0
  50. package/lib/interactive-customization/moqui-interactive-adapter.js +732 -0
  51. package/package.json +27 -2
@@ -0,0 +1,32 @@
1
+ {
2
+ "timestamp": "2026-02-20T00:00:00.000Z",
3
+ "source_project": "E:/workspace/your-project",
4
+ "specs": [
5
+ {
6
+ "id": "60-10-example-capability-spec",
7
+ "status": "completed",
8
+ "scene_package": ".kiro/specs/60-10-example-capability-spec/custom/scene-package.json",
9
+ "scene_manifest": ".kiro/specs/60-10-example-capability-spec/custom/scene.yaml"
10
+ }
11
+ ],
12
+ "templates": [
13
+ "sce.scene--example-capability-template--0.1.0"
14
+ ],
15
+ "capabilities": [
16
+ "example-capability-a",
17
+ "example-capability-b"
18
+ ],
19
+ "known_gaps": [],
20
+ "ontology_validation": {
21
+ "status": "passed",
22
+ "quality_score": 90,
23
+ "business_rules": {
24
+ "total": 1,
25
+ "mapped": 1
26
+ },
27
+ "decision_logic": {
28
+ "total": 1,
29
+ "resolved": 1
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,53 @@
1
+ name: Handoff Intake (Profile)
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ profile:
7
+ description: "handoff profile: default|moqui|enterprise"
8
+ required: true
9
+ default: "moqui"
10
+ manifest:
11
+ description: "handoff manifest path"
12
+ required: true
13
+ default: "docs/handoffs/handoff-manifest.json"
14
+
15
+ jobs:
16
+ handoff-intake:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v3
20
+
21
+ - uses: actions/setup-node@v3
22
+ with:
23
+ node-version: "20.x"
24
+ cache: "npm"
25
+
26
+ - run: npm ci
27
+
28
+ - name: Validate capability matrix (profile scoped)
29
+ shell: bash
30
+ run: |
31
+ set -euo pipefail
32
+ PROFILE="${{ github.event.inputs.profile }}"
33
+ MANIFEST="${{ github.event.inputs.manifest }}"
34
+ npx sce auto handoff capability-matrix \
35
+ --manifest "${MANIFEST}" \
36
+ --profile "${PROFILE}" \
37
+ --fail-on-gap \
38
+ --json
39
+
40
+ - name: Execute handoff run (profile scoped)
41
+ shell: bash
42
+ run: |
43
+ set -euo pipefail
44
+ PROFILE="${{ github.event.inputs.profile }}"
45
+ MANIFEST="${{ github.event.inputs.manifest }}"
46
+ npx sce auto handoff run \
47
+ --manifest "${MANIFEST}" \
48
+ --profile "${PROFILE}" \
49
+ --json
50
+
51
+ - name: Build weekly ops summary
52
+ run: node scripts/release-ops-weekly-summary.js --json
53
+
@@ -0,0 +1,41 @@
1
+ name: Release Starter (SCE)
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v3
13
+
14
+ - uses: actions/setup-node@v3
15
+ with:
16
+ node-version: "20.x"
17
+ cache: "npm"
18
+
19
+ - run: npm ci
20
+ - run: npm test -- --runInBand
21
+ - run: node scripts/interactive-governance-report.js --period weekly --fail-on-alert --json
22
+
23
+ - name: Build release evidence cards
24
+ shell: bash
25
+ run: |
26
+ set -euo pipefail
27
+ TAG="${GITHUB_REF_NAME}"
28
+ NOTES_DIR=".kiro/reports/release-evidence"
29
+ mkdir -p "${NOTES_DIR}"
30
+
31
+ node scripts/release-ops-weekly-summary.js \
32
+ --out "${NOTES_DIR}/weekly-ops-summary-${TAG}.json" \
33
+ --markdown-out "${NOTES_DIR}/weekly-ops-summary-${TAG}.md" \
34
+ --json
35
+
36
+ RELEASE_TAG="${TAG}" \
37
+ RELEASE_EVIDENCE_SUMMARY_FILE="${NOTES_DIR}/release-evidence-summary-${TAG}.json" \
38
+ RELEASE_GOVERNANCE_SNAPSHOT_JSON="${NOTES_DIR}/governance-snapshot-${TAG}.json" \
39
+ RELEASE_GOVERNANCE_SNAPSHOT_MD="${NOTES_DIR}/governance-snapshot-${TAG}.md" \
40
+ node scripts/release-governance-snapshot-export.js
41
+
package/docs/zh/README.md CHANGED
@@ -190,6 +190,12 @@
190
190
  - 主从编排与门禁增强
191
191
  - 跨轮次回归与发布治理集成
192
192
 
193
+ ### [Handoff Profile Integration Guide](../handoff-profile-integration-guide.md)
194
+ **外部项目接入规范(英文)** - `default|moqui|enterprise` 三档 handoff profile 契约
195
+ - profile 默认策略与显式参数覆盖规则
196
+ - 外部项目 manifest/evidence 最小要求
197
+ - 从 `moqui` 到 `enterprise` 的分阶段上线建议
198
+
193
199
  ### [Value 可观测指南](value-observability-guide.md)
194
200
  **KPI 量化交付指南** - 快照、基线、趋势、门禁证据
195
201
  - 周度 KPI 快照生成
@@ -207,6 +213,12 @@
207
213
  - 测试、命令冒烟、打包检查
208
214
  - 文档一致性和 Git 准备状态
209
215
 
216
+ ### [安全治理默认基线](../security-governance-default-baseline.md)
217
+ **默认安全控制(英文)** - 上下文脱敏、审批策略、发布审计证据最小集合
218
+
219
+ ### [发布即用 Starter Kit](../starter-kit/README.md)
220
+ **外部项目接入脚手架(英文)** - handoff manifest 样例与 release workflow 样例
221
+
210
222
  ### [发布归档](releases/README.md)
211
223
  **历史发布入口** - 集中查看发布说明与验证报告
212
224
  - 版本化发布说明
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ const DEFAULT_CLUSTER_GOALS_ARG = '.kiro/auto/matrix-remediation.capability-clusters.json';
4
+ const DEFAULT_BASELINE_ARG = '.kiro/reports/release-evidence/moqui-template-baseline.json';
5
+ const DEFAULT_CLUSTER_PHASED_ALIAS = 'npm run run:matrix-remediation-clusters-phased -- --json';
6
+ const DEFAULT_CLUSTER_BATCH_ALIAS = 'npm run run:matrix-remediation-clusters';
7
+ const DEFAULT_BASELINE_PHASED_ALIAS = 'npm run run:matrix-remediation-from-baseline -- --json';
8
+
9
+ function buildMoquiRegressionRecoverySequenceLines(options = {}) {
10
+ const clusterGoalsArg = options.clusterGoalsArg || DEFAULT_CLUSTER_GOALS_ARG;
11
+ const baselineArg = options.baselineArg || DEFAULT_BASELINE_ARG;
12
+ const clusterPhasedCommand = options.clusterPhasedCommand
13
+ || `node scripts/moqui-matrix-remediation-phased-runner.js --cluster-goals ${clusterGoalsArg} --json`;
14
+ const clusterBatchCommand = options.clusterBatchCommand
15
+ || `sce auto close-loop-batch ${clusterGoalsArg} --format json --batch-parallel 1 --batch-agent-budget 2 --batch-retry-until-complete --json`;
16
+ const baselinePhasedCommand = options.baselinePhasedCommand
17
+ || `node scripts/moqui-matrix-remediation-phased-runner.js --baseline ${baselineArg} --json`;
18
+ const clusterPhasedAlias = options.clusterPhasedAlias || DEFAULT_CLUSTER_PHASED_ALIAS;
19
+ const clusterBatchAlias = options.clusterBatchAlias || DEFAULT_CLUSTER_BATCH_ALIAS;
20
+ const baselinePhasedAlias = options.baselinePhasedAlias || DEFAULT_BASELINE_PHASED_ALIAS;
21
+
22
+ const includeLabel = options.includeLabel !== false;
23
+ const includeStep1Alias = options.includeStep1Alias !== false;
24
+ const includeStep1Fallback = options.includeStep1Fallback !== false;
25
+ const includeStep1FallbackAlias = options.includeStep1FallbackAlias !== false;
26
+ const includeStep2Alias = options.includeStep2Alias !== false;
27
+
28
+ const wrapCommands = options.wrapCommands === true;
29
+ const withPeriod = options.withPeriod === true;
30
+ const formatCommand = command => (wrapCommands ? `\`${command}\`` : command);
31
+ const suffix = withPeriod ? '.' : '';
32
+ const lines = [];
33
+
34
+ if (includeLabel) {
35
+ lines.push('Moqui regression recovery sequence (recommended):');
36
+ }
37
+ lines.push(`Step 1 (Cluster phased): ${formatCommand(clusterPhasedCommand)}${suffix}`);
38
+ if (includeStep1Alias) {
39
+ lines.push(`Step 1 alias: ${formatCommand(clusterPhasedAlias)}${suffix}`);
40
+ }
41
+ if (includeStep1Fallback) {
42
+ lines.push(`Step 1 fallback (cluster batch): ${formatCommand(clusterBatchCommand)}${suffix}`);
43
+ }
44
+ if (includeStep1FallbackAlias) {
45
+ lines.push(`Step 1 fallback alias: ${formatCommand(clusterBatchAlias)}${suffix}`);
46
+ }
47
+ lines.push(`Step 2 (Baseline phased): ${formatCommand(baselinePhasedCommand)}${suffix}`);
48
+ if (includeStep2Alias) {
49
+ lines.push(`Step 2 alias: ${formatCommand(baselinePhasedAlias)}${suffix}`);
50
+ }
51
+
52
+ return lines;
53
+ }
54
+
55
+ module.exports = {
56
+ DEFAULT_CLUSTER_GOALS_ARG,
57
+ DEFAULT_BASELINE_ARG,
58
+ DEFAULT_CLUSTER_PHASED_ALIAS,
59
+ DEFAULT_CLUSTER_BATCH_ALIAS,
60
+ DEFAULT_BASELINE_PHASED_ALIAS,
61
+ buildMoquiRegressionRecoverySequenceLines
62
+ };
@@ -6,6 +6,7 @@ const AutonomousEngine = require('../auto/autonomous-engine');
6
6
  const { mergeConfigs, DEFAULT_CONFIG } = require('../auto/config-schema');
7
7
  const { runAutoCloseLoop } = require('../auto/close-loop-runner');
8
8
  const { analyzeGoalSemantics } = require('../auto/semantic-decomposer');
9
+ const { buildMoquiRegressionRecoverySequenceLines } = require('../auto/moqui-recovery-sequence');
9
10
  const MOQUI_CAPABILITY_LEXICON = require('../data/moqui-capability-lexicon.json');
10
11
  const fs = require('fs-extra');
11
12
  const path = require('path');
@@ -27,8 +28,68 @@ const AUTO_HANDOFF_SCENE_PACKAGE_BATCH_TASK_QUEUE_FILE = '.kiro/auto/ontology-re
27
28
  const AUTO_HANDOFF_MOQUI_CAPABILITY_COVERAGE_JSON_FILE = '.kiro/reports/release-evidence/moqui-capability-coverage.json';
28
29
  const AUTO_HANDOFF_MOQUI_CAPABILITY_COVERAGE_MARKDOWN_FILE = '.kiro/reports/release-evidence/moqui-capability-coverage.md';
29
30
  const AUTO_HANDOFF_MOQUI_REMEDIATION_QUEUE_FILE = '.kiro/auto/moqui-remediation.lines';
31
+ const AUTO_HANDOFF_MOQUI_CLUSTER_REMEDIATION_FILE = '.kiro/auto/matrix-remediation.capability-clusters.json';
30
32
  const AUTO_HANDOFF_CLI_SCRIPT_FILE = path.resolve(__dirname, '..', '..', 'bin', 'scene-capability-engine.js');
31
33
  const MOQUI_CAPABILITY_LEXICON_INDEX = buildMoquiCapabilityLexiconIndex(MOQUI_CAPABILITY_LEXICON);
34
+ const AUTO_HANDOFF_POLICY_PROFILE_PRESETS = {
35
+ default: {
36
+ min_spec_success_rate: 100,
37
+ max_risk_level: 'high',
38
+ min_ontology_score: 0,
39
+ min_capability_coverage_percent: 100,
40
+ min_capability_semantic_percent: 100,
41
+ max_moqui_matrix_regressions: 0,
42
+ max_unmapped_rules: null,
43
+ max_undecided_decisions: null,
44
+ require_ontology_validation: true,
45
+ require_moqui_baseline: true,
46
+ require_scene_package_batch: true,
47
+ require_capability_coverage: true,
48
+ require_capability_semantic: true,
49
+ require_capability_lexicon: true,
50
+ require_release_gate_preflight: false,
51
+ dependency_batching: true,
52
+ release_evidence_window: 5
53
+ },
54
+ moqui: {
55
+ min_spec_success_rate: 100,
56
+ max_risk_level: 'high',
57
+ min_ontology_score: 0,
58
+ min_capability_coverage_percent: 100,
59
+ min_capability_semantic_percent: 100,
60
+ max_moqui_matrix_regressions: 0,
61
+ max_unmapped_rules: null,
62
+ max_undecided_decisions: null,
63
+ require_ontology_validation: true,
64
+ require_moqui_baseline: true,
65
+ require_scene_package_batch: true,
66
+ require_capability_coverage: true,
67
+ require_capability_semantic: true,
68
+ require_capability_lexicon: true,
69
+ require_release_gate_preflight: false,
70
+ dependency_batching: true,
71
+ release_evidence_window: 5
72
+ },
73
+ enterprise: {
74
+ min_spec_success_rate: 100,
75
+ max_risk_level: 'medium',
76
+ min_ontology_score: 0,
77
+ min_capability_coverage_percent: 100,
78
+ min_capability_semantic_percent: 100,
79
+ max_moqui_matrix_regressions: 0,
80
+ max_unmapped_rules: null,
81
+ max_undecided_decisions: null,
82
+ require_ontology_validation: true,
83
+ require_moqui_baseline: true,
84
+ require_scene_package_batch: true,
85
+ require_capability_coverage: true,
86
+ require_capability_semantic: true,
87
+ require_capability_lexicon: true,
88
+ require_release_gate_preflight: true,
89
+ dependency_batching: true,
90
+ release_evidence_window: 10
91
+ }
92
+ };
32
93
 
33
94
  /**
34
95
  * Register auto commands
@@ -1532,6 +1593,7 @@ function registerAutoCommands(program) {
1532
1593
  .command('capability-matrix')
1533
1594
  .description('Build Moqui template capability matrix from handoff manifest and local template library')
1534
1595
  .requiredOption('--manifest <path>', 'Path to handoff-manifest.json')
1596
+ .option('--profile <profile>', 'Handoff policy profile: default|moqui|enterprise (default: default)', 'default')
1535
1597
  .option('--strict', 'Fail when manifest validation contains errors')
1536
1598
  .option('--strict-warnings', 'Fail when manifest validation contains warnings')
1537
1599
  .option('--min-capability-coverage <n>', 'Minimum Moqui capability coverage percent (default: 100)', parseFloat)
@@ -1567,6 +1629,7 @@ function registerAutoCommands(program) {
1567
1629
  console.log(chalk.blue('Auto handoff capability matrix:'));
1568
1630
  console.log(chalk.gray(` Status: ${result.status}`));
1569
1631
  console.log(chalk.gray(` Manifest: ${result.manifest_path}`));
1632
+ console.log(chalk.gray(` Policy profile: ${result.policy && result.policy.profile ? result.policy.profile : 'default'}`));
1570
1633
  console.log(chalk.gray(` Capabilities: ${result.handoff.capability_count}`));
1571
1634
  if (result.capability_coverage && result.capability_coverage.summary) {
1572
1635
  const summary = result.capability_coverage.summary;
@@ -1871,6 +1934,7 @@ function registerAutoCommands(program) {
1871
1934
  .command('run')
1872
1935
  .description('Execute handoff integration pipeline: plan -> queue -> close-loop-batch -> observability')
1873
1936
  .requiredOption('--manifest <path>', 'Path to handoff-manifest.json')
1937
+ .option('--profile <profile>', 'Handoff policy profile: default|moqui|enterprise (default: default)', 'default')
1874
1938
  .option('--out <path>', 'Write handoff run report JSON to file')
1875
1939
  .option('--queue-out <path>', `Queue output file (default: ${AUTO_HANDOFF_DEFAULT_QUEUE_FILE})`, AUTO_HANDOFF_DEFAULT_QUEUE_FILE)
1876
1940
  .option('--append', 'Append generated goals to existing queue file')
@@ -1889,7 +1953,7 @@ function registerAutoCommands(program) {
1889
1953
  .option('--batch-retry-until-complete', 'Retry until all goals complete or retry max is reached')
1890
1954
  .option('--batch-retry-max-rounds <n>', 'Max retry rounds when --batch-retry-until-complete is enabled', parseInt)
1891
1955
  .option('--min-spec-success-rate <n>', 'Gate: minimum handoff spec success rate percent (default: 100)', parseFloat)
1892
- .option('--max-risk-level <level>', 'Gate: maximum allowed risk level (low|medium|high)', 'high')
1956
+ .option('--max-risk-level <level>', 'Gate: maximum allowed risk level (low|medium|high)')
1893
1957
  .option('--min-ontology-score <n>', 'Gate: minimum ontology quality score (0-100, default: 0)', parseFloat)
1894
1958
  .option('--max-unmapped-rules <n>', 'Gate: maximum allowed unmapped business rules (optional)', parseInt)
1895
1959
  .option('--max-undecided-decisions <n>', 'Gate: maximum allowed undecided decisions (optional)', parseInt)
@@ -1919,6 +1983,7 @@ function registerAutoCommands(program) {
1919
1983
  console.log(chalk.gray(` Session: ${result.session_id}`));
1920
1984
  console.log(chalk.gray(` Status: ${result.status}`));
1921
1985
  console.log(chalk.gray(` Manifest: ${result.manifest_path}`));
1986
+ console.log(chalk.gray(` Policy profile: ${result.policy && result.policy.profile ? result.policy.profile : 'default'}`));
1922
1987
  console.log(chalk.gray(` Specs: ${result.handoff && result.handoff.spec_count ? result.handoff.spec_count : 0}`));
1923
1988
  console.log(chalk.gray(` Queue goals: ${result.queue && result.queue.goal_count ? result.queue.goal_count : 0}`));
1924
1989
  if (result.template_diff) {
@@ -8712,6 +8777,12 @@ function buildAutoHandoffRegressionRecommendations(payload = {}) {
8712
8777
  'Recover Moqui matrix regressions and rerun baseline gate: ' +
8713
8778
  '`sce scene moqui-baseline --include-all --compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json`.'
8714
8779
  );
8780
+ for (const line of buildMoquiRegressionRecoverySequenceLines({
8781
+ wrapCommands: true,
8782
+ withPeriod: true
8783
+ })) {
8784
+ push(line);
8785
+ }
8715
8786
  }
8716
8787
 
8717
8788
  if ((payload.window && Number(payload.window.actual) > 0) && (payload.window.requested !== payload.window.actual)) {
@@ -10850,29 +10921,144 @@ function normalizeHandoffReleaseEvidenceWindow(windowCandidate) {
10850
10921
  return parsed;
10851
10922
  }
10852
10923
 
10924
+ function normalizeAutoHandoffPolicyProfile(profileCandidate, optionName = '--profile') {
10925
+ const normalized = typeof profileCandidate === 'string'
10926
+ ? profileCandidate.trim().toLowerCase()
10927
+ : 'default';
10928
+ if (!normalized) {
10929
+ return 'default';
10930
+ }
10931
+ if (!AUTO_HANDOFF_POLICY_PROFILE_PRESETS[normalized]) {
10932
+ const allowed = Object.keys(AUTO_HANDOFF_POLICY_PROFILE_PRESETS).join(', ');
10933
+ throw new Error(`${optionName} must be one of: ${allowed}.`);
10934
+ }
10935
+ return normalized;
10936
+ }
10937
+
10938
+ function resolveAutoHandoffPolicyPreset(profileCandidate, optionName) {
10939
+ const profile = normalizeAutoHandoffPolicyProfile(profileCandidate, optionName);
10940
+ const preset = AUTO_HANDOFF_POLICY_PROFILE_PRESETS[profile];
10941
+ return {
10942
+ profile,
10943
+ preset: {
10944
+ ...preset
10945
+ }
10946
+ };
10947
+ }
10948
+
10949
+ function resolveAutoHandoffPolicyOptionNumber(valueCandidate, fallbackValue) {
10950
+ if (valueCandidate === undefined || valueCandidate === null || valueCandidate === '') {
10951
+ return fallbackValue;
10952
+ }
10953
+ return valueCandidate;
10954
+ }
10955
+
10956
+ function resolveAutoHandoffPolicyOptionBoolean(valueCandidate, fallbackValue) {
10957
+ if (valueCandidate === undefined || valueCandidate === null) {
10958
+ return fallbackValue === true;
10959
+ }
10960
+ return valueCandidate === true;
10961
+ }
10962
+
10853
10963
  function buildAutoHandoffRunPolicy(options = {}) {
10964
+ const { profile, preset } = resolveAutoHandoffPolicyPreset(options.profile, '--profile');
10854
10965
  return {
10855
- min_spec_success_rate: normalizeHandoffMinSpecSuccessRate(options.minSpecSuccessRate),
10856
- max_risk_level: normalizeHandoffRiskLevel(options.maxRiskLevel),
10857
- min_ontology_score: normalizeHandoffMinOntologyScore(options.minOntologyScore),
10858
- min_capability_coverage_percent: normalizeHandoffMinCapabilityCoverage(options.minCapabilityCoverage),
10859
- max_moqui_matrix_regressions: normalizeHandoffMaxMoquiMatrixRegressions(options.maxMoquiMatrixRegressions),
10966
+ profile,
10967
+ min_spec_success_rate: normalizeHandoffMinSpecSuccessRate(
10968
+ resolveAutoHandoffPolicyOptionNumber(options.minSpecSuccessRate, preset.min_spec_success_rate)
10969
+ ),
10970
+ max_risk_level: normalizeHandoffRiskLevel(
10971
+ resolveAutoHandoffPolicyOptionNumber(options.maxRiskLevel, preset.max_risk_level)
10972
+ ),
10973
+ min_ontology_score: normalizeHandoffMinOntologyScore(
10974
+ resolveAutoHandoffPolicyOptionNumber(options.minOntologyScore, preset.min_ontology_score)
10975
+ ),
10976
+ min_capability_coverage_percent: normalizeHandoffMinCapabilityCoverage(
10977
+ resolveAutoHandoffPolicyOptionNumber(
10978
+ options.minCapabilityCoverage,
10979
+ preset.min_capability_coverage_percent
10980
+ )
10981
+ ),
10982
+ max_moqui_matrix_regressions: normalizeHandoffMaxMoquiMatrixRegressions(
10983
+ resolveAutoHandoffPolicyOptionNumber(
10984
+ options.maxMoquiMatrixRegressions,
10985
+ preset.max_moqui_matrix_regressions
10986
+ )
10987
+ ),
10860
10988
  max_unmapped_rules: normalizeHandoffOptionalNonNegativeInteger(
10861
- options.maxUnmappedRules,
10989
+ resolveAutoHandoffPolicyOptionNumber(options.maxUnmappedRules, preset.max_unmapped_rules),
10862
10990
  '--max-unmapped-rules'
10863
10991
  ),
10864
10992
  max_undecided_decisions: normalizeHandoffOptionalNonNegativeInteger(
10865
- options.maxUndecidedDecisions,
10993
+ resolveAutoHandoffPolicyOptionNumber(options.maxUndecidedDecisions, preset.max_undecided_decisions),
10866
10994
  '--max-undecided-decisions'
10867
10995
  ),
10868
- require_ontology_validation: options.requireOntologyValidation !== false,
10869
- require_moqui_baseline: options.requireMoquiBaseline !== false,
10870
- require_scene_package_batch: options.requireScenePackageBatch !== false,
10871
- require_capability_coverage: options.requireCapabilityCoverage !== false,
10872
- require_capability_lexicon: options.requireCapabilityLexicon !== false,
10873
- require_release_gate_preflight: options.requireReleaseGatePreflight === true,
10874
- dependency_batching: options.dependencyBatching !== false,
10875
- release_evidence_window: normalizeHandoffReleaseEvidenceWindow(options.releaseEvidenceWindow)
10996
+ require_ontology_validation: resolveAutoHandoffPolicyOptionBoolean(
10997
+ options.requireOntologyValidation,
10998
+ preset.require_ontology_validation
10999
+ ),
11000
+ require_moqui_baseline: resolveAutoHandoffPolicyOptionBoolean(
11001
+ options.requireMoquiBaseline,
11002
+ preset.require_moqui_baseline
11003
+ ),
11004
+ require_scene_package_batch: resolveAutoHandoffPolicyOptionBoolean(
11005
+ options.requireScenePackageBatch,
11006
+ preset.require_scene_package_batch
11007
+ ),
11008
+ require_capability_coverage: resolveAutoHandoffPolicyOptionBoolean(
11009
+ options.requireCapabilityCoverage,
11010
+ preset.require_capability_coverage
11011
+ ),
11012
+ require_capability_lexicon: resolveAutoHandoffPolicyOptionBoolean(
11013
+ options.requireCapabilityLexicon,
11014
+ preset.require_capability_lexicon
11015
+ ),
11016
+ require_release_gate_preflight: resolveAutoHandoffPolicyOptionBoolean(
11017
+ options.requireReleaseGatePreflight,
11018
+ preset.require_release_gate_preflight
11019
+ ),
11020
+ dependency_batching: resolveAutoHandoffPolicyOptionBoolean(
11021
+ options.dependencyBatching,
11022
+ preset.dependency_batching
11023
+ ),
11024
+ release_evidence_window: normalizeHandoffReleaseEvidenceWindow(
11025
+ resolveAutoHandoffPolicyOptionNumber(options.releaseEvidenceWindow, preset.release_evidence_window)
11026
+ )
11027
+ };
11028
+ }
11029
+
11030
+ function buildAutoHandoffCapabilityMatrixPolicy(options = {}) {
11031
+ const { profile, preset } = resolveAutoHandoffPolicyPreset(options.profile, '--profile');
11032
+ return {
11033
+ profile,
11034
+ min_capability_coverage_percent: normalizeHandoffMinCapabilityCoverage(
11035
+ resolveAutoHandoffPolicyOptionNumber(
11036
+ options.minCapabilityCoverage,
11037
+ preset.min_capability_coverage_percent
11038
+ )
11039
+ ),
11040
+ min_capability_semantic_percent: normalizeHandoffMinCapabilitySemantic(
11041
+ resolveAutoHandoffPolicyOptionNumber(
11042
+ options.minCapabilitySemantic,
11043
+ preset.min_capability_semantic_percent
11044
+ )
11045
+ ),
11046
+ require_capability_coverage: resolveAutoHandoffPolicyOptionBoolean(
11047
+ options.requireCapabilityCoverage,
11048
+ preset.require_capability_coverage
11049
+ ),
11050
+ require_capability_semantic: resolveAutoHandoffPolicyOptionBoolean(
11051
+ options.requireCapabilitySemantic,
11052
+ preset.require_capability_semantic
11053
+ ),
11054
+ require_capability_lexicon: resolveAutoHandoffPolicyOptionBoolean(
11055
+ options.requireCapabilityLexicon,
11056
+ preset.require_capability_lexicon
11057
+ ),
11058
+ require_moqui_baseline: resolveAutoHandoffPolicyOptionBoolean(
11059
+ options.requireMoquiBaseline,
11060
+ preset.require_moqui_baseline
11061
+ )
10876
11062
  };
10877
11063
  }
10878
11064
 
@@ -11741,6 +11927,27 @@ function buildAutoHandoffRunRecommendations(projectPath, result) {
11741
11927
  const processedGoals = Number(summary && summary.processed_goals) || 0;
11742
11928
  const failedGoals = Number(summary && summary.failed_goals) || 0;
11743
11929
  const hasPendingOrFailed = totalGoals > 0 && (failedGoals > 0 || processedGoals < totalGoals);
11930
+ const moquiBaseline = result && result.moqui_baseline && typeof result.moqui_baseline === 'object'
11931
+ ? result.moqui_baseline
11932
+ : null;
11933
+ const moquiSummary = moquiBaseline && moquiBaseline.summary && typeof moquiBaseline.summary === 'object'
11934
+ ? moquiBaseline.summary
11935
+ : null;
11936
+ const moquiCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
11937
+ ? moquiBaseline.compare
11938
+ : {};
11939
+ const moquiCoverageRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
11940
+ const pushMoquiClusterFirstRecoverySequence = () => {
11941
+ const lines = buildMoquiRegressionRecoverySequenceLines({
11942
+ clusterGoalsArg: quoteCliArg(AUTO_HANDOFF_MOQUI_CLUSTER_REMEDIATION_FILE),
11943
+ baselineArg: quoteCliArg(AUTO_HANDOFF_MOQUI_BASELINE_JSON_FILE),
11944
+ wrapCommands: false,
11945
+ withPeriod: false
11946
+ });
11947
+ for (const line of lines) {
11948
+ push(line);
11949
+ }
11950
+ };
11744
11951
 
11745
11952
  if (manifestPath && result.session_id && hasPendingOrFailed) {
11746
11953
  push(
@@ -11834,18 +12041,11 @@ function buildAutoHandoffRunRecommendations(projectPath, result) {
11834
12041
  toAutoHandoffCliPath(projectPath, result.remediation_queue.file)
11835
12042
  )} --format lines --json`
11836
12043
  );
12044
+ if (moquiCoverageRegressions.length > 0) {
12045
+ pushMoquiClusterFirstRecoverySequence();
12046
+ }
11837
12047
  }
11838
12048
 
11839
- const moquiBaseline = result && result.moqui_baseline && typeof result.moqui_baseline === 'object'
11840
- ? result.moqui_baseline
11841
- : null;
11842
- const moquiSummary = moquiBaseline && moquiBaseline.summary && typeof moquiBaseline.summary === 'object'
11843
- ? moquiBaseline.summary
11844
- : null;
11845
- const moquiCompare = moquiBaseline && moquiBaseline.compare && typeof moquiBaseline.compare === 'object'
11846
- ? moquiBaseline.compare
11847
- : {};
11848
- const moquiCoverageRegressions = buildAutoHandoffMoquiCoverageRegressions(moquiCompare);
11849
12049
  if (moquiBaseline && moquiBaseline.status === 'error') {
11850
12050
  push('sce scene moqui-baseline --json');
11851
12051
  } else if (moquiSummary && moquiSummary.portfolio_passed === false) {
@@ -11867,6 +12067,7 @@ function buildAutoHandoffRunRecommendations(projectPath, result) {
11867
12067
  'sce scene moqui-baseline --include-all ' +
11868
12068
  '--compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json'
11869
12069
  );
12070
+ pushMoquiClusterFirstRecoverySequence();
11870
12071
  if (manifestPath) {
11871
12072
  push(
11872
12073
  `sce auto handoff run --manifest ${manifestCli} ` +
@@ -13409,6 +13610,14 @@ function buildAutoHandoffCapabilityMatrixRecommendations(result = {}) {
13409
13610
  `Recover Moqui matrix regressions: ` +
13410
13611
  `${baselineRegressions.slice(0, 3).map(item => `${item.label}:${item.delta_rate_percent}%`).join(' | ')}`
13411
13612
  );
13613
+ for (const line of buildMoquiRegressionRecoverySequenceLines({
13614
+ clusterGoalsArg: quoteCliArg(AUTO_HANDOFF_MOQUI_CLUSTER_REMEDIATION_FILE),
13615
+ baselineArg: quoteCliArg(AUTO_HANDOFF_MOQUI_BASELINE_JSON_FILE),
13616
+ wrapCommands: false,
13617
+ withPeriod: false
13618
+ })) {
13619
+ push(line);
13620
+ }
13412
13621
  }
13413
13622
  if (capabilityCoverage.status === 'skipped') {
13414
13623
  push('Declare `capabilities` in handoff manifest to enable capability matrix coverage gates.');
@@ -13505,6 +13714,7 @@ function renderAutoHandoffCapabilityMatrixMarkdown(payload = {}) {
13505
13714
  `- Specs: ${handoff.spec_count !== undefined ? handoff.spec_count : 'n/a'}`,
13506
13715
  `- Templates: ${handoff.template_count !== undefined ? handoff.template_count : 'n/a'}`,
13507
13716
  `- Capabilities: ${handoff.capability_count !== undefined ? handoff.capability_count : 'n/a'}`,
13717
+ `- Policy profile: ${policy.profile || 'default'}`,
13508
13718
  `- Min capability coverage: ${policy.min_capability_coverage_percent !== undefined ? `${policy.min_capability_coverage_percent}%` : 'n/a'}`,
13509
13719
  `- Min capability semantic completeness: ${policy.min_capability_semantic_percent !== undefined ? `${policy.min_capability_semantic_percent}%` : 'n/a'}`,
13510
13720
  `- Capability lexicon gate: ${policy.require_capability_lexicon === false ? 'disabled' : 'enabled'}`,
@@ -13599,14 +13809,7 @@ async function buildAutoHandoffCapabilityMatrix(projectPath, options = {}) {
13599
13809
  strictWarnings: options.strictWarnings
13600
13810
  });
13601
13811
 
13602
- const policy = {
13603
- min_capability_coverage_percent: normalizeHandoffMinCapabilityCoverage(options.minCapabilityCoverage),
13604
- min_capability_semantic_percent: normalizeHandoffMinCapabilitySemantic(options.minCapabilitySemantic),
13605
- require_capability_coverage: true,
13606
- require_capability_semantic: options.requireCapabilitySemantic !== false,
13607
- require_capability_lexicon: options.requireCapabilityLexicon !== false,
13608
- require_moqui_baseline: true
13609
- };
13812
+ const policy = buildAutoHandoffCapabilityMatrixPolicy(options);
13610
13813
 
13611
13814
  const [templateDiff, moquiBaseline, capabilityCoverage] = await Promise.all([
13612
13815
  buildAutoHandoffTemplateDiff(projectPath, { handoff: plan.handoff }),
@@ -18911,6 +19114,10 @@ function buildGovernanceRecommendations(summary) {
18911
19114
  '`sce scene moqui-baseline --include-all ' +
18912
19115
  '--compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json`.'
18913
19116
  );
19117
+ recommendations.push(...buildMoquiRegressionRecoverySequenceLines({
19118
+ wrapCommands: true,
19119
+ withPeriod: true
19120
+ }));
18914
19121
  }
18915
19122
  }
18916
19123
 
@@ -20392,6 +20599,10 @@ function buildGovernanceCloseLoopRecommendations(finalAssessment, stopReason, st
20392
20599
  '`sce scene moqui-baseline --include-all ' +
20393
20600
  '--compare-with .kiro/reports/release-evidence/moqui-template-baseline.json --json`.'
20394
20601
  );
20602
+ base.push(...buildMoquiRegressionRecoverySequenceLines({
20603
+ wrapCommands: true,
20604
+ withPeriod: true
20605
+ }));
20395
20606
  }
20396
20607
  if (reasons.some(item => `${item}`.startsWith('handoff-capability-') && `${item}`.includes('unknown'))) {
20397
20608
  base.push(