Skip to content

Commit aa39041

Browse files
committed
feat: persist readiness criteria matrix in runtime
1 parent 321a6eb commit aa39041

9 files changed

Lines changed: 77 additions & 3 deletions

docs/brainstorms/2026-04-19-mainline-progress-reconciliation-and-post-m7-direction-requirements.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ This document re-baselines current mainline truth on 2026-04-19, records what ch
237237
- agent-workspace diagnostics snapshots now persist full `mandatoryChecks`, `promotionBlockers`, and `recommendations`
238238
- toolbar summaries now expose recommendation counts alongside the existing gate/blocker ids
239239
- overall status still remains `in_progress` / `no-go`.
240+
- The next bounded execution slice after that makes runtime criterion-matrix parity explicit:
241+
- agent-workspace diagnostics snapshots now persist full `promotionCriteria`
242+
- toolbar summaries now expose compact criterion-matrix entry counts alongside the existing `criteria x/y` totals
243+
- overall status still remains `in_progress` / `no-go`.
240244
- Current expected outcome on `main` remains:
241245
- status `in_progress`
242246
- decision `no-go`

docs/diataxis/en/explanation/development-progress-dashboard.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,18 @@ Execution anchor:
354354
- decision stays `no-go`,
355355
- actionable-detail parity improves inspectability only; it does not relax the no-go contract.
356356

357+
## Latest Mainline Increment (2026-04-20 M8.18 Foundation Runtime Criterion-Matrix Parity)
358+
359+
- Closed the next operator-runtime parity gap for the full promotion-criteria matrix already present in the typed readiness payload:
360+
- `lastFoundationReadiness.promotionCriteria`
361+
- Runtime/operator visibility now keeps the same criterion-matrix detail used by downstream diagnostics:
362+
- toolbar summaries expose `criteria-detail 7` alongside the existing `criteria 5/7` aggregate,
363+
- diagnostics snapshots preserve every criterion entry with `criterionId`, `satisfied`, and `summary`.
364+
- Guardrail remains unchanged on `main`:
365+
- status stays `in_progress`,
366+
- decision stays `no-go`,
367+
- criterion-matrix parity improves inspectability only; it does not relax graph/vector independence requirements.
368+
357369
## Latest Mainline Increment (2026-04-20 M8.13 Foundation Readiness Provenance Evidence)
358370

359371
- Added machine-readable provenance so operator tooling can tell whether readiness is reading the runtime project root or falling back to real repo evidence:

docs/diataxis/en/explanation/foundation-reentry-readiness-checklist.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Bundle note:
5353
- diagnostics snapshot field `lastFoundationReadiness`
5454
- runbook link `foundation-reentry-readiness-checklist`
5555
- runtime snapshots now preserve both `promotionCriteriaSatisfiedIds` and `promotionCriteriaUnsatisfiedIds`
56+
- runtime snapshots now preserve full `promotionCriteria`
5657
- runtime snapshots now preserve `mandatoryCheckIds` for the active gate contract
5758
- runtime snapshots now preserve full `mandatoryChecks`, `promotionBlockers`, and `recommendations`
5859
- Current expected result on `main` is:
@@ -91,6 +92,7 @@ Bundle note:
9192
- `promotionCriteriaUnsatisfiedIds = [graph_backend_independent, vector_backend_independent]`
9293
- Current expected runtime/operator summary phrasing on `main` is:
9394
- `gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation`
95+
- `criteria-detail 7`
9496
- `recommendations 2`
9597
- `satisfied store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present`
9698
- `unmet graph_backend_independent, vector_backend_independent`

docs/diataxis/zh/explanation/development-progress-dashboard.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,18 @@
354354
- 决策仍为 `no-go`
355355
- 可执行细节对齐只提升可检查性,不会放松 no-go contract。
356356

357+
## 主线最新增量(2026-04-20 M8.18 Foundation 运行时条件矩阵对齐)
358+
359+
- 已补齐 typed readiness payload 中完整 promotion-criteria matrix 在运行时中的下一处对齐缺口:
360+
- `lastFoundationReadiness.promotionCriteria`
361+
- 运行时/执行侧现在会保留下游诊断需要的同一份 criterion matrix 细节:
362+
- 工具栏摘要会在现有 `criteria 5/7` 聚合之外显示 `criteria-detail 7`
363+
- diagnostics snapshot 会保留每条 criterion 的 `criterionId``satisfied``summary`
364+
- `main` 上的护栏结论保持不变:
365+
- 状态仍为 `in_progress`
366+
- 决策仍为 `no-go`
367+
- 条件矩阵对齐只提升可检查性,不会放宽 graph/vector independence 要求。
368+
357369
## 主线最新增量(2026-04-20 M8.13 Foundation Readiness 来源证据)
358370

