Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
53ef9bd
release v0.9.0-rc.1: CI test fixes for agents, preview, models, and b…
jsyqrt Jul 27, 2026
c9aa050
release v0.9.0-rc.2: fix chat load, mailbox ghosts, image preview, an…
jsyqrt Jul 27, 2026
0de307b
fix: resolve eslint eqeqeq and prefer-const in browser helpers
jsyqrt Jul 27, 2026
2584003
fix: add @markus/comms to core tsconfig project references
jsyqrt Jul 27, 2026
03fde1b
release v0.9.0-rc.3: fix core→comms tsconfig reference for CI typecheck
jsyqrt Jul 27, 2026
e07d095
release v0.9.0-rc.4: Hub install deep link with Explore highlight banner
jsyqrt Jul 27, 2026
795efcf
release v0.9.0-rc.5: stamp Hub asset version on install to fix false …
jsyqrt Jul 28, 2026
5f1d8a7
release v0.9.0-rc.6: Windows markus:// protocol, Hub login polling, c…
jsyqrt Jul 29, 2026
76861cb
release v0.9.0-rc.7: Windows install/login UX, hub-login OR sync, sin…
jsyqrt Jul 29, 2026
709b9dc
docs: note v0.9.0-rc.7 changes in RELEASELOG
jsyqrt Jul 29, 2026
a7b17a8
fix: prevent uncaught ENOENT from runtime logger in telemetry tests
jsyqrt Jul 29, 2026
b23509f
release v0.9.0-rc.8: republish install/login UX after stuck rc.7 Publish
jsyqrt Jul 29, 2026
314d45d
fix: cap per-request max_tokens so OpenRouter does not over-reserve c…
jsyqrt Jul 29, 2026
a62a51d
fix: stop injecting catalog max_output into request max_tokens
jsyqrt Jul 29, 2026
e5ffa47
fix: raise BYOK provider default max_tokens from 4k to 32k for coding…
jsyqrt Jul 29, 2026
4f899d5
update
jsyqrt Jul 30, 2026
97ba50d
feat: learning loop, Remember evolve, deliverable/markdown link fixes
jsyqrt Aug 1, 2026
bf7d056
test(billing): freeze Hub plan/cu-sync contract and block BYOK on CU …
jsyqrt Aug 1, 2026
8da2e65
update ui
jsyqrt Aug 2, 2026
c37d5cd
fix: distillation scenario, keyword memory search, and notify_user ch…
jsyqrt Aug 2, 2026
2fbbbd6
fix: resolve lint errors blocking rc release
jsyqrt Aug 2, 2026
94621e2
fix: complete ChatHelpers test fixture for ChatMessageInfo
jsyqrt Aug 2, 2026
859efa7
release v0.9.0-rc.9: Post-task Distillation, keyword memory/skill sea…
jsyqrt Aug 2, 2026
c5c3e0d
fix: align skill injection tests with progressive disclosure
jsyqrt Aug 2, 2026
55cdc7c
fix(windows): shortcuts, hide menu bar, and local Markdown images
jsyqrt Aug 2, 2026
2436de8
release v0.9.0-rc.10: Windows shortcuts, hide menu bar, and local Mar…
jsyqrt Aug 2, 2026
c283f76
fix(windows): stop NSIS custom script from shadowing stock installer.nsh
jsyqrt Aug 2, 2026
4864138
release v0.9.0-rc.11: Windows installer: fix NSIS shadowing, false ru…
jsyqrt Aug 2, 2026
210dc8b
fix(windows): stop upgrade false "cannot be closed" and force shortcuts
jsyqrt Aug 2, 2026
4bb9073
release v0.9.0-rc.12: Windows installer: fix upgrade cannot-close dia…
jsyqrt Aug 2, 2026
ee1d323
fix(windows): hard-patch NSIS templates and create shortcuts on first…
jsyqrt Aug 2, 2026
e35975a
release v0.9.0-rc.13: Windows installer: hard-patch NSIS no-block + f…
jsyqrt Aug 2, 2026
5a274d9
fix(desktop): Windows close-to-tray and macOS titlebar chrome
jsyqrt Aug 2, 2026
6108d17
release v0.9.0-rc.14: macOS titlebar chrome and Windows close-to-tray
jsyqrt Aug 2, 2026
dc67cae
fix(windows): skip unused getProcessInfo in NSIS patch
jsyqrt Aug 2, 2026
f59f457
release v0.9.0-rc.15: fix Windows NSIS build: unused getProcessInfo w…
jsyqrt Aug 2, 2026
e7524b8
fix(windows): drop unused NSIS Var pid from template patch
jsyqrt Aug 2, 2026
d1fd61b
release v0.9.0-rc.16: fix Windows NSIS: remove unused Var pid warning
jsyqrt Aug 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,12 @@ jobs:
- name: Build Electron app
run: pnpm --filter @markus/desktop build:electron

