Skip to content

Commit 66f011c

Browse files
committed
feat: surface foundation readiness in agent workspace
1 parent e0e292a commit 66f011c

11 files changed

Lines changed: 272 additions & 15 deletions

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ This document re-baselines current mainline truth on 2026-04-19, records what ch
162162
- `npm test -- src/learning/KnowledgeLearningPlatform.persistence.test.ts --runInBand`
163163
- The current working branch remains a reference source for future lanes, not a justification for direct wide merge.
164164

165-
## Execution Note (2026-04-20 M8.1-M8.6)
165+
## Execution Note (2026-04-20 M8.1-M8.7)
166166

167167
- The smallest executed post-M7 slice is now an evidence bundle, not an adapter claim:
168168
- `npm run verify:foundation:readiness`
@@ -185,6 +185,10 @@ This document re-baselines current mainline truth on 2026-04-19, records what ch
185185
- The next bounded execution slice after that propagates the same staged vector metadata through conversation traces:
186186
- `runAgentConversation(...)` now preserves bounded `vectorAcceleration` and `evidenceCoverageRatio` fields
187187
- runtime diagnostics snapshots keep that same metadata in `lastConversation`, so operator evidence no longer drops the staged vector path.
188+
- The next bounded execution slice after that makes the same foundation-readiness baseline inspectable from the operator shell itself:
189+
- agent-workspace toolbar now exposes `Foundation Readiness`
190+
- runtime diagnostics snapshots persist `lastFoundationReadiness`
191+
- no status flip occurs; the route still reports `in_progress` / `no-go`.
188192
- Current expected outcome on `main` remains:
189193
- status `in_progress`
190194
- decision `no-go`

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,23 @@ Execution anchor:
639639
- `npm run docs:diataxis:check`
640640
- `npm run docs:site:build`
641641

642+
## Latest Mainline Increment (2026-04-20 M8.7 Foundation Readiness Toolbar Inspectability)
643+
644+
- Added a bounded operator-side foundation-readiness entry point directly in the agent-workspace toolbar:
645+
- `src/frontend/index.html`
646+
- `src/frontend/agent_workspace_runtime.js`
647+
- The toolbar now pulls the existing typed readiness route instead of relying on build artifacts or manual endpoint inspection:
648+
- `GET /api/knowledge/foundation/readiness`
649+
- Agent-workspace diagnostics snapshots now keep the latest readiness summary alongside conversation diagnostics:
650+
- `lastFoundationReadiness`
651+
- `foundation-reentry-readiness-checklist` runbook link
652+
- Added multilingual UI coverage for the new toolbar action and summary message:
653+
- `src/frontend/locales/en.json`
654+
- `src/frontend/locales/zh.json`
655+
- Added focused regression coverage for toolbar wiring, i18n rerendering, and diagnostics persistence:
656+
- `src/agent_workspace.runtime.behavior.test.ts`
657+
- `src/agent_workspace.runtime.integration.test.ts`
658+
642659
## Latest Mainline Increment (2026-04-20 M8.6 Conversation Trace Vector Visibility)
643660

644661
- Extended `runAgentConversation(...)` trace payloads so conversation-level diagnostics no longer hide the staged vector path:

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ Bundle note:
4848
- `build/foundation-readiness/foundation-readiness-latest.md`
4949
- The same bounded readiness payload is also exposed through:
5050
- `GET /api/knowledge/foundation/readiness`
51+
- Operator-side runtime inspectability is now present without leaving the agent workspace:
52+
- toolbar button `Foundation Readiness`
53+
- diagnostics snapshot field `lastFoundationReadiness`
54+
- runbook link `foundation-reentry-readiness-checklist`
5155
- Current expected result on `main` is:
5256
- status `In Progress`
5357
- decision `No-Go`

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,23 @@
642642
- `npm run docs:diataxis:check`
643643
- `npm run docs:site:build`
644644

645+
## 主线最新增量(2026-04-20 M8.7 Foundation Readiness 工具栏可检查性)
646+
647+
- 已在 agent-workspace 工具栏补上受限 foundation-readiness 入口,方便执行侧直接检查当前主线基线:
648+
- `src/frontend/index.html`
649+
- `src/frontend/agent_workspace_runtime.js`
650+
- 该工具栏动作现在直接调用现有 typed readiness 路由,而不是要求人工查看构建产物或手动访问接口:
651+
- `GET /api/knowledge/foundation/readiness`
652+
- agent-workspace diagnostics snapshot 现在会把最近一次 readiness 摘要与 conversation 诊断并列保留:
653+
- `lastFoundationReadiness`
654+
- `foundation-reentry-readiness-checklist` runbook link
655+
- 已为该工具栏动作与摘要消息补齐多语言 UI 文案:
656+
- `src/frontend/locales/en.json`
657+
- `src/frontend/locales/zh.json`
658+
- 已补工具栏接线、i18n 重渲染与 diagnostics 持久化的聚焦回归:
659+
- `src/agent_workspace.runtime.behavior.test.ts`
660+
- `src/agent_workspace.runtime.integration.test.ts`
661+
645662
## 主线最新增量(2026-04-20 M8.6 Conversation Trace 向量阶段可见性)
646663

