Skip to content

Commit 5c40ad0

Browse files
committed
feat: tighten graph readiness semantics
1 parent d0d9b05 commit 5c40ad0

20 files changed

Lines changed: 277 additions & 17 deletions

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ This document re-baselines current mainline truth on 2026-04-19, records what ch
198198
- readiness now reports `vectorAdapterSignalKind`
199199
- current mainline truth is now machine-readable as lexical-prefilter semantics rather than an ambiguous "vector" label
200200
- overall status still remains `in_progress` / `no-go`, because lexical overlap evidence is still not ANN evidence.
201+
- The next bounded execution slice after that makes graph-backend semantics explicit and closes a readiness loophole:
202+
- readiness now reports `graphBackendStatus`
203+
- readiness now reports `graphBackendSignalKind`
204+
- readiness now reports `graphBackendIndependent`
205+
- integrated readiness now requires independent graph-backend evidence in addition to independent vector evidence
206+
- overall status still remains `in_progress` / `no-go`, because current mainline persistence is still file-backed snapshot-only.
201207
- Current expected outcome on `main` remains:
202208
- status `in_progress`
203209
- decision `no-go`

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,28 @@ Execution anchor:
275275
- decision stays `no-go`,
276276
- no ANN readiness claim is permitted from lexical-prefilter evidence alone.
277277

278+
## Latest Mainline Increment (2026-04-20 M8.10 Foundation Graph-Backend Semantics Evidence)
279+
280+
- Tightened foundation readiness so file-backed snapshot persistence can no longer be mistaken for graph-backend re-entry:
281+
- `FoundationReadinessReport.baseline` now includes `graphBackendStatus`,
282+
- `FoundationReadinessReport.baseline` now includes `graphBackendSignalKind`,
283+
- `FoundationReadinessReport.baseline` now includes `graphBackendIndependent`.
284+
- Readiness promotion logic is now stricter and matches the actual roadmap gap:
285+
- independent vector evidence alone is not enough,
286+
- integrated readiness now also requires independent graph-backend evidence.
287+
- Current mainline truth is now explicit:
288+
- `graphBackendStatus = file_snapshot_only`
289+
- `graphBackendSignalKind = json_snapshot_file`
290+
- `graphBackendIndependent = false`
291+
- Operator/runtime inspectability stayed aligned:
292+
- `scripts/verify-foundation-readiness.js` prints graph-backend semantics,
293+
- `src/frontend/agent_workspace_runtime.js` persists the same graph fields in `lastFoundationReadiness`,
294+
- toolbar summaries now show graph status and signal kind alongside query/vector semantics.
295+
- Guardrail remains unchanged on `main`:
296+
- status stays `in_progress`,
297+
- decision stays `no-go`,
298+
- file snapshots still do not qualify as independent graph backend readiness.
299+
278300
## Latest Mainline Increment (2026-04-16 M7.2 Runtime Evidence Deepening Lane)
279301

280302
- Expanded runtime behavior coverage in `src/agent_workspace.runtime.behavior.test.ts` for pane lifecycle evidence:

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,27 @@ Bundle note:
5555
- Current expected result on `main` is:
5656
- status `In Progress`
5757
- decision `No-Go`
58-
- rationale: file-backed baseline exists, query-backend and vector-boundary modules are now present, but the vector adapter is still only `prefilter_only`, so independent ANN evidence is still absent.
58+
- rationale: mainline persistence is still `file_snapshot_only`, query-backend and vector-boundary modules are present, but graph-backend independence is absent and the vector adapter is still only `prefilter_only`, so independent graph/ANN evidence is still absent.
5959
- The readiness payload now makes that distinction explicit:
60+
- `graphBackendStatus`
61+
- `graphBackendSignalKind`
62+
- `graphBackendIndependent`
6063
- `queryBackendDefaultMode`
6164
- `queryBackendScoreSignals`
6265
- `vectorAdapterLinkedIntoQueryBackend`
6366
- `vectorAdapterStatus`
6467
- `vectorAdapterSignalKind`
6568
- `vectorAdapterIndependent`
69+
- Current expected graph semantics on `main` are:
70+
- `graphBackendStatus = file_snapshot_only`
71+
- `graphBackendSignalKind = json_snapshot_file`
72+
- `graphBackendIndependent = false`
6673
- Current expected signal semantics on `main` are:
6774
- `queryBackendScoreSignals = [keyword_matches, title_match_bonus, vector_prefilter_content_bonus, relation_bonus]`
6875
- `vectorAdapterSignalKind = lexical_token_overlap`
6976
- Interpretation rule:
77+
- `file_snapshot_only` is evidence of snapshot persistence only.
78+
- It is **not** evidence of independent graph-backend semantics.
7079
- `lexical_token_overlap` is evidence of lexical prefilter scoring only.
7180
- It is **not** evidence of embedding-backed ANN readiness.
7281