# PowerShell treats `ls -lh` as Get-ChildItem -lh (invalid). Use bash.
- name: Verify Electron dist includes extension zip
run: ls -lh packages/desktop/dist/markus-browser-extension.zip
shell: bash
run: |
test -f packages/desktop/dist/markus-browser-extension.zip
ls -lh packages/desktop/dist/markus-browser-extension.zip

# Fetch the ssign client used by build/sign.cjs and export its native
# Windows path so electron-builder's custom signer can find it.
Expand Down
71 changes: 71 additions & 0 deletions RELEASELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Markus Cloud / Hub 额度与计费体验落地;认知增强与统一 A2A 消
- **Conversation buffer 状态机** — 抽取会话缓冲状态机,修复聊天竞态与流式重连边界
- **Hub recommended routing** — Hub 推荐路由与模型目录 / 路由能力增强
- **Team Chat 菜单优化** — 「移动到」可搜索折叠、组织秘书保护、文案改为「移出团队」
- **飞书原生发图** — `feishu_send_image` / `feishu_send_message`,支持本地图片上传发送

### Bug Fixes

Expand All @@ -20,6 +21,76 @@ Markus Cloud / Hub 额度与计费体验落地;认知增强与统一 A2A 消
- **任务与通知稳定性** — 任务状态实时更新、deliberation / notify 上下文、triage 完整性
- **性能与前端** — Prompt cache 友好与 Tier 3 token 成本优化;web-ui 路由拆分、共享缓存、轮询去重

### v0.9.0-rc.2

- **图片预览** — 大图(webp/png 等)改走 stream,不再被 2MB base64 上限误判为无法预览
- **Team Chat 历史加载** — 修复空 buffer 跳过 DB 拉取;进入会话显示 loading,加载后展示消息
- **Mailbox 幽灵条目** — 修复 background_exec 完成回调广播到所有 Agent;过期 callback_result 自动清理;drop 幂等
- **注意力空闲卡死** — 修复 dequeueAsync lost-wakeup;idle 且有队列时 watchdog nudge;UI 不再显示「等待新邮件」
- **引用回复 / 重复继续** — 引用内容不写入用户气泡;发送去重与 Resume 按钮可见性修正

### v0.9.0-rc.3

- **CI / typecheck** — `@markus/core` 补充 `@markus/comms` project reference,修复干净环境下 `feishu.ts` 找不到模块
- **Lint** — embedded browser / browserUrl 的 eqeqeq、prefer-const 修复

### v0.9.0-rc.4

- **Hub → Markus 安装深链** — 支持 `markus://install?id=&type=`;冷启动保留 pending URL,打开 Explore 并高亮目标条目
- **Explore 安装引导** — DeepLinkBanner + Hub 单项拉取合并进列表,避免目标不在首页结果时无反馈
- **StrictMode / 路由** — 修复 `install` 状态被二次 init 清空;保留 query 并重试导航,保证 banner 可见

### v0.9.0-rc.5