647664
- 已扩展 `runAgentConversation(...)` 的 trace 载荷,使对话层诊断不再隐藏 staged vector 路径:

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
- `build/foundation-readiness/foundation-readiness-latest.md`
4949
- 同一份受限 readiness 载荷现在也通过下列路由暴露:
5050
- `GET /api/knowledge/foundation/readiness`
51+
- 执行侧现在也可以直接在 agent workspace 内检查该受限 readiness:
52+
- 工具栏按钮 `Foundation Readiness`
53+
- diagnostics snapshot 字段 `lastFoundationReadiness`
54+
- runbook link `foundation-reentry-readiness-checklist`
5155
- 当前主线的预期结果是:
5256
- 状态 `In Progress`
5357
- 决策 `No-Go`

src/agent_workspace.runtime.behavior.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ type AgentRuntimeModule = {
44
createAgentWorkspaceRuntime: (options?: Record<string, unknown>) => {
55
init: () => void;
66
sendConversation: () => Promise<void>;
7+
loadFoundationReadiness: () => Promise<void>;
78
openLearningPathDock: (preferredAtomId?: string) => void;
89
hidePathDock: () => void;
910
togglePathFullscreen: () => void;
@@ -20,6 +21,7 @@ type AgentRuntimeModule = {
2021
capabilityEvents: Array<Record<string, unknown>>;
2122
lastCapabilityEvent: Record<string, unknown> | null;
2223
lastConversation: Record<string, unknown> | null;
24+
lastFoundationReadiness: Record<string, unknown> | null;
2325
lastFailure: Record<string, unknown> | null;
2426
pathState: {
2527
visible: boolean;
@@ -68,6 +70,7 @@ function createShellHtml(): string {
6870
<button id="agent-workspace-open-learning-path" type="button">Learning Path</button>
6971
<button id="agent-workspace-close-learning-path" type="button">Close Path</button>
7072
<button id="agent-workspace-path-fullscreen" type="button">Path Fullscreen</button>
73+
<button id="agent-workspace-open-foundation-readiness" type="button">Foundation Readiness</button>
7174
<div id="agent-workspace-knowledge-list"></div>
7275
</aside>
7376
</body>
@@ -1528,6 +1531,7 @@ describe('agent workspace runtime behavior', () => {
15281531
'agentWorkspace.placeholders.input': 'Ask in English',
15291532
'agentWorkspace.actions.pathFullscreen': 'Path Fullscreen EN',
15301533
'agentWorkspace.actions.exitPathFullscreen': 'Exit Path Fullscreen EN',
1534+
'agentWorkspace.actions.openFoundationReadiness': 'Foundation Readiness EN',
15311535
'agentWorkspace.messages.clickPointToFocus': 'Click to focus EN',
15321536
'agentWorkspace.labels.score': 'Score EN',
15331537
'agentWorkspace.actions.openLearningPath': 'Open Learning Path EN',
@@ -1536,6 +1540,7 @@ describe('agent workspace runtime behavior', () => {
15361540
'agentWorkspace.placeholders.input': '请用中文提问',
15371541
'agentWorkspace.actions.pathFullscreen': '路径全屏 ZH',
15381542
'agentWorkspace.actions.exitPathFullscreen': '退出路径全屏 ZH',
1543+
'agentWorkspace.actions.openFoundationReadiness': '基础就绪性 ZH',
15391544
'agentWorkspace.messages.clickPointToFocus': '点击进入专注 ZH',
15401545
'agentWorkspace.labels.score': '分数 ZH',
15411546
'agentWorkspace.actions.openLearningPath': '打开学习路径 ZH',
@@ -1612,8 +1617,10 @@ describe('agent workspace runtime behavior', () => {
16121617
await flushAsync();
16131618

16141619
const pathFullscreenButton = document.getElementById('agent-workspace-path-fullscreen') as HTMLButtonElement;
1620+
const readinessButton = document.getElementById('agent-workspace-open-foundation-readiness') as HTMLButtonElement;
16151621
expect(input.placeholder).toBe('Ask in English');
16161622
expect(pathFullscreenButton.textContent).toBe('Path Fullscreen EN');
1623+
expect(readinessButton.textContent).toBe('Foundation Readiness EN');
16171624
runtime.togglePathFullscreen();
16181625
expect(pathFullscreenButton.textContent).toBe('Exit Path Fullscreen EN');
16191626

@@ -1633,6 +1640,7 @@ describe('agent workspace runtime behavior', () => {
16331640
const actionButtonZh = document.querySelector('.agent-workspace-action-button') as HTMLButtonElement;
16341641
expect(input.placeholder).toBe('请用中文提问');
16351642
expect(pathFullscreenButton.textContent).toBe('退出路径全屏 ZH');
1643+
expect(readinessButton.textContent).toBe('基础就绪性 ZH');
16361644
expect(pointCardZh.title).toBe('点击进入专注 ZH');
16371645
expect(pointMetaZh.textContent || '').toContain('分数 ZH: 0.905');
16381646
expect(actionButtonZh.textContent).toBe('打开学习路径 ZH');
@@ -1641,6 +1649,78 @@ describe('agent workspace runtime behavior', () => {
16411649
expect(pathFullscreenButton.textContent).toBe('路径全屏 ZH');
16421650
});
16431651

1652+
test('loads foundation readiness from toolbar and records diagnostics snapshot', async () => {
1653+
const fetchMock = jest.fn().mockResolvedValue({
1654+
ok: true,
1655+
status: 200,
1656+
json: async () => ({
1657+
success: true,
1658+
readiness: {
1659+
evaluatedAt: '2026-04-20T05:00:00.000Z',
1660+
status: 'in_progress',
1661+
decision: 'no-go',
1662+
baseline: {
1663+
storeType: 'file',
1664+
exists: true,
1665+
loaded: true,
1666+
fileBackedStore: true,
1667+
graphAdapterModulePresent: true,
1668+
vectorAdapterModulePresent: true,
1669+
vectorAdapterStatus: 'prefilter_only',
1670+
vectorAdapterIndependent: false,
1671+
},
1672+
documents: {
1673+
checklistPagesPresent: true,
1674+
dashboardReferencesPresent: true,
1675+
},
1676+
packageScripts: {
1677+
readinessVerifierPresent: true,
1678+
},
1679+
mandatoryChecks: [
1680+
{
1681+
gateId: 'contract',
1682+
command: 'npm test -- src/knowledge.api.contract.test.ts --runInBand',
1683+
},
1684+
],
1685+
recommendations: [
1686+
'Keep foundation re-entry at no-go while the vector adapter remains a local prefilter boundary without independent ANN evidence on mainline.',
1687+
],
1688+
},
1689+
}),
1690+
});
1691+
(global as unknown as Record<string, unknown>).fetch = fetchMock;
1692+
1693+
const runtime = runtimeModule.createAgentWorkspaceRuntime({ defaultUserId: 'agent_user_default' });
1694+
runtime.init();
1695+
1696+
const readinessButton = document.getElementById('agent-workspace-open-foundation-readiness') as HTMLButtonElement;
1697+
readinessButton.click();
1698+
await flushAsync();
1699+
1700+
expect(fetchMock).toHaveBeenCalledWith(
1701+
'/api/knowledge/foundation/readiness',
1702+
expect.objectContaining({
1703+
method: 'GET',
1704+
})
1705+
);
1706+
1707+
const messages = document.getElementById('agent-workspace-messages') as HTMLElement;
1708+
expect(messages.textContent || '').toContain('Foundation readiness');
1709+
expect(messages.textContent || '').toContain('prefilter_only');
1710+
1711+
const snapshot = runtime.getDiagnosticsSnapshot();
1712+
expect(snapshot.lastFoundationReadiness).toEqual(
1713+
expect.objectContaining({
1714+
status: 'in_progress',
1715+
decision: 'no-go',
1716+
storeType: 'file',
1717+
vectorAdapterStatus: 'prefilter_only',
1718+
vectorAdapterIndependent: false,
1719+
recommendationsCount: 1,
1720+
})
1721+
);
1722+
});
1723+
16441724
test('records replay candidates and capability execution diagnostics snapshot', async () => {
16451725
const fetchMock = jest
16461726
.fn()

src/agent_workspace.runtime.integration.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ describe('agent workspace runtime integration baseline', () => {
1414
expect(indexHtml).toContain('id="agent-workspace-panel"');
1515
expect(indexHtml).toContain('id="agent-workspace-form"');
1616
expect(indexHtml).toContain('id="agent-workspace-open-learning-path"');
17+
expect(indexHtml).toContain('id="agent-workspace-open-foundation-readiness"');
1718
expect(indexHtml).toContain('<script src="agent_workspace.js"></script>');
1819
expect(indexHtml).toContain('<script src="agent_workspace_runtime.js"></script>');
1920
expect(indexHtml.indexOf('<script src="agent_workspace.js"></script>')).toBeLessThan(
@@ -31,6 +32,7 @@ describe('agent workspace runtime integration baseline', () => {
3132
expect(runtimeSource).toContain('/api/knowledge/mastery/misconceptions');
3233
expect(runtimeSource).toContain('/api/knowledge/quality/snapshot');
3334
expect(runtimeSource).toContain('/api/knowledge/memory/policy');
35+
expect(runtimeSource).toContain('/api/knowledge/foundation/readiness');
3436
expect(runtimeSource).toContain('/api/knowledge/operator/agent-workspace-diagnostics/report');
3537
expect(runtimeSource).toContain('focusOnNode');
3638
expect(runtimeSource).toContain('enterFocusMode');

0 commit comments

Comments
 (0)