docs/diataxis/en/explanation/knowledge-mastery-evolution-roadmap.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ This requires:
5353
## Primary Structural Gaps Still Open
5454

5555
1. Graph persistence depth:
56-
- `graphdb` mode currently relies on `FileGraphDbSnapshotAdapter` in `src/learning/store.ts`.
57-
- this preserves fallback reliability but does not yet deliver a true local graph database backend.
56+
- `src/learning/store.ts` currently exposes file-backed snapshot persistence as the verified mainline baseline.
57+
- no independent local graph database backend is integrated on `main` yet.
5858
2. Vector retrieval independence:
5959
- retrieval currently uses `local_hybrid` token/semantic heuristics and `keyword_only` fallback in `src/learning/queryBackend.ts`.
6060
- a standalone vector index backend is not integrated yet.

docs/diataxis/en/reference/release-and-governance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ npm run test:migration
105105
- API contract surface coverage
106106
- runtime runbook and diagnostics endpoints
107107
- Needs continued hardening:
108-
- graphdb backend depth (current graphdb mode still file-adapter backed)
108+
- graph backend depth (current mainline persistence is still file-backed snapshot-only)
109109
- independent vector retrieval backend integration
110110
- stricter promotion from trend observations to hard release quality gates
111111

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,28 @@
275275
- 决策仍为 `no-go`
276276
- 不能把 lexical-prefilter 证据误写成 ANN readiness。
277277

278+
## 主线最新增量(2026-04-20 M8.10 Foundation 图后端语义证据)
279+
280+
- 已加固 foundation readiness,避免把 file-backed snapshot persistence 误读成 graph backend 回归:
281+
- `FoundationReadinessReport.baseline` 新增 `graphBackendStatus`
282+
- `FoundationReadinessReport.baseline` 新增 `graphBackendSignalKind`
283+
- `FoundationReadinessReport.baseline` 新增 `graphBackendIndependent`
284+
- readiness 升级逻辑现在更严格,也更符合真实路线图缺口:
285+
- 只有独立 vector 证据还不够,
286+
- 要进入 integrated readiness,还必须同时具备独立 graph backend 证据。
287+
- 当前主线事实现在已显式化:
288+
- `graphBackendStatus = file_snapshot_only`
289+
- `graphBackendSignalKind = json_snapshot_file`
290+
- `graphBackendIndependent = false`
291+
- 执行侧/运行时可观测性保持对齐:
292+
- `scripts/verify-foundation-readiness.js` 现在输出图后端语义,
293+
- `src/frontend/agent_workspace_runtime.js` 会在 `lastFoundationReadiness` 中保留同样字段,
294+
- 工具栏摘要现在会同时展示图后端状态与信号类型。
295+
- `main` 上的护栏结论保持不变:
296+
- 状态仍为 `in_progress`
297+
- 决策仍为 `no-go`
298+
- file snapshot 仍不构成独立 graph backend readiness。
299+
278300
## 主线最新增量(2026-04-16 M7.2 运行时证据加深链路)
279301