- **Hub 安装版本戳** — 安装时把 Hub 资产 `version` 写入本地 manifest,避免默认 `1.0.0` 导致安装后误显示「升级」
- **Agent hub_install** — `downloadAndInstall` 同步写入 version / hub source,与 UI 安装行为对齐

### v0.9.0-rc.6

- **Windows `markus://` 协议** — NSIS 安装写入 HKCU URL protocol;启动时强制重新注册,修复系统浏览器登录后无法回跳桌面端
- **桌面 Hub 登录轮询** — 打开浏览器后立即轮询;窗口 focus / 可见时立刻再查,避免后台定时器节流导致切回应用仍不完成登录
- **能力分配无工厂默认** — Hub 未推荐的多模态槽位保持空;失效 assignment 自动清理,不再误显示假「已选推荐」

### v0.9.0-rc.7

- **Windows 安装体验** — NSIS 升级时 `taskkill` 强制结束 Markus;`allowElevation: false`;生成 `icon.ico` 保证桌面快捷方式品牌图标
- **首启稳定性** — 未拿到单实例锁不跑 `whenReady`;API `listen` await + health 重试;`before-quit` 2s 超时强制退出
- **Hub 登录 UX(需已部署 Hub)** — 成功页替换表单、禁止自动 `markus://`、验证防双点/重发;Login「已在浏览器打开」+ 取消等待
- **登录后 Cloud AI 就绪** — `hub-login` 内 await OpenRouter sync + 推荐路由;能力分配在 catalog 未就绪时不 persist 清空

### v0.9.0-rc.8

- **重新发版** — rc.7 的 Publish 因 Windows job 长时间 waiting 未完成制品;含 telemetry 测试中 runtime logger ENOENT 修复后重打 tag 触发发布

### v0.9.0-rc.9

- **Post-task Distillation** — 任务 **completed** 后走 `scenario: distillation`(不再误用 Dream);注入 Learning Habits;允许 `package_install`(§8.3 impact/HITL);失败任务不蒸馏
- **Memory / knowledge.md** — 搜索改为关键词 OR 匹配,并覆盖 curated 段落;语义命中时合并 curated 结果
- **通用关键词搜索** — `task_list`、SkillHub / skill loader / 模板搜索共用 `tokenizeSearchQuery`,避免整句 substring 漏检
- **notify_user UX** — 通知栏点击打开 Chat 时不提前 mark-read(保留「知道了」卡片);剥离 segment 中的 `notify_context` 泄漏;虚拟列表 `getItemKey` + 按 `createdAt` 插入,修复气泡重叠

### v0.9.0-rc.10

- **Windows 安装快捷方式** — NSIS 强制创建桌面与开始菜单 `Markus.lnk`(`createDesktopShortcut: always`)
- **Windows 菜单栏** — 隐藏原生「文件/编辑/视图…」菜单栏,保留快捷键
- **Windows Markdown 本地图** — 正确识别 `C:\` / `C:/` / `file:///C:/` 路径并经 `/api/files/image` 渲染;生图 markdown 改用正斜杠

### v0.9.0-rc.11

- **Windows 安装误报「正在运行」** — 覆盖 electron-builder 进程检测(PowerShell/`tasklist` 误判),安装时只做精确 `taskkill`,不再弹窗中止
- **Windows 安装目录空洞** — 自定义 NSIS 脚本改名为 `markus-installer.nsh`,避免遮蔽官方 `installer.nsh`(否则 `installApplicationFiles` 不执行)
- **Windows 快捷方式** — `SetShellVarContext current` 强制写当前用户桌面与开始菜单;注册 App Paths;关闭 elevate helper

### v0.9.0-rc.12

- **Windows 升级弹窗「无法关闭」** — 根因是旧版静默卸载失败 5 次后父安装器复用同一文案;安装前强杀安装目录进程,并清除旧 `UninstallString` 跳过坏卸载器(Electron 覆盖安装)
- **Windows 桌面快捷方式** — 去掉错误的 `menuCategory: false`;`CreateShortCut` + PowerShell `GetFolderPath('Desktop')` 双通道强制创建

