Skip to content

Commit 241e699

Browse files
committed
feat: expose readiness gates in runtime
1 parent 483d8da commit 241e699

9 files changed

Lines changed: 79 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
@@ -229,6 +229,10 @@ This document re-baselines current mainline truth on 2026-04-19, records what ch
229229
- agent-workspace diagnostics snapshots now persist both `promotionCriteriaSatisfiedIds` and `promotionCriteriaUnsatisfiedIds`
230230
- toolbar summaries now render both satisfied and unmet criterion ids from the same readiness payload
231231
- overall status still remains `in_progress` / `no-go`.
232+
- The next bounded execution slice after that makes runtime gate parity explicit:
233+
- agent-workspace diagnostics snapshots now persist `mandatoryCheckIds`
234+
- toolbar summaries now render the same gate ids exposed by `mandatoryChecks`
235+
- overall status still remains `in_progress` / `no-go`.
232236
- Current expected outcome on `main` remains:
233237
- status `in_progress`
234238
- decision `no-go`

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,19 @@ Execution anchor:
327327
- decision stays `no-go`,
328328
- runtime parity improves inspectability only; it does not relax graph/vector independence requirements.
329329

330+
## Latest Mainline Increment (2026-04-20 M8.16 Foundation Runtime Gate Parity)
331+
332+
- Closed the next operator-runtime parity gap for readiness verification gates:
333+
- `lastFoundationReadiness.mandatoryCheckIds`
334+
- `lastFoundationReadiness.mandatoryChecksCount`
335+
- Runtime/operator visibility now exposes the same gate ids already carried by the typed readiness payload:
336+
- toolbar summaries render `gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation`,
337+
- diagnostics snapshots keep the gate ids for downstream diffing and exported reports.
338+
- Guardrail remains unchanged on `main`:
339+
- status stays `in_progress`,
340+
- decision stays `no-go`,
341+
- gate parity improves inspectability only; it does not weaken the promotion contract.
342+
330343
## Latest Mainline Increment (2026-04-20 M8.13 Foundation Readiness Provenance Evidence)
331344

332345
- 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 `mandatoryCheckIds` for the active gate contract
5657
- Current expected result on `main` is:
5758
- status `In Progress`
5859
- decision `No-Go`
@@ -88,6 +89,7 @@ Bundle note:
8889
- `promotionCriteriaSatisfiedIds = [store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present]`
8990
- `promotionCriteriaUnsatisfiedIds = [graph_backend_independent, vector_backend_independent]`
9091
- Current expected runtime/operator summary phrasing on `main` is:
92+
- `gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation`
9193
- `satisfied store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present`
9294
- `unmet graph_backend_independent, vector_backend_independent`
9395
- Current expected provenance behavior is:

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,19 @@
327327
- 决策仍为 `no-go`
328328
- 运行时对齐只提升可检查性,不放宽 graph/vector independence 要求。
329329

330+
## 主线最新增量(2026-04-20 M8.16 Foundation 运行时门禁对齐)
331+
332+
- 已补齐 readiness verification gate 在执行侧运行时中的下一处对齐缺口:
333+
- `lastFoundationReadiness.mandatoryCheckIds`
334+
- `lastFoundationReadiness.mandatoryChecksCount`
335+
- 运行时/执行侧现在会暴露 typed readiness payload 已携带的同一组 gate ids:
336+
- 工具栏摘要会显示 `gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation`
337+
- diagnostics snapshot 会保留 gate ids,便于后续 diff 与导出报告。
338+
- `main` 上的护栏结论保持不变:
339+
- 状态仍为 `in_progress`
340+
- 决策仍为 `no-go`
341+
- gate 对齐只提升可检查性,不会削弱 promotion contract。
342+
330343
## 主线最新增量(2026-04-20 M8.13 Foundation Readiness 来源证据)
331344

332345
- 已新增 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 现在也会保留当前 gate contract 的 `mandatoryCheckIds`
5657
- 当前主线的预期结果是:
5758
- 状态 `In Progress`
5859
- 决策 `No-Go`
@@ -88,6 +89,7 @@
8889
- `promotionCriteriaSatisfiedIds = [store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present]`
8990
- `promotionCriteriaUnsatisfiedIds = [graph_backend_independent, vector_backend_independent]`
9091
- 当前主线预期的运行时/执行侧摘要措辞为:
92+
- `gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation`
9193
- `satisfied store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present`
9294
- `unmet graph_backend_independent, vector_backend_independent`
9395
- 当前预期 provenance 行为为:

src/agent_workspace.runtime.behavior.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,22 @@ describe('agent workspace runtime behavior', () => {
17471747
gateId: 'contract',
17481748
command: 'npm test -- src/knowledge.api.contract.test.ts --runInBand',
17491749
},
1750+
{
1751+
gateId: 'core_behavior',
1752+
command: 'npm test -- src/learning/KnowledgeLearningPlatform.test.ts --runInBand',
1753+
},
1754+
{
1755+
gateId: 'persistence_safety',
1756+
command: 'npm test -- src/learning/KnowledgeLearningPlatform.persistence.test.ts --runInBand',
1757+
},
1758+
{
1759+
gateId: 'interaction_non_regression',
1760+
command: 'npm run test:agent-workspace:contracts',
1761+
},
1762+
{
1763+
gateId: 'documentation',
1764+
command: 'npm run docs:diataxis:check && npm run docs:site:build',
1765+
},
17501766
],
17511767
promotionBlockers: [
17521768
{
@@ -1790,6 +1806,9 @@ describe('agent workspace runtime behavior', () => {
17901806
expect(messages.textContent || '').toContain('lexical_token_overlap');
17911807
expect(messages.textContent || '').toContain('repo-source cwd');
17921808
expect(messages.textContent || '').toContain('aligned no');
1809+
expect(messages.textContent || '').toContain(
1810+
'gates contract, core_behavior, persistence_safety, interaction_non_regression, documentation'
1811+
);
17931812
expect(messages.textContent || '').toContain(
17941813
'satisfied store_backend_evidence_present, query_backend_boundary_present, vector_backend_present, docs_aligned, readiness_verifier_present'
17951814
);
@@ -1820,6 +1839,13 @@ describe('agent workspace runtime behavior', () => {
18201839
vectorAdapterLinkedIntoQueryBackend: true,
18211840
repoRootSource: 'cwd',
18221841
runtimeProjectRootAligned: false,
1842+
mandatoryCheckIds: [
1843+
'contract',
1844+
'core_behavior',
1845+
'persistence_safety',
1846+
'interaction_non_regression',
1847+
'documentation',
1848+
],
18231849
promotionCriteriaSatisfiedIds: [
18241850
'store_backend_evidence_present',
18251851
'query_backend_boundary_present',
@@ -1837,6 +1863,7 @@ describe('agent workspace runtime behavior', () => {
18371863
],
18381864
promotionCriteriaPassed: 5,
18391865
promotionCriteriaTotal: 7,
1866+
mandatoryChecksCount: 5,
18401867
promotionBlockersCount: 2,
18411868
recommendationsCount: 2,
18421869
})

src/frontend/agent_workspace_runtime.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1444,8 +1444,10 @@
14441444
vectorAdapterLinkedIntoQueryBackend: false,
14451445
repoRootSource: '',
14461446
runtimeProjectRootAligned: false,
1447+
mandatoryCheckIds: [],
14471448
promotionCriteriaPassed: 0,
14481449
promotionCriteriaTotal: 0,
1450+
mandatoryChecksCount: 0,
14491451
promotionCriteriaSatisfiedIds: [],
14501452
promotionCriteriaUnsatisfiedIds: [],
14511453
promotionBlockerIds: [],
@@ -1468,6 +1470,14 @@
14681470
const recommendationsCount = Array.isArray(readiness && readiness.recommendations)
14691471
? readiness.recommendations.length
14701472
: 0;
1473+
const mandatoryCheckIds = Array.isArray(readiness && readiness.mandatoryChecks)
1474+
? readiness.mandatoryChecks
1475+
.map((entry) => {
1476+
const source = entry && typeof entry === 'object' ? entry : {};
1477+
return trimString(source.gateId);
1478+
})
1479+
.filter(Boolean)
1480+
: [];
14711481
const provenance = readiness && readiness.provenance && typeof readiness.provenance === 'object'
14721482
? readiness.provenance
14731483
: {};
@@ -1527,8 +1537,10 @@
15271537
vectorAdapterLinkedIntoQueryBackend: Boolean(baseline.vectorAdapterLinkedIntoQueryBackend),
15281538
repoRootSource: trimString(provenance.repoRootSource),
15291539
runtimeProjectRootAligned: Boolean(provenance.runtimeProjectRootAligned),
1540+
mandatoryCheckIds,
15301541
promotionCriteriaPassed,
15311542
promotionCriteriaTotal,
1543+
mandatoryChecksCount: mandatoryCheckIds.length,
15321544
promotionCriteriaSatisfiedIds,
15331545
promotionCriteriaUnsatisfiedIds,
15341546
promotionBlockerIds,
@@ -1542,7 +1554,7 @@
15421554
'assistant',
15431555
getI18nText(
15441556
'agentWorkspace.messages.foundationReadinessLoaded',
1545-
`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'}, criteria ${promotionCriteriaPassed}/${promotionCriteriaTotal}, satisfied ${promotionCriteriaSatisfiedIds.join(', ') || 'none'}, unmet ${promotionCriteriaUnsatisfiedIds.join(', ') || 'none'}, blockers ${promotionBlockerIds.join(', ') || 'none'}).`,
1557+
`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'}).`,
15461558
{
15471559
status: trimString(readiness && readiness.status) || 'unknown',
15481560
decision: trimString(readiness && readiness.decision) || 'unknown',
@@ -1560,6 +1572,7 @@
15601572
: 'no',
15611573
repoRootSource: trimString(provenance.repoRootSource) || 'n/a',
15621574
runtimeProjectRootAligned: Boolean(provenance.runtimeProjectRootAligned) ? 'yes' : 'no',
1575+
mandatoryCheckIds: mandatoryCheckIds.join(', ') || 'none',
15631576
promotionCriteriaPassed,
15641577
promotionCriteriaTotal,
15651578
promotionCriteriaSatisfiedIds: promotionCriteriaSatisfiedIds.join(', ') || 'none',
@@ -1587,8 +1600,10 @@
15871600
vectorAdapterLinkedIntoQueryBackend: false,
15881601
repoRootSource: '',
15891602
runtimeProjectRootAligned: false,
1603+
mandatoryCheckIds: [],
15901604
promotionCriteriaPassed: 0,
15911605
promotionCriteriaTotal: 0,
1606+
mandatoryChecksCount: 0,
15921607
promotionCriteriaSatisfiedIds: [],
15931608
promotionCriteriaUnsatisfiedIds: [],
15941609
promotionBlockerIds: [],

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}, criteria {promotionCriteriaPassed}/{promotionCriteriaTotal}, satisfied {promotionCriteriaSatisfiedIds}, unmet {promotionCriteriaUnsatisfiedIds}, blockers {promotionBlockerIds}).",
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}).",
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},条件 {promotionCriteriaPassed}/{promotionCriteriaTotal},已满足 {promotionCriteriaSatisfiedIds},未满足 {promotionCriteriaUnsatisfiedIds},阻塞项 {promotionBlockerIds})。",
285+
"foundationReadinessLoaded": "基础就绪性 {status} / {decision}(存储 {storeType},图后端 {graphBackendStatus}/{graphBackendSignalKind},图独立性 {graphBackendIndependent},后端 {queryBackendDefaultMode},打分信号 {queryBackendScoreSignals},向量阶段 {vectorAdapterStatus},信号类型 {vectorAdapterSignalKind},独立性 {vectorAdapterIndependent},接线 {vectorAdapterLinkedIntoQueryBackend},repo 来源 {repoRootSource},对齐 {runtimeProjectRootAligned},门禁 {mandatoryCheckIds},条件 {promotionCriteriaPassed}/{promotionCriteriaTotal},已满足 {promotionCriteriaSatisfiedIds},未满足 {promotionCriteriaUnsatisfiedIds},阻塞项 {promotionBlockerIds})。",
286286
"memoryPolicyFailed": "记忆快照请求失败。",
287287
"memoryPolicyLoaded": "记忆快照已加载({layer}/{operation}):{entriesCount} 条,清理 {evictedCount} 条,总量 session {sessionCount}、unit {unitCount}、long-term {longTermCount},推荐动作 {recommendedActionsCount} 个。"
288288
}

0 commit comments

Comments
 (0)