280302
- 已在 `src/agent_workspace.runtime.behavior.test.ts` 扩展 pane 生命周期证据覆盖:

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,27 @@
5555
- 当前主线的预期结果是:
5656
- 状态 `In Progress`
5757
- 决策 `No-Go`
58-
- 原因:file-backed 基线已存在,query-backend 与 vector 边界都已进入主线,但该 vector adapter 仍只是 `prefilter_only`独立 ANN 证据仍未进入主线。
58+
- 原因:主线 persistence 仍是 `file_snapshot_only`,query-backend 与 vector 边界虽已进入主线,但 graph backend 独立性仍缺失,且 vector adapter 仍只是 `prefilter_only`因此独立 graph/ANN 证据仍未进入主线。
5959
- readiness 载荷现在也显式区分这层语义:
60+
- `graphBackendStatus`
61+
- `graphBackendSignalKind`
62+
- `graphBackendIndependent`
6063
- `queryBackendDefaultMode`
6164
- `queryBackendScoreSignals`
6265
- `vectorAdapterLinkedIntoQueryBackend`
6366
- `vectorAdapterStatus`
6467
- `vectorAdapterSignalKind`
6568
- `vectorAdapterIndependent`
69+
- 当前 `main` 的图后端预期语义为:
70+
- `graphBackendStatus = file_snapshot_only`
71+
- `graphBackendSignalKind = json_snapshot_file`
72+
- `graphBackendIndependent = false`
6673
- 当前 `main` 的预期信号语义为:
6774
- `queryBackendScoreSignals = [keyword_matches, title_match_bonus, vector_prefilter_content_bonus, relation_bonus]`
6875
- `vectorAdapterSignalKind = lexical_token_overlap`
6976
- 解读规则:
77+
- `file_snapshot_only` 只表示 snapshot persistence 存在。
78+
-**不等于**独立 graph backend 语义已成立。
7079
- `lexical_token_overlap` 只表示词法预过滤打分存在。
7180
-**不等于** embedding/ANN readiness 已经成立。
7281

docs/diataxis/zh/explanation/knowledge-mastery-evolution-roadmap.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
## 当前仍需优先补齐的结构缺口
5353

5454
1. 图存储深度不足:
55-
- `src/learning/store.ts` `graphdb` 当前仍依赖 `FileGraphDbSnapshotAdapter`
56-
- 具备 fallback 稳定性,但尚未达到“真实本地图数据库后端”目标
55+
- `src/learning/store.ts` 当前在主线仅提供 file-backed snapshot persistence 基线
56+
- `main` 尚未集成独立的本地图数据库图后端
5757
2. 向量检索独立性不足:
5858
- `src/learning/queryBackend.ts` 目前是 `local_hybrid``keyword_only` 两路。
5959
- 尚未接入独立向量索引后端。