### v0.9.0-rc.13

- **Windows 安装弹窗(硬修)** — 打包前直接 patch electron-builder NSIS 模板:进程检测只 `taskkill` 不弹窗;旧卸载失败 5 次后静默继续覆盖安装
- **Windows 桌面快捷方式(硬修)** — 应用首次启动时用 PowerShell 强制创建桌面/开始菜单快捷方式(不依赖 NSIS)

### Stats

- 290 files changed, +36,540 / −12,148 lines
Expand Down
286 changes: 286 additions & 0 deletions docs/AGENT-RUNTIME.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
# Markus Agent Runtime

> Single source of truth for **Context Economics + Learning Loop**.
> Spec language: **MUST** / **SHOULD** / **MUST NOT**. Test IDs map to plan Wave A/B/C.
> Related: [PROMPT-ENGINEERING.md](./PROMPT-ENGINEERING.md), [TOOL-SYSTEM.md](./TOOL-SYSTEM.md),
> [MEMORY-SYSTEM.md](./MEMORY-SYSTEM.md), [LEARNING-LOOP.md](./LEARNING-LOOP.md),
> [STATE-MACHINES.md](./STATE-MACHINES.md).

**Formula**: `Agent = LLM + Harness + Learning Loop`.
**Hard constraint**: the Context Surface keeps cold-start fixed prefix cheap while skills/experience grow unbounded.

---

## §1 Invariants

### §1.1 Fixed-prefix budget

MUST: Every LLM call's fixed prefix `systemTokens + toolDefTokens` MUST fit the active scenario pack budget (see §3) before history is considered.

MUST: When `promptAffordTokens` is known and
`systemTokens + toolDefTokens + PROMPT_AFFORD_OUTPUT_RESERVE + safetyMargin > promptAffordTokens`,
the runtime MUST downgrade once to the `reflex` pack+profile and re-pack; if still over, it MUST NOT call the provider (`prompt_pack_rejected`).

MUST (§Afford.S1): The same afford gate MUST run on **every** LLM entry that calls
`prepareMessages` before the provider — including `handleMessage` **and**
`handleMessageStream` (and task streams that share prepare). Shared helper
`ensureAffordablePromptPack` MUST be used so stream/non-stream cannot drift.

MUST NOT: Shrink only `messageBudget` while shipping a fixed prefix that already exceeds afford.

Test IDs: `A-afford-downgrade`, `A-afford-heartbeat-fail`, `A-budget-contract-converse`,
`A-budget-contract-reflex`, `S-stream-afford-reject`, `S-stream-afford-downgrade`.

### §1.2 Unlimited capability, limited visibility

MUST: Skill full bodies and deferred tool schemas MUST enter context only via `discover_tools` (or equivalent L1 load). Cold start exposes L0 catalog (name + short description) only.

MUST NOT: Inject full SKILL.md bodies at spawn into the system prompt.

Test IDs: `A-skill-l0-only`, `A-tooldef-budget`.

### §1.3 Execute ≠ learn

MUST: Task execution MUST NOT write new team skills. Distillation runs after **`completed`**
(including rejection→revision→approval) via the Learning Loop hook with **`scenario: distillation`**
([LEARNING-LOOP.md](./LEARNING-LOOP.md) §2) — MUST NOT reuse Dream's `memory_consolidation`.
MUST NOT: Distill on `failed`.

Test IDs: `B-hook-skip-trivial`, `B-hook-fire-complex`, `B-hook-skip-failed`,
`B-distill-uses-distillation-scenario`.

### §1.4 Human gate for evolution

MUST: High-impact (or impact-omitted) skill installs require human approve via HITL
([LEARNING-LOOP.md](./LEARNING-LOOP.md) §8.3). Low-impact skill installs MAY proceed without HITL.
Optional `.pending/` staging (§3) remains a helper path.

MUST NOT: Couple skill usage/success metrics to trust score.