359371
- 已新增 machine-readable provenance,执行侧现在可以直接知道 readiness 是读取 runtime project root,还是回退到真实 repo 证据:

docs/diataxis/zh/explanation/foundation-reentry-readiness-checklist.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
- diagnostics snapshot 字段 `lastFoundationReadiness`
5454
- runbook link `foundation-reentry-readiness-checklist`
5555
- runtime snapshot 现在会同时保留 `promotionCriteriaSatisfiedIds``promotionCriteriaUnsatisfiedIds`
56+
- runtime snapshot 现在会保留完整 `promotionCriteria`
5657
- runtime snapshot 现在也会保留当前 gate contract 的 `mandatoryCheckIds`
5758
- runtime snapshot 现在也会保留完整 `mandatoryChecks``promotionBlockers``recommendations`
5859
- 当前主线的预期结果是:
@@ -91,6 +92,7 @@
9192
- `promotionCriteriaUnsatisfiedIds = [graph_backend_independent, vector_backend_independent]`
9293
- 当前主线预期的运行时/执行侧摘要措辞为:
9394
- `gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation`
95+
- `criteria-detail 7`
9496
- `recommendations 2`
9597
- `satisfied store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present`
9698
- `unmet graph_backend_independent, vector_backend_independent`

src/agent_workspace.runtime.behavior.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,7 @@ describe('agent workspace runtime behavior', () => {
18091809
expect(messages.textContent || '').toContain(
18101810
'gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation'
18111811
);
1812+
expect(messages.textContent || '').toContain('criteria-detail 7');
18121813
expect(messages.textContent || '').toContain('recommendations 2');
18131814
expect(messages.textContent || '').toContain(
18141815
'satisfied store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present'
@@ -1880,6 +1881,43 @@ describe('agent workspace runtime behavior', () => {
18801881
'graph_backend_independent',
18811882
'vector_backend_independent',
18821883
],
1884+
promotionCriteria: [
1885+
{
1886+
criterionId: 'store_backend_evidence_present',
1887+
satisfied: true,
1888+
summary: 'Store backend evidence is present in the repository baseline.',
1889+
},
1890+
{
1891+
criterionId: 'graph_backend_independent',
1892+
satisfied: false,
1893+
summary: 'Graph backend still resolves to file-backed snapshot semantics.',
1894+
},
1895+
{
1896+
criterionId: 'query_backend_boundary_present',
1897+
satisfied: true,
1898+
summary: 'Dedicated query backend boundary is present.',
1899+
},
1900+
{
1901+
criterionId: 'vector_backend_present',
1902+
satisfied: true,
1903+
summary: 'Dedicated vector adapter boundary is present.',
1904+
},
1905+
{
1906+
criterionId: 'vector_backend_independent',
1907+
satisfied: false,
1908+
summary: 'Vector backend still resolves to lexical prefilter semantics.',
1909+
},
1910+
{
1911+
criterionId: 'docs_aligned',
1912+
satisfied: true,
1913+
summary: 'EN/ZH checklist and dashboard references are aligned.',
1914+
},
1915+
{
1916+
criterionId: 'readiness_verifier_present',
1917+
satisfied: true,
1918+
summary: 'Readiness verifier command is present in package scripts.',
1919+
},
1920+
],
18831921
promotionBlockerIds: [
18841922
'graph_backend_not_independent',
18851923
'vector_backend_not_independent',

src/frontend/agent_workspace_runtime.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,7 @@
14511451
mandatoryChecksCount: 0,
14521452
promotionCriteriaSatisfiedIds: [],
14531453
promotionCriteriaUnsatisfiedIds: [],
1454+
promotionCriteria: [],
14541455
promotionBlockerIds: [],
14551456
promotionBlockers: [],
14561457
promotionBlockersCount: 0,
@@ -1558,6 +1559,7 @@
15581559
mandatoryChecksCount: mandatoryCheckIds.length,
15591560
promotionCriteriaSatisfiedIds,
15601561
promotionCriteriaUnsatisfiedIds,
1562+
promotionCriteria,
15611563
promotionBlockerIds,
15621564
promotionBlockers,
15631565
promotionBlockersCount: promotionBlockerIds.length,
@@ -1573,7 +1575,7 @@
15731575
'assistant',
15741576
getI18nText(
15751577
'agentWorkspace.messages.foundationReadinessLoaded',
1576-
`Foundation readiness ${trimString(readiness && readiness.status) || 'unknown'} / ${trimString(readiness && readiness.decision) || 'unknown'} (store ${trimString(baseline.storeType) || 'n/a'}, graph ${trimString(baseline.graphBackendStatus) || 'n/a'}/${trimString(baseline.graphBackendSignalKind) || 'n/a'}, graph-independent ${Boolean(baseline.graphBackendIndependent) ? 'yes' : 'no'}, backend ${trimString(baseline.queryBackendDefaultMode) || 'n/a'}, signals ${queryBackendScoreSignals.join(', ') || 'none'}, vector ${trimString(baseline.vectorAdapterStatus) || 'n/a'}, signal-kind ${trimString(baseline.vectorAdapterSignalKind) || 'n/a'}, independent ${Boolean(baseline.vectorAdapterIndependent) ? 'yes' : 'no'}, linked ${Boolean(baseline.vectorAdapterLinkedIntoQueryBackend) ? 'yes' : 'no'}, repo-source ${trimString(provenance.repoRootSource) || 'n/a'}, aligned ${Boolean(provenance.runtimeProjectRootAligned) ? 'yes' : 'no'}, gates ${mandatoryCheckIds.join(', ') || 'none'}, criteria ${promotionCriteriaPassed}/${promotionCriteriaTotal}, satisfied ${promotionCriteriaSatisfiedIds.join(', ') || 'none'}, unmet ${promotionCriteriaUnsatisfiedIds.join(', ') || 'none'}, blockers ${promotionBlockerIds.join(', ') || 'none'}, recommendations ${recommendationsCount}).`,
1578+
`Foundation readiness ${trimString(readiness && readiness.status) || 'unknown'} / ${trimString(readiness && readiness.decision) || 'unknown'} (store ${trimString(baseline.storeType) || 'n/a'}, graph ${trimString(baseline.graphBackendStatus) || 'n/a'}/${trimString(baseline.graphBackendSignalKind) || 'n/a'}, graph-independent ${Boolean(baseline.graphBackendIndependent) ? 'yes' : 'no'}, backend ${trimString(baseline.queryBackendDefaultMode) || 'n/a'}, signals ${queryBackendScoreSignals.join(', ') || 'none'}, vector ${trimString(baseline.vectorAdapterStatus) || 'n/a'}, signal-kind ${trimString(baseline.vectorAdapterSignalKind) || 'n/a'}, independent ${Boolean(baseline.vectorAdapterIndependent) ? 'yes' : 'no'}, linked ${Boolean(baseline.vectorAdapterLinkedIntoQueryBackend) ? 'yes' : 'no'}, repo-source ${trimString(provenance.repoRootSource) || 'n/a'}, aligned ${Boolean(provenance.runtimeProjectRootAligned) ? 'yes' : 'no'}, gates ${mandatoryCheckIds.join(', ') || 'none'}, criteria ${promotionCriteriaPassed}/${promotionCriteriaTotal}, criteria-detail ${promotionCriteria.length}, satisfied ${promotionCriteriaSatisfiedIds.join(', ') || 'none'}, unmet ${promotionCriteriaUnsatisfiedIds.join(', ') || 'none'}, blockers ${promotionBlockerIds.join(', ') || 'none'}, recommendations ${recommendationsCount}).`,
15771579
{
15781580
status: trimString(readiness && readiness.status) || 'unknown',
15791581
decision: trimString(readiness && readiness.decision) || 'unknown',
@@ -1594,6 +1596,7 @@
15941596
mandatoryCheckIds: mandatoryCheckIds.join(', ') || 'none',
15951597
promotionCriteriaPassed,
15961598
promotionCriteriaTotal,
1599+
promotionCriteriaCount: promotionCriteria.length,
15971600
promotionCriteriaSatisfiedIds: promotionCriteriaSatisfiedIds.join(', ') || 'none',
15981601
promotionCriteriaUnsatisfiedIds: promotionCriteriaUnsatisfiedIds.join(', ') || 'none',
15991602
promotionBlockerIds: promotionBlockerIds.join(', ') || 'none',
@@ -1627,6 +1630,7 @@
16271630
mandatoryChecksCount: 0,
16281631
promotionCriteriaSatisfiedIds: [],
16291632
promotionCriteriaUnsatisfiedIds: [],
1633+
promotionCriteria: [],
16301634
promotionBlockerIds: [],
16311635
promotionBlockers: [],
16321636
promotionBlockersCount: 0,

src/frontend/locales/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@
282282
"learningQualitySnapshotFailed": "Learning quality snapshot request failed.",
283283
"learningQualitySnapshotLoaded": "Learning quality snapshot loaded (retest {retestPassRatePct}%, recurrence {misconceptionRecurrenceRatePct}%).",
284284
"foundationReadinessFailed": "Foundation readiness request failed.",
285-
"foundationReadinessLoaded": "Foundation readiness {status} / {decision} (store {storeType}, graph {graphBackendStatus}/{graphBackendSignalKind}, graph-independent {graphBackendIndependent}, backend {queryBackendDefaultMode}, signals {queryBackendScoreSignals}, vector {vectorAdapterStatus}, signal-kind {vectorAdapterSignalKind}, independent {vectorAdapterIndependent}, linked {vectorAdapterLinkedIntoQueryBackend}, repo-source {repoRootSource}, aligned {runtimeProjectRootAligned}, gates {mandatoryCheckIds}, criteria {promotionCriteriaPassed}/{promotionCriteriaTotal}, satisfied {promotionCriteriaSatisfiedIds}, unmet {promotionCriteriaUnsatisfiedIds}, blockers {promotionBlockerIds}, recommendations {recommendationsCount}).",
285+
"foundationReadinessLoaded": "Foundation readiness {status} / {decision} (store {storeType}, graph {graphBackendStatus}/{graphBackendSignalKind}, graph-independent {graphBackendIndependent}, backend {queryBackendDefaultMode}, signals {queryBackendScoreSignals}, vector {vectorAdapterStatus}, signal-kind {vectorAdapterSignalKind}, independent {vectorAdapterIndependent}, linked {vectorAdapterLinkedIntoQueryBackend}, repo-source {repoRootSource}, aligned {runtimeProjectRootAligned}, gates {mandatoryCheckIds}, criteria {promotionCriteriaPassed}/{promotionCriteriaTotal}, criteria-detail {promotionCriteriaCount}, satisfied {promotionCriteriaSatisfiedIds}, unmet {promotionCriteriaUnsatisfiedIds}, blockers {promotionBlockerIds}, recommendations {recommendationsCount}).",
286286
"memoryPolicyFailed": "Memory snapshot request failed.",
287287
"memoryPolicyLoaded": "Memory snapshot loaded ({layer}/{operation}): {entriesCount} entries, evicted {evictedCount}, totals session {sessionCount}, unit {unitCount}, long-term {longTermCount}, recommended {recommendedActionsCount} actions."
288288
}

src/frontend/locales/zh.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@
282282
"learningQualitySnapshotFailed": "学习质量快照请求失败。",
283283
"learningQualitySnapshotLoaded": "学习质量快照已加载(复测通过率 {retestPassRatePct}% ,误解复发率 {misconceptionRecurrenceRatePct}%)。",
284284
"foundationReadinessFailed": "基础就绪性请求失败。",
285-
"foundationReadinessLoaded": "基础就绪性 {status} / {decision}(存储 {storeType},图后端 {graphBackendStatus}/{graphBackendSignalKind},图独立性 {graphBackendIndependent},后端 {queryBackendDefaultMode},打分信号 {queryBackendScoreSignals},向量阶段 {vectorAdapterStatus},信号类型 {vectorAdapterSignalKind},独立性 {vectorAdapterIndependent},接线 {vectorAdapterLinkedIntoQueryBackend},repo 来源 {repoRootSource},对齐 {runtimeProjectRootAligned},门禁 {mandatoryCheckIds},条件 {promotionCriteriaPassed}/{promotionCriteriaTotal},已满足 {promotionCriteriaSatisfiedIds},未满足 {promotionCriteriaUnsatisfiedIds},阻塞项 {promotionBlockerIds},建议 {recommendationsCount} 条)。",
285+
"foundationReadinessLoaded": "基础就绪性 {status} / {decision}(存储 {storeType},图后端 {graphBackendStatus}/{graphBackendSignalKind},图独立性 {graphBackendIndependent},后端 {queryBackendDefaultMode},打分信号 {queryBackendScoreSignals},向量阶段 {vectorAdapterStatus},信号类型 {vectorAdapterSignalKind},独立性 {vectorAdapterIndependent},接线 {vectorAdapterLinkedIntoQueryBackend},repo 来源 {repoRootSource},对齐 {runtimeProjectRootAligned},门禁 {mandatoryCheckIds},条件 {promotionCriteriaPassed}/{promotionCriteriaTotal},条件明细 {promotionCriteriaCount},已满足 {promotionCriteriaSatisfiedIds},未满足 {promotionCriteriaUnsatisfiedIds},阻塞项 {promotionBlockerIds},建议 {recommendationsCount} 条)。",
286286
"memoryPolicyFailed": "记忆快照请求失败。",
287287
"memoryPolicyLoaded": "记忆快照已加载({layer}/{operation}):{entriesCount} 条,清理 {evictedCount} 条,总量 session {sessionCount}、unit {unitCount}、long-term {longTermCount},推荐动作 {recommendedActionsCount} 个。"
288288
}

0 commit comments

Comments
 (0)