scene-capability-engine 3.6.5 → 3.6.7
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 +25 -0
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/docs/command-reference.md +5 -1
- package/lib/state/sce-state-store.js +426 -0
- package/lib/state/state-migration-manager.js +141 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.6.7] - 2026-03-05
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `state-migration-reconciliation-gate` now treats `blocking` checks as advisory by default and only fails when `--fail-on-blocking` is explicitly set.
|
|
14
|
+
- Release workflow reconciliation step now adds `--fail-on-blocking` only in enforce mode, preventing advisory mode from failing npm publish.
|
|
15
|
+
|
|
16
|
+
## [3.6.6] - 2026-03-05
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- Stage-4 SQLite migration components for release evidence indexes:
|
|
20
|
+
- `release.evidence-runs-index` (`.sce/reports/release-evidence/handoff-runs.json`)
|
|
21
|
+
- `release.gate-history-index` (`.sce/reports/release-evidence/release-gate-history.json`)
|
|
22
|
+
- New SQLite index tables in state store:
|
|
23
|
+
- `release_evidence_run_registry`
|
|
24
|
+
- `release_gate_history_registry`
|
|
25
|
+
- New `SceStateStore` APIs:
|
|
26
|
+
- `upsert/listReleaseEvidenceRunRecords`
|
|
27
|
+
- `upsert/listReleaseGateHistoryRecords`
|
|
28
|
+
- Release workflow gate integration:
|
|
29
|
+
- new step `state_migration_reconciliation`
|
|
30
|
+
- new release asset `.sce/reports/release-evidence/state-migration-reconciliation-<tag>.json`
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- `sce state plan/doctor/migrate/export` now includes release-evidence components in migration scope and parity summaries.
|
|
34
|
+
|
|
10
35
|
## [3.6.5] - 2026-03-05
|
|
11
36
|
|
|
12
37
|
### Added
|
package/README.md
CHANGED
|
@@ -153,7 +153,7 @@ Studio task-stream output contract (default):
|
|
|
153
153
|
- reconciliation gate: `npm run gate:state-migration-reconciliation`
|
|
154
154
|
- runtime reads now prefer sqlite indexes for timeline/scene-session views when indexed data exists
|
|
155
155
|
- `state doctor` now emits `summary` and runtime diagnostics (`runtime.timeline`, `runtime.scene_session`) with read-source and consistency status
|
|
156
|
-
- migratable components now include errorbook + spec-governance indexes (`errorbook.entry-index`, `errorbook.incident-index`, `governance.spec-scene-overrides`, `governance.scene-index`)
|
|
156
|
+
- migratable components now include runtime + errorbook + spec-governance + release evidence indexes (`errorbook.entry-index`, `errorbook.incident-index`, `governance.spec-scene-overrides`, `governance.scene-index`, `release.evidence-runs-index`, `release.gate-history-index`)
|
|
157
157
|
- Write authorization lease model (SQLite-backed):
|
|
158
158
|
- policy file: `.sce/config/authorization-policy.json`
|
|
159
159
|
- grant lease: `sce auth grant --scope studio:* --reason "<reason>" --auth-password <password> --json`
|
package/README.zh.md
CHANGED
|
@@ -153,7 +153,7 @@ Studio 任务流输出契约(默认):
|
|
|
153
153
|
- 对账门禁:`npm run gate:state-migration-reconciliation`
|
|
154
154
|
- 运行时读取在存在索引数据时优先使用 SQLite(timeline/scene-session 视图)
|
|
155
155
|
- `state doctor` 新增 `summary` 与运行时诊断(`runtime.timeline`、`runtime.scene_session`),可直接读取读源与一致性状态
|
|
156
|
-
- 可迁移组件扩展到 errorbook + spec-governance 索引(`errorbook.entry-index`、`errorbook.incident-index`、`governance.spec-scene-overrides`、`governance.scene-index`)
|
|
156
|
+
- 可迁移组件扩展到 runtime + errorbook + spec-governance + release evidence 索引(`errorbook.entry-index`、`errorbook.incident-index`、`governance.spec-scene-overrides`、`governance.scene-index`、`release.evidence-runs-index`、`release.gate-history-index`)
|
|
157
157
|
- 写入授权租约模型(SQLite 持久化):
|
|
158
158
|
- 策略文件:`.sce/config/authorization-policy.json`
|
|
159
159
|
- 申请租约:`sce auth grant --scope studio:* --reason "<原因>" --auth-password <密码> --json`
|
|
@@ -727,7 +727,7 @@ sce state export --out .sce/reports/state-migration/state-export.latest.json --j
|
|
|
727
727
|
|
|
728
728
|
# reconciliation gate (non-blocking by default; choose strict flags as needed)
|
|
729
729
|
npm run gate:state-migration-reconciliation
|
|
730
|
-
node scripts/state-migration-reconciliation-gate.js --fail-on-alert --fail-on-pending --json
|
|
730
|
+
node scripts/state-migration-reconciliation-gate.js --fail-on-blocking --fail-on-alert --fail-on-pending --json
|
|
731
731
|
```
|
|
732
732
|
|
|
733
733
|
Current migratable components:
|
|
@@ -738,6 +738,8 @@ Current migratable components:
|
|
|
738
738
|
- `errorbook.incident-index` (`.sce/errorbook/staging/index.json`)
|
|
739
739
|
- `governance.spec-scene-overrides` (`.sce/spec-governance/spec-scene-overrides.json`)
|
|
740
740
|
- `governance.scene-index` (`.sce/spec-governance/scene-index.json`)
|
|
741
|
+
- `release.evidence-runs-index` (`.sce/reports/release-evidence/handoff-runs.json`)
|
|
742
|
+
- `release.gate-history-index` (`.sce/reports/release-evidence/release-gate-history.json`)
|
|
741
743
|
|
|
742
744
|
SQLite index tables introduced for gradual migration:
|
|
743
745
|
- `agent_runtime_registry`
|
|
@@ -747,6 +749,8 @@ SQLite index tables introduced for gradual migration:
|
|
|
747
749
|
- `errorbook_incident_index_registry`
|
|
748
750
|
- `governance_spec_scene_override_registry`
|
|
749
751
|
- `governance_scene_index_registry`
|
|
752
|
+
- `release_evidence_run_registry`
|
|
753
|
+
- `release_gate_history_registry`
|
|
750
754
|
- `state_migration_registry`
|
|
751
755
|
|
|
752
756
|
Runtime read preference:
|
|
@@ -137,6 +137,8 @@ class SceStateStore {
|
|
|
137
137
|
errorbook_incident_index: {},
|
|
138
138
|
governance_spec_scene_override: {},
|
|
139
139
|
governance_scene_index: {},
|
|
140
|
+
release_evidence_run: {},
|
|
141
|
+
release_gate_history: {},
|
|
140
142
|
migration_records: {},
|
|
141
143
|
auth_leases: {},
|
|
142
144
|
auth_events: [],
|
|
@@ -407,6 +409,54 @@ class SceStateStore {
|
|
|
407
409
|
|
|
408
410
|
CREATE INDEX IF NOT EXISTS idx_governance_scene_index_registry_counts
|
|
409
411
|
ON governance_scene_index_registry(total_specs DESC, active_specs DESC);
|
|
412
|
+
|
|
413
|
+
CREATE TABLE IF NOT EXISTS release_evidence_run_registry (
|
|
414
|
+
session_id TEXT PRIMARY KEY,
|
|
415
|
+
merged_at TEXT,
|
|
416
|
+
status TEXT,
|
|
417
|
+
gate_passed INTEGER,
|
|
418
|
+
spec_success_rate_percent REAL,
|
|
419
|
+
risk_level TEXT,
|
|
420
|
+
ontology_quality_score REAL,
|
|
421
|
+
capability_coverage_percent REAL,
|
|
422
|
+
capability_coverage_passed INTEGER,
|
|
423
|
+
scene_package_batch_passed INTEGER,
|
|
424
|
+
scene_package_batch_failure_count INTEGER,
|
|
425
|
+
failed_goals INTEGER,
|
|
426
|
+
release_gate_preflight_available INTEGER,
|
|
427
|
+
release_gate_preflight_blocked INTEGER,
|
|
428
|
+
source_updated_at TEXT,
|
|
429
|
+
source TEXT,
|
|
430
|
+
indexed_at TEXT NOT NULL
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
CREATE INDEX IF NOT EXISTS idx_release_evidence_run_registry_status_merged
|
|
434
|
+
ON release_evidence_run_registry(status, merged_at DESC);
|
|
435
|
+
|
|
436
|
+
CREATE TABLE IF NOT EXISTS release_gate_history_registry (
|
|
437
|
+
tag TEXT PRIMARY KEY,
|
|
438
|
+
evaluated_at TEXT,
|
|
439
|
+
gate_passed INTEGER,
|
|
440
|
+
enforce INTEGER,
|
|
441
|
+
risk_level TEXT,
|
|
442
|
+
spec_success_rate_percent REAL,
|
|
443
|
+
scene_package_batch_passed INTEGER,
|
|
444
|
+
scene_package_batch_failure_count INTEGER,
|
|
445
|
+
capability_expected_unknown_count INTEGER,
|
|
446
|
+
capability_provided_unknown_count INTEGER,
|
|
447
|
+
release_gate_preflight_available INTEGER,
|
|
448
|
+
release_gate_preflight_blocked INTEGER,
|
|
449
|
+
require_release_gate_preflight INTEGER,
|
|
450
|
+
drift_alert_count INTEGER,
|
|
451
|
+
drift_blocked INTEGER,
|
|
452
|
+
weekly_ops_blocked INTEGER,
|
|
453
|
+
source_updated_at TEXT,
|
|
454
|
+
source TEXT,
|
|
455
|
+
indexed_at TEXT NOT NULL
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
CREATE INDEX IF NOT EXISTS idx_release_gate_history_registry_eval
|
|
459
|
+
ON release_gate_history_registry(evaluated_at DESC);
|
|
410
460
|
`);
|
|
411
461
|
}
|
|
412
462
|
|
|
@@ -678,6 +728,66 @@ class SceStateStore {
|
|
|
678
728
|
};
|
|
679
729
|
}
|
|
680
730
|
|
|
731
|
+
_mapReleaseEvidenceRunRow(row) {
|
|
732
|
+
if (!row) {
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
return {
|
|
736
|
+
session_id: normalizeString(row.session_id),
|
|
737
|
+
merged_at: normalizeIsoTimestamp(row.merged_at, '') || null,
|
|
738
|
+
status: normalizeString(row.status) || null,
|
|
739
|
+
gate_passed: normalizeBooleanValue(row.gate_passed, false),
|
|
740
|
+
spec_success_rate_percent: Number.isFinite(Number(row.spec_success_rate_percent))
|
|
741
|
+
? Number(row.spec_success_rate_percent)
|
|
742
|
+
: null,
|
|
743
|
+
risk_level: normalizeString(row.risk_level) || null,
|
|
744
|
+
ontology_quality_score: Number.isFinite(Number(row.ontology_quality_score))
|
|
745
|
+
? Number(row.ontology_quality_score)
|
|
746
|
+
: null,
|
|
747
|
+
capability_coverage_percent: Number.isFinite(Number(row.capability_coverage_percent))
|
|
748
|
+
? Number(row.capability_coverage_percent)
|
|
749
|
+
: null,
|
|
750
|
+
capability_coverage_passed: normalizeBooleanValue(row.capability_coverage_passed, false),
|
|
751
|
+
scene_package_batch_passed: normalizeBooleanValue(row.scene_package_batch_passed, false),
|
|
752
|
+
scene_package_batch_failure_count: normalizeNonNegativeInteger(row.scene_package_batch_failure_count, 0),
|
|
753
|
+
failed_goals: normalizeNonNegativeInteger(row.failed_goals, 0),
|
|
754
|
+
release_gate_preflight_available: normalizeBooleanValue(row.release_gate_preflight_available, false),
|
|
755
|
+
release_gate_preflight_blocked: normalizeBooleanValue(row.release_gate_preflight_blocked, false),
|
|
756
|
+
source_updated_at: normalizeIsoTimestamp(row.source_updated_at, '') || null,
|
|
757
|
+
source: normalizeString(row.source) || null,
|
|
758
|
+
indexed_at: normalizeIsoTimestamp(row.indexed_at, '') || null
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
_mapReleaseGateHistoryRow(row) {
|
|
763
|
+
if (!row) {
|
|
764
|
+
return null;
|
|
765
|
+
}
|
|
766
|
+
return {
|
|
767
|
+
tag: normalizeString(row.tag),
|
|
768
|
+
evaluated_at: normalizeIsoTimestamp(row.evaluated_at, '') || null,
|
|
769
|
+
gate_passed: normalizeBooleanValue(row.gate_passed, false),
|
|
770
|
+
enforce: normalizeBooleanValue(row.enforce, false),
|
|
771
|
+
risk_level: normalizeString(row.risk_level) || null,
|
|
772
|
+
spec_success_rate_percent: Number.isFinite(Number(row.spec_success_rate_percent))
|
|
773
|
+
? Number(row.spec_success_rate_percent)
|
|
774
|
+
: null,
|
|
775
|
+
scene_package_batch_passed: normalizeBooleanValue(row.scene_package_batch_passed, false),
|
|
776
|
+
scene_package_batch_failure_count: normalizeNonNegativeInteger(row.scene_package_batch_failure_count, 0),
|
|
777
|
+
capability_expected_unknown_count: normalizeNonNegativeInteger(row.capability_expected_unknown_count, 0),
|
|
778
|
+
capability_provided_unknown_count: normalizeNonNegativeInteger(row.capability_provided_unknown_count, 0),
|
|
779
|
+
release_gate_preflight_available: normalizeBooleanValue(row.release_gate_preflight_available, false),
|
|
780
|
+
release_gate_preflight_blocked: normalizeBooleanValue(row.release_gate_preflight_blocked, false),
|
|
781
|
+
require_release_gate_preflight: normalizeBooleanValue(row.require_release_gate_preflight, false),
|
|
782
|
+
drift_alert_count: normalizeNonNegativeInteger(row.drift_alert_count, 0),
|
|
783
|
+
drift_blocked: normalizeBooleanValue(row.drift_blocked, false),
|
|
784
|
+
weekly_ops_blocked: normalizeBooleanValue(row.weekly_ops_blocked, false),
|
|
785
|
+
source_updated_at: normalizeIsoTimestamp(row.source_updated_at, '') || null,
|
|
786
|
+
source: normalizeString(row.source) || null,
|
|
787
|
+
indexed_at: normalizeIsoTimestamp(row.indexed_at, '') || null
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
|
|
681
791
|
async resolveOrCreateTaskRef(options = {}) {
|
|
682
792
|
const sceneId = normalizeString(options.sceneId);
|
|
683
793
|
const specId = normalizeString(options.specId);
|
|
@@ -2165,6 +2275,322 @@ class SceStateStore {
|
|
|
2165
2275
|
.filter(Boolean);
|
|
2166
2276
|
}
|
|
2167
2277
|
|
|
2278
|
+
async upsertReleaseEvidenceRunRecords(records = [], options = {}) {
|
|
2279
|
+
const source = normalizeString(options.source) || 'file.release-evidence.handoff-runs';
|
|
2280
|
+
const nowIso = this.now();
|
|
2281
|
+
const normalizedRecords = Array.isArray(records)
|
|
2282
|
+
? records.map((item) => ({
|
|
2283
|
+
session_id: normalizeString(item && item.session_id),
|
|
2284
|
+
merged_at: normalizeIsoTimestamp(item && item.merged_at, '') || null,
|
|
2285
|
+
status: normalizeString(item && item.status) || null,
|
|
2286
|
+
gate_passed: normalizeBooleanValue(item && item.gate_passed, false),
|
|
2287
|
+
spec_success_rate_percent: Number.isFinite(Number(item && item.spec_success_rate_percent))
|
|
2288
|
+
? Number(item.spec_success_rate_percent)
|
|
2289
|
+
: null,
|
|
2290
|
+
risk_level: normalizeString(item && item.risk_level) || null,
|
|
2291
|
+
ontology_quality_score: Number.isFinite(Number(item && item.ontology_quality_score))
|
|
2292
|
+
? Number(item.ontology_quality_score)
|
|
2293
|
+
: null,
|
|
2294
|
+
capability_coverage_percent: Number.isFinite(Number(item && item.capability_coverage_percent))
|
|
2295
|
+
? Number(item.capability_coverage_percent)
|
|
2296
|
+
: null,
|
|
2297
|
+
capability_coverage_passed: normalizeBooleanValue(item && item.capability_coverage_passed, false),
|
|
2298
|
+
scene_package_batch_passed: normalizeBooleanValue(item && item.scene_package_batch_passed, false),
|
|
2299
|
+
scene_package_batch_failure_count: normalizeNonNegativeInteger(item && item.scene_package_batch_failure_count, 0),
|
|
2300
|
+
failed_goals: normalizeNonNegativeInteger(item && item.failed_goals, 0),
|
|
2301
|
+
release_gate_preflight_available: normalizeBooleanValue(item && item.release_gate_preflight_available, false),
|
|
2302
|
+
release_gate_preflight_blocked: normalizeBooleanValue(item && item.release_gate_preflight_blocked, false),
|
|
2303
|
+
source_updated_at: normalizeIsoTimestamp(item && item.source_updated_at, '') || null,
|
|
2304
|
+
source: normalizeString(item && item.source) || source,
|
|
2305
|
+
indexed_at: nowIso
|
|
2306
|
+
}))
|
|
2307
|
+
.filter((item) => item.session_id)
|
|
2308
|
+
: [];
|
|
2309
|
+
|
|
2310
|
+
if (this._useMemoryBackend()) {
|
|
2311
|
+
for (const item of normalizedRecords) {
|
|
2312
|
+
this._memory.release_evidence_run[item.session_id] = { ...item };
|
|
2313
|
+
}
|
|
2314
|
+
return {
|
|
2315
|
+
success: true,
|
|
2316
|
+
written: normalizedRecords.length,
|
|
2317
|
+
total: Object.keys(this._memory.release_evidence_run || {}).length
|
|
2318
|
+
};
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
if (!await this.ensureReady()) {
|
|
2322
|
+
return null;
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
const statement = this._db.prepare(`
|
|
2326
|
+
INSERT OR REPLACE INTO release_evidence_run_registry(
|
|
2327
|
+
session_id, merged_at, status, gate_passed, spec_success_rate_percent, risk_level,
|
|
2328
|
+
ontology_quality_score, capability_coverage_percent, capability_coverage_passed,
|
|
2329
|
+
scene_package_batch_passed, scene_package_batch_failure_count, failed_goals,
|
|
2330
|
+
release_gate_preflight_available, release_gate_preflight_blocked,
|
|
2331
|
+
source_updated_at, source, indexed_at
|
|
2332
|
+
)
|
|
2333
|
+
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2334
|
+
`);
|
|
2335
|
+
|
|
2336
|
+
this._withTransaction(() => {
|
|
2337
|
+
for (const item of normalizedRecords) {
|
|
2338
|
+
statement.run(
|
|
2339
|
+
item.session_id,
|
|
2340
|
+
item.merged_at,
|
|
2341
|
+
item.status,
|
|
2342
|
+
item.gate_passed ? 1 : 0,
|
|
2343
|
+
item.spec_success_rate_percent,
|
|
2344
|
+
item.risk_level,
|
|
2345
|
+
item.ontology_quality_score,
|
|
2346
|
+
item.capability_coverage_percent,
|
|
2347
|
+
item.capability_coverage_passed ? 1 : 0,
|
|
2348
|
+
item.scene_package_batch_passed ? 1 : 0,
|
|
2349
|
+
item.scene_package_batch_failure_count,
|
|
2350
|
+
item.failed_goals,
|
|
2351
|
+
item.release_gate_preflight_available ? 1 : 0,
|
|
2352
|
+
item.release_gate_preflight_blocked ? 1 : 0,
|
|
2353
|
+
item.source_updated_at,
|
|
2354
|
+
item.source,
|
|
2355
|
+
item.indexed_at
|
|
2356
|
+
);
|
|
2357
|
+
}
|
|
2358
|
+
});
|
|
2359
|
+
|
|
2360
|
+
const totalRow = this._db
|
|
2361
|
+
.prepare('SELECT COUNT(*) AS total FROM release_evidence_run_registry')
|
|
2362
|
+
.get();
|
|
2363
|
+
|
|
2364
|
+
return {
|
|
2365
|
+
success: true,
|
|
2366
|
+
written: normalizedRecords.length,
|
|
2367
|
+
total: normalizeNonNegativeInteger(totalRow && totalRow.total, 0)
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2371
|
+
async listReleaseEvidenceRunRecords(options = {}) {
|
|
2372
|
+
const limit = normalizeInteger(options.limit, 100);
|
|
2373
|
+
const status = normalizeString(options.status);
|
|
2374
|
+
const riskLevel = normalizeString(options.riskLevel || options.risk_level);
|
|
2375
|
+
|
|
2376
|
+
if (this._useMemoryBackend()) {
|
|
2377
|
+
let rows = Object.values(this._memory.release_evidence_run || {}).map((item) => ({ ...item }));
|
|
2378
|
+
if (status) {
|
|
2379
|
+
rows = rows.filter((item) => normalizeString(item.status) === status);
|
|
2380
|
+
}
|
|
2381
|
+
if (riskLevel) {
|
|
2382
|
+
rows = rows.filter((item) => normalizeString(item.risk_level) === riskLevel);
|
|
2383
|
+
}
|
|
2384
|
+
rows.sort((left, right) => {
|
|
2385
|
+
const leftTs = Date.parse(left.merged_at || '') || 0;
|
|
2386
|
+
const rightTs = Date.parse(right.merged_at || '') || 0;
|
|
2387
|
+
if (rightTs !== leftTs) {
|
|
2388
|
+
return rightTs - leftTs;
|
|
2389
|
+
}
|
|
2390
|
+
return `${right.session_id}`.localeCompare(`${left.session_id}`);
|
|
2391
|
+
});
|
|
2392
|
+
if (limit > 0) {
|
|
2393
|
+
rows = rows.slice(0, limit);
|
|
2394
|
+
}
|
|
2395
|
+
return rows.map((row) => this._mapReleaseEvidenceRunRow(row));
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
if (!await this.ensureReady()) {
|
|
2399
|
+
return null;
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
let query = `
|
|
2403
|
+
SELECT session_id, merged_at, status, gate_passed, spec_success_rate_percent, risk_level,
|
|
2404
|
+
ontology_quality_score, capability_coverage_percent, capability_coverage_passed,
|
|
2405
|
+
scene_package_batch_passed, scene_package_batch_failure_count, failed_goals,
|
|
2406
|
+
release_gate_preflight_available, release_gate_preflight_blocked, source_updated_at,
|
|
2407
|
+
source, indexed_at
|
|
2408
|
+
FROM release_evidence_run_registry
|
|
2409
|
+
`;
|
|
2410
|
+
const clauses = [];
|
|
2411
|
+
const params = [];
|
|
2412
|
+
if (status) {
|
|
2413
|
+
clauses.push('status = ?');
|
|
2414
|
+
params.push(status);
|
|
2415
|
+
}
|
|
2416
|
+
if (riskLevel) {
|
|
2417
|
+
clauses.push('risk_level = ?');
|
|
2418
|
+
params.push(riskLevel);
|
|
2419
|
+
}
|
|
2420
|
+
if (clauses.length > 0) {
|
|
2421
|
+
query += ` WHERE ${clauses.join(' AND ')}`;
|
|
2422
|
+
}
|
|
2423
|
+
query += ' ORDER BY merged_at DESC, session_id DESC';
|
|
2424
|
+
if (limit > 0) {
|
|
2425
|
+
query += ' LIMIT ?';
|
|
2426
|
+
params.push(limit);
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
const rows = this._db.prepare(query).all(...params);
|
|
2430
|
+
return rows
|
|
2431
|
+
.map((row) => this._mapReleaseEvidenceRunRow(row))
|
|
2432
|
+
.filter(Boolean);
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
async upsertReleaseGateHistoryRecords(records = [], options = {}) {
|
|
2436
|
+
const source = normalizeString(options.source) || 'file.release-evidence.gate-history';
|
|
2437
|
+
const nowIso = this.now();
|
|
2438
|
+
const normalizedRecords = Array.isArray(records)
|
|
2439
|
+
? records.map((item) => ({
|
|
2440
|
+
tag: normalizeString(item && item.tag),
|
|
2441
|
+
evaluated_at: normalizeIsoTimestamp(item && item.evaluated_at, '') || null,
|
|
2442
|
+
gate_passed: normalizeBooleanValue(item && item.gate_passed, false),
|
|
2443
|
+
enforce: normalizeBooleanValue(item && item.enforce, false),
|
|
2444
|
+
risk_level: normalizeString(item && item.risk_level) || null,
|
|
2445
|
+
spec_success_rate_percent: Number.isFinite(Number(item && item.spec_success_rate_percent))
|
|
2446
|
+
? Number(item.spec_success_rate_percent)
|
|
2447
|
+
: null,
|
|
2448
|
+
scene_package_batch_passed: normalizeBooleanValue(item && item.scene_package_batch_passed, false),
|
|
2449
|
+
scene_package_batch_failure_count: normalizeNonNegativeInteger(item && item.scene_package_batch_failure_count, 0),
|
|
2450
|
+
capability_expected_unknown_count: normalizeNonNegativeInteger(item && item.capability_expected_unknown_count, 0),
|
|
2451
|
+
capability_provided_unknown_count: normalizeNonNegativeInteger(item && item.capability_provided_unknown_count, 0),
|
|
2452
|
+
release_gate_preflight_available: normalizeBooleanValue(item && item.release_gate_preflight_available, false),
|
|
2453
|
+
release_gate_preflight_blocked: normalizeBooleanValue(item && item.release_gate_preflight_blocked, false),
|
|
2454
|
+
require_release_gate_preflight: normalizeBooleanValue(item && item.require_release_gate_preflight, false),
|
|
2455
|
+
drift_alert_count: normalizeNonNegativeInteger(item && item.drift_alert_count, 0),
|
|
2456
|
+
drift_blocked: normalizeBooleanValue(item && item.drift_blocked, false),
|
|
2457
|
+
weekly_ops_blocked: normalizeBooleanValue(item && item.weekly_ops_blocked, false),
|
|
2458
|
+
source_updated_at: normalizeIsoTimestamp(item && item.source_updated_at, '') || null,
|
|
2459
|
+
source: normalizeString(item && item.source) || source,
|
|
2460
|
+
indexed_at: nowIso
|
|
2461
|
+
}))
|
|
2462
|
+
.filter((item) => item.tag)
|
|
2463
|
+
: [];
|
|
2464
|
+
|
|
2465
|
+
if (this._useMemoryBackend()) {
|
|
2466
|
+
for (const item of normalizedRecords) {
|
|
2467
|
+
this._memory.release_gate_history[item.tag] = { ...item };
|
|
2468
|
+
}
|
|
2469
|
+
return {
|
|
2470
|
+
success: true,
|
|
2471
|
+
written: normalizedRecords.length,
|
|
2472
|
+
total: Object.keys(this._memory.release_gate_history || {}).length
|
|
2473
|
+
};
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
if (!await this.ensureReady()) {
|
|
2477
|
+
return null;
|
|
2478
|
+
}
|
|
2479
|
+
|
|
2480
|
+
const statement = this._db.prepare(`
|
|
2481
|
+
INSERT OR REPLACE INTO release_gate_history_registry(
|
|
2482
|
+
tag, evaluated_at, gate_passed, enforce, risk_level, spec_success_rate_percent,
|
|
2483
|
+
scene_package_batch_passed, scene_package_batch_failure_count,
|
|
2484
|
+
capability_expected_unknown_count, capability_provided_unknown_count,
|
|
2485
|
+
release_gate_preflight_available, release_gate_preflight_blocked,
|
|
2486
|
+
require_release_gate_preflight, drift_alert_count, drift_blocked,
|
|
2487
|
+
weekly_ops_blocked, source_updated_at, source, indexed_at
|
|
2488
|
+
)
|
|
2489
|
+
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2490
|
+
`);
|
|
2491
|
+
|
|
2492
|
+
this._withTransaction(() => {
|
|
2493
|
+
for (const item of normalizedRecords) {
|
|
2494
|
+
statement.run(
|
|
2495
|
+
item.tag,
|
|
2496
|
+
item.evaluated_at,
|
|
2497
|
+
item.gate_passed ? 1 : 0,
|
|
2498
|
+
item.enforce ? 1 : 0,
|
|
2499
|
+
item.risk_level,
|
|
2500
|
+
item.spec_success_rate_percent,
|
|
2501
|
+
item.scene_package_batch_passed ? 1 : 0,
|
|
2502
|
+
item.scene_package_batch_failure_count,
|
|
2503
|
+
item.capability_expected_unknown_count,
|
|
2504
|
+
item.capability_provided_unknown_count,
|
|
2505
|
+
item.release_gate_preflight_available ? 1 : 0,
|
|
2506
|
+
item.release_gate_preflight_blocked ? 1 : 0,
|
|
2507
|
+
item.require_release_gate_preflight ? 1 : 0,
|
|
2508
|
+
item.drift_alert_count,
|
|
2509
|
+
item.drift_blocked ? 1 : 0,
|
|
2510
|
+
item.weekly_ops_blocked ? 1 : 0,
|
|
2511
|
+
item.source_updated_at,
|
|
2512
|
+
item.source,
|
|
2513
|
+
item.indexed_at
|
|
2514
|
+
);
|
|
2515
|
+
}
|
|
2516
|
+
});
|
|
2517
|
+
|
|
2518
|
+
const totalRow = this._db
|
|
2519
|
+
.prepare('SELECT COUNT(*) AS total FROM release_gate_history_registry')
|
|
2520
|
+
.get();
|
|
2521
|
+
|
|
2522
|
+
return {
|
|
2523
|
+
success: true,
|
|
2524
|
+
written: normalizedRecords.length,
|
|
2525
|
+
total: normalizeNonNegativeInteger(totalRow && totalRow.total, 0)
|
|
2526
|
+
};
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
async listReleaseGateHistoryRecords(options = {}) {
|
|
2530
|
+
const limit = normalizeInteger(options.limit, 100);
|
|
2531
|
+
const tag = normalizeString(options.tag);
|
|
2532
|
+
const riskLevel = normalizeString(options.riskLevel || options.risk_level);
|
|
2533
|
+
|
|
2534
|
+
if (this._useMemoryBackend()) {
|
|
2535
|
+
let rows = Object.values(this._memory.release_gate_history || {}).map((item) => ({ ...item }));
|
|
2536
|
+
if (tag) {
|
|
2537
|
+
rows = rows.filter((item) => normalizeString(item.tag) === tag);
|
|
2538
|
+
}
|
|
2539
|
+
if (riskLevel) {
|
|
2540
|
+
rows = rows.filter((item) => normalizeString(item.risk_level) === riskLevel);
|
|
2541
|
+
}
|
|
2542
|
+
rows.sort((left, right) => {
|
|
2543
|
+
const leftTs = Date.parse(left.evaluated_at || '') || 0;
|
|
2544
|
+
const rightTs = Date.parse(right.evaluated_at || '') || 0;
|
|
2545
|
+
if (rightTs !== leftTs) {
|
|
2546
|
+
return rightTs - leftTs;
|
|
2547
|
+
}
|
|
2548
|
+
return `${right.tag}`.localeCompare(`${left.tag}`);
|
|
2549
|
+
});
|
|
2550
|
+
if (limit > 0) {
|
|
2551
|
+
rows = rows.slice(0, limit);
|
|
2552
|
+
}
|
|
2553
|
+
return rows.map((row) => this._mapReleaseGateHistoryRow(row));
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
if (!await this.ensureReady()) {
|
|
2557
|
+
return null;
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
let query = `
|
|
2561
|
+
SELECT tag, evaluated_at, gate_passed, enforce, risk_level, spec_success_rate_percent,
|
|
2562
|
+
scene_package_batch_passed, scene_package_batch_failure_count,
|
|
2563
|
+
capability_expected_unknown_count, capability_provided_unknown_count,
|
|
2564
|
+
release_gate_preflight_available, release_gate_preflight_blocked,
|
|
2565
|
+
require_release_gate_preflight, drift_alert_count, drift_blocked,
|
|
2566
|
+
weekly_ops_blocked, source_updated_at, source, indexed_at
|
|
2567
|
+
FROM release_gate_history_registry
|
|
2568
|
+
`;
|
|
2569
|
+
const clauses = [];
|
|
2570
|
+
const params = [];
|
|
2571
|
+
if (tag) {
|
|
2572
|
+
clauses.push('tag = ?');
|
|
2573
|
+
params.push(tag);
|
|
2574
|
+
}
|
|
2575
|
+
if (riskLevel) {
|
|
2576
|
+
clauses.push('risk_level = ?');
|
|
2577
|
+
params.push(riskLevel);
|
|
2578
|
+
}
|
|
2579
|
+
if (clauses.length > 0) {
|
|
2580
|
+
query += ` WHERE ${clauses.join(' AND ')}`;
|
|
2581
|
+
}
|
|
2582
|
+
query += ' ORDER BY evaluated_at DESC, tag DESC';
|
|
2583
|
+
if (limit > 0) {
|
|
2584
|
+
query += ' LIMIT ?';
|
|
2585
|
+
params.push(limit);
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
const rows = this._db.prepare(query).all(...params);
|
|
2589
|
+
return rows
|
|
2590
|
+
.map((row) => this._mapReleaseGateHistoryRow(row))
|
|
2591
|
+
.filter(Boolean);
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2168
2594
|
_resolveOrCreateTaskRefInMemory(options = {}) {
|
|
2169
2595
|
const sceneId = normalizeString(options.sceneId);
|
|
2170
2596
|
const specId = normalizeString(options.specId);
|
|
@@ -11,6 +11,8 @@ const COMPONENT_ERRORBOOK_ENTRY_INDEX = 'errorbook.entry-index';
|
|
|
11
11
|
const COMPONENT_ERRORBOOK_INCIDENT_INDEX = 'errorbook.incident-index';
|
|
12
12
|
const COMPONENT_SPEC_SCENE_OVERRIDES = 'governance.spec-scene-overrides';
|
|
13
13
|
const COMPONENT_SPEC_SCENE_INDEX = 'governance.scene-index';
|
|
14
|
+
const COMPONENT_RELEASE_EVIDENCE_RUNS = 'release.evidence-runs-index';
|
|
15
|
+
const COMPONENT_RELEASE_GATE_HISTORY = 'release.gate-history-index';
|
|
14
16
|
const DEFAULT_STATE_EXPORT_PATH = '.sce/reports/state-migration/state-export.latest.json';
|
|
15
17
|
|
|
16
18
|
const COMPONENT_DEFINITIONS = Object.freeze([
|
|
@@ -41,6 +43,14 @@ const COMPONENT_DEFINITIONS = Object.freeze([
|
|
|
41
43
|
{
|
|
42
44
|
id: COMPONENT_SPEC_SCENE_INDEX,
|
|
43
45
|
source_path: '.sce/spec-governance/scene-index.json'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: COMPONENT_RELEASE_EVIDENCE_RUNS,
|
|
49
|
+
source_path: '.sce/reports/release-evidence/handoff-runs.json'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: COMPONENT_RELEASE_GATE_HISTORY,
|
|
53
|
+
source_path: '.sce/reports/release-evidence/release-gate-history.json'
|
|
44
54
|
}
|
|
45
55
|
]);
|
|
46
56
|
|
|
@@ -280,6 +290,106 @@ function mapSpecSceneIndexPayload(payload = {}) {
|
|
|
280
290
|
.filter((item) => item.scene_id);
|
|
281
291
|
}
|
|
282
292
|
|
|
293
|
+
function mapReleaseEvidenceRunsPayload(payload = {}) {
|
|
294
|
+
if (!payload || typeof payload !== 'object' || !Array.isArray(payload.sessions)) {
|
|
295
|
+
return [];
|
|
296
|
+
}
|
|
297
|
+
const sourceUpdatedAt = normalizeString(payload.updated_at) || normalizeString(payload.generated_at);
|
|
298
|
+
return payload.sessions
|
|
299
|
+
.map((session) => {
|
|
300
|
+
const gate = session && session.gate && typeof session.gate === 'object' ? session.gate : {};
|
|
301
|
+
const gateActual = gate && gate.actual && typeof gate.actual === 'object' ? gate.actual : {};
|
|
302
|
+
const coverage = session && session.capability_coverage && typeof session.capability_coverage === 'object'
|
|
303
|
+
? session.capability_coverage
|
|
304
|
+
: {};
|
|
305
|
+
const coverageSummary = coverage && coverage.summary && typeof coverage.summary === 'object'
|
|
306
|
+
? coverage.summary
|
|
307
|
+
: {};
|
|
308
|
+
const scenePackageBatch = session && session.scene_package_batch && typeof session.scene_package_batch === 'object'
|
|
309
|
+
? session.scene_package_batch
|
|
310
|
+
: {};
|
|
311
|
+
const scenePackageBatchSummary = scenePackageBatch && scenePackageBatch.summary && typeof scenePackageBatch.summary === 'object'
|
|
312
|
+
? scenePackageBatch.summary
|
|
313
|
+
: {};
|
|
314
|
+
const batchSummary = session && session.batch_summary && typeof session.batch_summary === 'object'
|
|
315
|
+
? session.batch_summary
|
|
316
|
+
: {};
|
|
317
|
+
const preflight = session && session.release_gate_preflight && typeof session.release_gate_preflight === 'object'
|
|
318
|
+
? session.release_gate_preflight
|
|
319
|
+
: {};
|
|
320
|
+
return {
|
|
321
|
+
session_id: normalizeString(session && session.session_id),
|
|
322
|
+
merged_at: normalizeString(session && session.merged_at) || normalizeString(session && session.generated_at),
|
|
323
|
+
status: normalizeString(session && session.status),
|
|
324
|
+
gate_passed: gate && gate.passed === true,
|
|
325
|
+
spec_success_rate_percent: Number.isFinite(Number(gateActual.spec_success_rate_percent))
|
|
326
|
+
? Number(gateActual.spec_success_rate_percent)
|
|
327
|
+
: null,
|
|
328
|
+
risk_level: normalizeString(gateActual.risk_level),
|
|
329
|
+
ontology_quality_score: Number.isFinite(Number(gateActual.ontology_quality_score))
|
|
330
|
+
? Number(gateActual.ontology_quality_score)
|
|
331
|
+
: null,
|
|
332
|
+
capability_coverage_percent: Number.isFinite(Number(coverageSummary.coverage_percent))
|
|
333
|
+
? Number(coverageSummary.coverage_percent)
|
|
334
|
+
: null,
|
|
335
|
+
capability_coverage_passed: coverageSummary.passed === true,
|
|
336
|
+
scene_package_batch_passed: scenePackageBatchSummary.batch_gate_passed === true,
|
|
337
|
+
scene_package_batch_failure_count: Number.isFinite(Number(scenePackageBatchSummary.batch_gate_failure_count))
|
|
338
|
+
? Number.parseInt(`${scenePackageBatchSummary.batch_gate_failure_count}`, 10)
|
|
339
|
+
: (
|
|
340
|
+
Number.isFinite(Number(scenePackageBatchSummary.failed))
|
|
341
|
+
? Number.parseInt(`${scenePackageBatchSummary.failed}`, 10)
|
|
342
|
+
: 0
|
|
343
|
+
),
|
|
344
|
+
failed_goals: Number.isFinite(Number(batchSummary.failed_goals))
|
|
345
|
+
? Number.parseInt(`${batchSummary.failed_goals}`, 10)
|
|
346
|
+
: 0,
|
|
347
|
+
release_gate_preflight_available: preflight && preflight.available === true,
|
|
348
|
+
release_gate_preflight_blocked: preflight && preflight.blocked === true,
|
|
349
|
+
source_updated_at: sourceUpdatedAt
|
|
350
|
+
};
|
|
351
|
+
})
|
|
352
|
+
.filter((item) => item.session_id);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function mapReleaseGateHistoryPayload(payload = {}) {
|
|
356
|
+
if (!payload || typeof payload !== 'object' || !Array.isArray(payload.entries)) {
|
|
357
|
+
return [];
|
|
358
|
+
}
|
|
359
|
+
const sourceUpdatedAt = normalizeString(payload.updated_at) || normalizeString(payload.generated_at);
|
|
360
|
+
return payload.entries
|
|
361
|
+
.map((entry) => ({
|
|
362
|
+
tag: normalizeString(entry && entry.tag),
|
|
363
|
+
evaluated_at: normalizeString(entry && entry.evaluated_at),
|
|
364
|
+
gate_passed: entry && entry.gate_passed === true,
|
|
365
|
+
enforce: entry && entry.enforce === true,
|
|
366
|
+
risk_level: normalizeString(entry && entry.risk_level),
|
|
367
|
+
spec_success_rate_percent: Number.isFinite(Number(entry && entry.spec_success_rate_percent))
|
|
368
|
+
? Number(entry.spec_success_rate_percent)
|
|
369
|
+
: null,
|
|
370
|
+
scene_package_batch_passed: entry && entry.scene_package_batch_passed === true,
|
|
371
|
+
scene_package_batch_failure_count: Number.isFinite(Number(entry && entry.scene_package_batch_failure_count))
|
|
372
|
+
? Number.parseInt(`${entry.scene_package_batch_failure_count}`, 10)
|
|
373
|
+
: 0,
|
|
374
|
+
capability_expected_unknown_count: Number.isFinite(Number(entry && entry.capability_expected_unknown_count))
|
|
375
|
+
? Number.parseInt(`${entry.capability_expected_unknown_count}`, 10)
|
|
376
|
+
: 0,
|
|
377
|
+
capability_provided_unknown_count: Number.isFinite(Number(entry && entry.capability_provided_unknown_count))
|
|
378
|
+
? Number.parseInt(`${entry.capability_provided_unknown_count}`, 10)
|
|
379
|
+
: 0,
|
|
380
|
+
release_gate_preflight_available: entry && entry.release_gate_preflight_available === true,
|
|
381
|
+
release_gate_preflight_blocked: entry && entry.release_gate_preflight_blocked === true,
|
|
382
|
+
require_release_gate_preflight: entry && entry.require_release_gate_preflight === true,
|
|
383
|
+
drift_alert_count: Number.isFinite(Number(entry && entry.drift_alert_count))
|
|
384
|
+
? Number.parseInt(`${entry.drift_alert_count}`, 10)
|
|
385
|
+
: 0,
|
|
386
|
+
drift_blocked: entry && entry.drift_blocked === true,
|
|
387
|
+
weekly_ops_blocked: entry && entry.weekly_ops_blocked === true,
|
|
388
|
+
source_updated_at: sourceUpdatedAt
|
|
389
|
+
}))
|
|
390
|
+
.filter((item) => item.tag);
|
|
391
|
+
}
|
|
392
|
+
|
|
283
393
|
async function readJsonSource(absolutePath, fileSystem = fs) {
|
|
284
394
|
if (!await fileSystem.pathExists(absolutePath)) {
|
|
285
395
|
return {
|
|
@@ -325,6 +435,10 @@ async function readComponentSnapshot(component = {}, projectPath = process.cwd()
|
|
|
325
435
|
records = mapSpecSceneOverridesPayload(source.payload);
|
|
326
436
|
} else if (component.id === COMPONENT_SPEC_SCENE_INDEX) {
|
|
327
437
|
records = mapSpecSceneIndexPayload(source.payload);
|
|
438
|
+
} else if (component.id === COMPONENT_RELEASE_EVIDENCE_RUNS) {
|
|
439
|
+
records = mapReleaseEvidenceRunsPayload(source.payload);
|
|
440
|
+
} else if (component.id === COMPONENT_RELEASE_GATE_HISTORY) {
|
|
441
|
+
records = mapReleaseGateHistoryPayload(source.payload);
|
|
328
442
|
}
|
|
329
443
|
}
|
|
330
444
|
|
|
@@ -434,6 +548,16 @@ async function writeComponentToStateStore(componentSnapshot = {}, stateStore, co
|
|
|
434
548
|
source: componentId
|
|
435
549
|
});
|
|
436
550
|
}
|
|
551
|
+
if (componentId === COMPONENT_RELEASE_EVIDENCE_RUNS) {
|
|
552
|
+
return stateStore.upsertReleaseEvidenceRunRecords(componentSnapshot.records, {
|
|
553
|
+
source: componentId
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
if (componentId === COMPONENT_RELEASE_GATE_HISTORY) {
|
|
557
|
+
return stateStore.upsertReleaseGateHistoryRecords(componentSnapshot.records, {
|
|
558
|
+
source: componentId
|
|
559
|
+
});
|
|
560
|
+
}
|
|
437
561
|
return null;
|
|
438
562
|
}
|
|
439
563
|
|
|
@@ -561,6 +685,8 @@ async function runStateDoctor(options = {}, dependencies = {}) {
|
|
|
561
685
|
errorbookIncidentRows,
|
|
562
686
|
governanceOverrideRows,
|
|
563
687
|
governanceSceneRows,
|
|
688
|
+
releaseEvidenceRows,
|
|
689
|
+
releaseGateHistoryRows,
|
|
564
690
|
migrations
|
|
565
691
|
] = await Promise.all([
|
|
566
692
|
stateStore.listAgentRuntimeRecords({ limit: 0 }),
|
|
@@ -570,6 +696,8 @@ async function runStateDoctor(options = {}, dependencies = {}) {
|
|
|
570
696
|
stateStore.listErrorbookIncidentIndexRecords({ limit: 0 }),
|
|
571
697
|
stateStore.listGovernanceSpecSceneOverrideRecords({ limit: 0 }),
|
|
572
698
|
stateStore.listGovernanceSceneIndexRecords({ limit: 0 }),
|
|
699
|
+
stateStore.listReleaseEvidenceRunRecords({ limit: 0 }),
|
|
700
|
+
stateStore.listReleaseGateHistoryRecords({ limit: 0 }),
|
|
573
701
|
stateStore.listStateMigrations({ limit: 20 })
|
|
574
702
|
]);
|
|
575
703
|
|
|
@@ -580,7 +708,9 @@ async function runStateDoctor(options = {}, dependencies = {}) {
|
|
|
580
708
|
[COMPONENT_ERRORBOOK_ENTRY_INDEX, Array.isArray(errorbookEntryRows) ? errorbookEntryRows.length : 0],
|
|
581
709
|
[COMPONENT_ERRORBOOK_INCIDENT_INDEX, Array.isArray(errorbookIncidentRows) ? errorbookIncidentRows.length : 0],
|
|
582
710
|
[COMPONENT_SPEC_SCENE_OVERRIDES, Array.isArray(governanceOverrideRows) ? governanceOverrideRows.length : 0],
|
|
583
|
-
[COMPONENT_SPEC_SCENE_INDEX, Array.isArray(governanceSceneRows) ? governanceSceneRows.length : 0]
|
|
711
|
+
[COMPONENT_SPEC_SCENE_INDEX, Array.isArray(governanceSceneRows) ? governanceSceneRows.length : 0],
|
|
712
|
+
[COMPONENT_RELEASE_EVIDENCE_RUNS, Array.isArray(releaseEvidenceRows) ? releaseEvidenceRows.length : 0],
|
|
713
|
+
[COMPONENT_RELEASE_GATE_HISTORY, Array.isArray(releaseGateHistoryRows) ? releaseGateHistoryRows.length : 0]
|
|
584
714
|
]);
|
|
585
715
|
|
|
586
716
|
const checks = plan.components.map((component) => {
|
|
@@ -788,6 +918,8 @@ async function runStateExport(options = {}, dependencies = {}) {
|
|
|
788
918
|
errorbookIncidentRows,
|
|
789
919
|
governanceOverrideRows,
|
|
790
920
|
governanceSceneRows,
|
|
921
|
+
releaseEvidenceRows,
|
|
922
|
+
releaseGateHistoryRows,
|
|
791
923
|
migrations
|
|
792
924
|
] = await Promise.all([
|
|
793
925
|
stateStore.listAgentRuntimeRecords({ limit: 0 }),
|
|
@@ -797,6 +929,8 @@ async function runStateExport(options = {}, dependencies = {}) {
|
|
|
797
929
|
stateStore.listErrorbookIncidentIndexRecords({ limit: 0 }),
|
|
798
930
|
stateStore.listGovernanceSpecSceneOverrideRecords({ limit: 0 }),
|
|
799
931
|
stateStore.listGovernanceSceneIndexRecords({ limit: 0 }),
|
|
932
|
+
stateStore.listReleaseEvidenceRunRecords({ limit: 0 }),
|
|
933
|
+
stateStore.listReleaseGateHistoryRecords({ limit: 0 }),
|
|
800
934
|
stateStore.listStateMigrations({ limit: 0 })
|
|
801
935
|
]);
|
|
802
936
|
|
|
@@ -813,6 +947,8 @@ async function runStateExport(options = {}, dependencies = {}) {
|
|
|
813
947
|
errorbook_incident_index_registry: Array.isArray(errorbookIncidentRows) ? errorbookIncidentRows : [],
|
|
814
948
|
governance_spec_scene_override_registry: Array.isArray(governanceOverrideRows) ? governanceOverrideRows : [],
|
|
815
949
|
governance_scene_index_registry: Array.isArray(governanceSceneRows) ? governanceSceneRows : [],
|
|
950
|
+
release_evidence_run_registry: Array.isArray(releaseEvidenceRows) ? releaseEvidenceRows : [],
|
|
951
|
+
release_gate_history_registry: Array.isArray(releaseGateHistoryRows) ? releaseGateHistoryRows : [],
|
|
816
952
|
state_migration_registry: Array.isArray(migrations) ? migrations : []
|
|
817
953
|
},
|
|
818
954
|
summary: {
|
|
@@ -823,6 +959,8 @@ async function runStateExport(options = {}, dependencies = {}) {
|
|
|
823
959
|
errorbook_incident_index_registry: Array.isArray(errorbookIncidentRows) ? errorbookIncidentRows.length : 0,
|
|
824
960
|
governance_spec_scene_override_registry: Array.isArray(governanceOverrideRows) ? governanceOverrideRows.length : 0,
|
|
825
961
|
governance_scene_index_registry: Array.isArray(governanceSceneRows) ? governanceSceneRows.length : 0,
|
|
962
|
+
release_evidence_run_registry: Array.isArray(releaseEvidenceRows) ? releaseEvidenceRows.length : 0,
|
|
963
|
+
release_gate_history_registry: Array.isArray(releaseGateHistoryRows) ? releaseGateHistoryRows.length : 0,
|
|
826
964
|
state_migration_registry: Array.isArray(migrations) ? migrations.length : 0
|
|
827
965
|
},
|
|
828
966
|
out_file: path.relative(projectPath, outPath).replace(/\\/g, '/')
|
|
@@ -841,6 +979,8 @@ module.exports = {
|
|
|
841
979
|
COMPONENT_ERRORBOOK_INCIDENT_INDEX,
|
|
842
980
|
COMPONENT_SPEC_SCENE_OVERRIDES,
|
|
843
981
|
COMPONENT_SPEC_SCENE_INDEX,
|
|
982
|
+
COMPONENT_RELEASE_EVIDENCE_RUNS,
|
|
983
|
+
COMPONENT_RELEASE_GATE_HISTORY,
|
|
844
984
|
COMPONENT_DEFINITIONS,
|
|
845
985
|
DEFAULT_STATE_EXPORT_PATH,
|
|
846
986
|
buildStateMigrationPlan,
|
package/package.json
CHANGED