Test IDs: `B-approve-install`, `B-reject-feedback`, `B-stats-reject-feedback`.

---

## §2 Scenario Capability Packs

### §2.1 Pack definitions

| Pack | Scenarios | ToolDef budget (tokens) | Prompt profile |
|------|-----------|-------------------------|----------------|
| `reflex` | `heartbeat`, `memory_consolidation` (Dream), `memory_flush`, `distillation` | 3_000 | `reflex` |
| `converse` | `chat`, `a2a`, `group_chat`, `comment_response`, `requirement_action` | 6_000 | `converse` |
| `execute` | `task_execution` | 10_000 | `execute` |
| `govern` | `review`, `deliberation` | 8_000 | `govern` |

MUST: `selectTools` / allowlists MUST resolve through the pack for the active scenario.

### §2.2 Reflex core tools

MUST: `reflex` tool set MUST be a subset of:

`task_list`, `task_get`, `memory_save`, `memory_search`, `notify_user`, `request_user_input`,
`schedule_wakeup`, `cancel_wakeup`, `set_heartbeat_interval`, `discover_tools`,
`check_mailbox`, `file_read`, `agent_send_message`, `update_notebook`,
and for managers additionally `team_status`.

MUST NOT: Include `package_install`, `package_list`, `goal_create`, `goal_update`, `goal_status`,
`spawn_subagent`, `spawn_subagents`, `deliverable_create`, `requirement_propose`,
`memory_update_longterm` in the default reflex allowlist (reachable only via `discover_tools`).

### §2.2.1 Distillation allowlist extras

MUST: When `scenario: distillation`, the runtime MAY widen the allowlist with:
`memory_update`, `memory_update_longterm`, `file_write`, `file_edit`,
`package_list`, `package_install` (plus reflex core, which already includes `request_user_input`).
MUST NOT: Add `hub_install` on the distillation turn.
MUST: Skill `package_install` follows Learning Habits impact/HITL
([LEARNING-LOOP.md](./LEARNING-LOOP.md) §2.2 / §8.3) — high/omitted impact asks first.
MUST: Inject Learning Habits for `distillation`; MUST NOT inject them for `memory_consolidation`.

Test IDs: `A-pack-reflex-tools`, `B-hb-no-evolution-essay`, `B-distill-package-install-allowed`,
`B-distill-habits-injected`, `B-dream-no-habits`.

### §2.3 Converse / execute / govern

MUST: Default `converse` MUST NOT include `spawn_subagents` or `deliverable_create` (discover only).

MUST: `execute` MUST include code/shell/coding groups (or equivalent) needed for task work.

MUST: Keyword matching and `recentToolNames` MAY accelerate loading but MUST NOT exceed the pack `toolDefTokens` budget.

Test IDs: `A-pack-converse-no-spawn`, `A-pack-execute-has-code`, `A-tooldef-sticky-capped`.

---

## §3 Budgets

| Constant | Value | Purpose |
|----------|-------|---------|
| `TOOL_DEF_BUDGET_REFLEX` | 3_000 | Max tool schema tokens |
| `TOOL_DEF_BUDGET_CONVERSE` | 6_000 | Max tool schema tokens |
| `TOOL_DEF_BUDGET_EXECUTE` | 10_000 | Max tool schema tokens |
| `TOOL_DEF_BUDGET_GOVERN` | 8_000 | Max tool schema tokens |
| `ROLE_PROMPT_MAX_TOKENS` | 2_500 | ROLE truncation |
| `KNOWLEDGE_PROMPT_MAX_TOKENS` | 1_500 | knowledge.md injection (`converse`/`execute`/`govern`) |
| `KNOWLEDGE_PROMPT_MAX_TOKENS_REFLEX` | 0 | reflex: no full knowledge dump |
| `STATE_PROMPT_MAX_LINES_REFLEX` | 5 | state.md lines in reflex |
| `STATE_TTL_DAYS` | 7 | state.md entry expiry |
| `COLD_CONVERSE_FIXED_MAX` | 12_000 | Acceptance: system+tools |
| `COLD_REFLEX_FIXED_MAX` | 8_000 | Acceptance: system+tools |
| `SYSTEM_PROMPT_BUDGET_CONVERSE` | 8_000 | Hard cap on converse systemTokens after assemble |
| `DEFERRED_CATALOG_MAX_CHARS` | 1_500 | Tier-3 rediscovery catalog hard cap |
| `DEEP_SLEEP_IDLE_HEARTBEATS` | 3 | Consecutive idle before skip LLM |
| `SUBTASK_SOFT_CAP` | 8 | Warn at/above this count |