docs/diataxis/zh/reference/release-and-governance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ npm run test:migration
105105
- API 契约覆盖
106106
- runtime runbook 与诊断端点
107107
- 需持续补强:
108-
- graphdb 后端深度(当前仍是 file-adapter 模式
108+
- 图后端深度(当前主线仍是 file-backed snapshot-only
109109
- 独立向量检索后端接入
110110
- 将趋势观察进一步升级为硬发布门禁
111111

scripts/foundation-readiness-utils.js

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,53 @@ function resolveQueryBackendDefaultMode(queryBackendSource, graphAdapterModulePr
5151
return 'unknown';
5252
}
5353

54+
function resolveGraphBackendSignalKind(storeSource, storeModulePresent, fileBackedStore) {
55+
if (!storeModulePresent) {
56+
return 'absent';
57+
}
58+
59+
if (fileBackedStore) {
60+
return 'json_snapshot_file';
61+
}
62+
63+
if (
64+
/better-sqlite3/i.test(storeSource)
65+
|| /\bsqlite\b/i.test(storeSource)
66+
|| /createSqliteKnowledgeGraphStore/.test(storeSource)
67+
|| /createLocalGraphDbStore/.test(storeSource)
68+
) {
69+
return 'embedded_graphdb';
70+
}
71+
72+
if (
73+
/neo4j/i.test(storeSource)
74+
|| /cypher/i.test(storeSource)
75+
|| /GraphDbClient/.test(storeSource)
76+
|| /createExternalGraphDbStore/.test(storeSource)
77+
) {
78+
return 'external_graphdb';
79+
}
80+
81+
return 'unknown';
82+
}
83+
84+
function resolveGraphBackendStatus(storeSource, storeModulePresent, fileBackedStore) {
85+
if (!storeModulePresent) {
86+
return 'absent';
87+
}
88+
89+
if (fileBackedStore) {
90+
return 'file_snapshot_only';
91+
}
92+
93+
const signalKind = resolveGraphBackendSignalKind(storeSource, storeModulePresent, fileBackedStore);
94+
if (signalKind === 'embedded_graphdb' || signalKind === 'external_graphdb') {
95+
return 'independent';
96+
}
97+
98+
return 'unknown';
99+
}
100+
54101
function resolveQueryBackendScoreSignals(queryBackendSource, graphAdapterModulePresent) {
55102
if (!graphAdapterModulePresent) {
56103
return [];
@@ -153,6 +200,9 @@ function evaluateFoundationReadiness(options = {}) {
153200
const fileBackedStore =
154201
storeSource.includes('createFileBackedKnowledgeGraphStore')
155202
&& storeSource.includes("storeType: 'file'");
203+
const graphBackendStatus = resolveGraphBackendStatus(storeSource, storeModulePresent, fileBackedStore);
204+
const graphBackendSignalKind = resolveGraphBackendSignalKind(storeSource, storeModulePresent, fileBackedStore);
205+
const graphBackendIndependent = graphBackendStatus === 'independent';
156206
const graphAdapterModulePresent = fileExists(graphAdapterPath);
157207
const queryBackendDefaultMode = resolveQueryBackendDefaultMode(queryBackendSource, graphAdapterModulePresent);
158208
const queryBackendScoreSignals = resolveQueryBackendScoreSignals(
@@ -177,14 +227,15 @@ function evaluateFoundationReadiness(options = {}) {
177227
const readinessVerifierPresent =
178228
scripts['verify:foundation:readiness'] === 'node scripts/verify-foundation-readiness.js';
179229

180-
const baselineReady = fileBackedStore && checklistPagesPresent && dashboardReferencesPresent;
230+
const baselineReady = storeModulePresent && checklistPagesPresent && dashboardReferencesPresent;
181231

182232
let status = 'planned';
183233
let decision = 'no-go';
184234

185235
if (
186236
baselineReady
187237
&& readinessVerifierPresent
238+
&& graphBackendIndependent
188239
&& graphAdapterModulePresent
189240
&& vectorAdapterIndependent
190241
) {
@@ -219,9 +270,21 @@ function evaluateFoundationReadiness(options = {}) {
219270

220271
const recommendations = [];
221272

222-
if (!fileBackedStore) {
273+
if (!fileBackedStore && !graphBackendIndependent) {
274+
recommendations.push(
275+
'Keep foundation re-entry at no-go until store backend evidence is explicit enough to distinguish file snapshots from a real graph backend on mainline.'
276+
);
277+
}
278+
279+
if (!storeModulePresent) {
280+
recommendations.push(
281+
'Restore explicit store backend evidence before advancing foundation readiness claims.'
282+
);
283+
}
284+
285+
if (!graphBackendIndependent) {
223286
recommendations.push(
224-
'Restore explicit file-backed store evidence before advancing foundation readiness claims.'
287+
'Keep foundation re-entry at no-go while graph persistence remains file-backed snapshot storage without independent graph backend semantics on mainline.'
225288
);
226289
}
227290

@@ -270,6 +333,9 @@ function evaluateFoundationReadiness(options = {}) {
270333
exists: storeModulePresent,
271334
loaded: storeModulePresent && storeSource.includes('loadSnapshot'),
272335
fileBackedStore,
336+
graphBackendStatus,
337+
graphBackendSignalKind,
338+
graphBackendIndependent,
273339
graphAdapterModulePresent,
274340
queryBackendDefaultMode,
275341
queryBackendScoreSignals,
@@ -305,6 +371,9 @@ function formatFoundationReadinessMarkdown(result, reportPaths) {
305371
`- Store evidence present: ${result.baseline.exists ? 'yes' : 'no'}`,
306372
`- Store load capability present: ${result.baseline.loaded ? 'yes' : 'no'}`,
307373
`- File-backed store evidence: ${result.baseline.fileBackedStore ? 'yes' : 'no'}`,
374+
`- Graph backend status: ${result.baseline.graphBackendStatus}`,
375+
`- Graph backend signal kind: ${result.baseline.graphBackendSignalKind}`,
376+
`- Graph backend independent: ${result.baseline.graphBackendIndependent ? 'yes' : 'no'}`,
308377
`- Dedicated graph adapter module present: ${result.baseline.graphAdapterModulePresent ? 'yes' : 'no'}`,
309378
`- Query backend default mode: ${result.baseline.queryBackendDefaultMode}`,
310379
`- Query backend score signals: ${result.baseline.queryBackendScoreSignals.join(', ') || 'none'}`,

0 commit comments

Comments
 (0)