Constants live in `@markus/shared` `limits.ts`.

---

## §4 Prompt Profiles

### §4.1 Profile → sections

| Section | reflex | converse | execute/govern |
|---------|--------|----------|----------------|
| ROLE (capped) | yes | yes | yes |
| L0 tool/security rules | yes (short) | yes | yes |
| Identity (roster) | manager + ≤3 active | capped (existing max) | capped |
| knowledge.md | no | capped | capped |
| state.md | ≤5 lines | short/optional | short/optional |
| Skill L0 catalog | yes | yes | yes |
| Skill full bodies | discover only | discover only | discover only |
| L3 checklists (quality/git/error recovery) | no | no | yes |
| Channel history / shared deliverables | no | optional short | as needed |
| Task board detail | counts + top blocked/failed | existing caps | existing caps |

MUST: `buildSystemPrompt` MUST accept `promptProfile` derived from scenario pack.

MUST (§Afford.S3): After assemble, when `promptProfile=converse`, `systemTokens` MUST be
≤ `SYSTEM_PROMPT_BUDGET_CONVERSE` (8000). Over budget: drop lower-priority dynamic
sections in order — team norms/announcements → long Search Strategy → roster detail →
other Tier-3 dynamics — until under budget. ROLE/knowledge caps still apply first.

Test IDs: `A-profile-reflex-omits`, `A-profile-role-cap`, `A-knowledge-cap`,
`S-converse-system-budget`.

---

## §5 ToolDef budget eviction (Hermes Tool Search style)

MUST: When estimated tool-definition tokens exceed the pack budget, the runtime MUST keep:
pack core tools + `discover_tools` + HITL (`notify_user`, `request_user_input`, `request_user_approval`),
then evict largest / least-recently-used extras until under budget.

MUST (§Afford.S2): Evicted tool rediscovery catalog MUST be injected into **system Tier 3**
as a short name-only (or name + ≤40 chars) list, total ≤ `DEFERRED_CATALOG_MAX_CHARS`.

MUST NOT: Append the eviction catalog to `discover_tools.description` (that re-inflates
`toolDefTokens` and defeats the budget).

Test IDs: `A-tooldef-budget`, `A-tooldef-sticky-capped`, `S-catalog-not-in-tooldef`.

### §5.1 max_tokens reservation clamp (§Afford.S4)

MUST: On OpenRouter reservation 402 (`requested up to N … can only afford M`), retry with
`max_tokens = min(M, max(512, M - safety))`.

MUST: When `lastPromptAffordTokens` is known, **first** request MUST also clamp
`max_tokens ≤ promptAfford - estimatedPrompt - margin` so the client does not send a
doomed high reservation (e.g. 13156) before failing.

Test IDs: `S-max-tokens-clamp-remaining`.

---

## §6 Memory taxonomy

MUST: Persistent semantic storage MUST use:

| File | Role |
|------|------|
| `knowledge.md` | Permanent curated knowledge |
| `state.md` | Time-bounded snapshots (TTL) |
| `NOTEBOOK.md` | Situational workspace |
| observations buffer | Raw insights; never fully injected |

MUST: On first load, migrate legacy `MEMORY.md` (heuristic: dated/silent/current → state; else knowledge).

Details: [MEMORY-SYSTEM.md](./MEMORY-SYSTEM.md).

Test IDs: `A-knowledge-cap`, `C-dream-state-ttl`.

---

## §7 Learning Loop (summary)

State machine: `task completed → DistillationHook → Habits encode (memory / skill+HITL) → stats → DreamLibrarian → fanout`.

Also: platform **Learning Habits** L0 (look-back / encode-where / skill impact) and user-initiated
**Remember-from-message** → child evolution session (user↔agent DM only).

Details and MUST rules: [LEARNING-LOOP.md](./LEARNING-LOOP.md) §2–§9.

Test IDs (habits / remember): `B-prompt-learning-habits-*`, `B-skill-install-*`,
`B-self-evolution-skill-retired`, `B-evolve-*`, `B-recall-chat-session-*`, `B-ui-remember-*`.

---

## §8 Governance (summary)

- Review verdicts: `approved` | `approved_with_notes` | `rejected`
- `task_context` attached on assign
- Deliverable `version` + `changelog`
- Deep sleep after idle heartbeats
- Subtask soft cap warning

Details: [STATE-MACHINES.md](./STATE-MACHINES.md) and TOOL/MEMORY docs.

Test IDs: `C-review-notes`, `C-task-context-inject`, `C-deliv-version`, `C-subtask-soft-cap`, `A-deep-sleep-skip`, `A-deep-sleep-wake`.

---

## §9 Acceptance metrics

| Metric | Target | Verify |
|--------|--------|--------|
| Cold converse fixed | ≤ 12_000 (median ≤ 10_000) | `A-budget-contract-converse` + live |
| Cold reflex fixed | ≤ 8_000 | `A-budget-contract-reflex` + live |
| Deep sleep quiet period | 0 LLM calls | `A-deep-sleep-skip` + live |
| Afford over fixed | 0 provider calls | `A-afford-downgrade` |
| Skill library growth | Does not increase fixed L0 cost beyond catalog | `A-skill-l0-only` |
| Evolution rates API | reuse / first-pass / distill rate | `C-metrics-api` |

---

## §10 Spec → Test → Implement → Verify

1. Spec merged (this doc + linked specs).
2. Failing tests with Test IDs above.
3. Minimal implementation to green.
4. Verify checklist against MUST rows; live cold-start logs for Wave D.

If Spec is wrong: fix Spec → fix tests → fix code (never hack around Spec).

## §11 Verification checklist (Wave D)

Automated (must be green):

- [x] `packages/core/test/capability-packs.test.ts` (A-pack-*, A-tooldef-*)
- [x] `packages/core/test/afford-guard.test.ts` (A-afford-*)
- [x] `packages/core/test/deep-sleep.test.ts` (A-deep-sleep-*)
- [x] `packages/core/test/prompt-profiles.test.ts` (A-profile-*, B-hb-no-evolution-essay)
- [x] `packages/core/test/prompt-budget.contract.test.ts` (A-budget-contract-*)
- [x] `packages/core/test/learning-loop.test.ts` (B-hook-*, B-stats-*)
- [x] `packages/core/test/memory-taxonomy.test.ts` (A-knowledge / C-dream-state-ttl)
- [x] `packages/core/test/skill-fanout.test.ts` (C-fanout-*, C-task-context-inject)
- [x] `packages/core/test/evolution-metrics.test.ts` + `GET /api/evolution/metrics` (C-metrics-api)
- [x] `packages/core/test/governance-runtime.test.ts` (C-review-notes / C-subtask-soft-cap)

Live (operator):

1. Cold chat: log `systemTokens`+`toolDefTokens` ≤ 12k
2. Cold heartbeat / deep sleep: ≤ 8k fixed; idle skips LLM
3. Low afford: `prompt_pack_rejected` without OR call
4. Complex task complete → distillation (Habits encode; skill install via §8.3 HITL)
5. Deliverable update returns `version` bump
6. `acceptTask(..., notes)` stores `approved_with_notes`
Loading
Loading