Просмотр исходного кода

docs: refresh codemaps for current codebase state

Update the repository atlas and sub-directory codemaps to reflect the
codebase since the last codemap run (2026-07-16):

- Add new directories: src/v2/, src/hooks/cache-monitor/,
  src/hooks/orchestrator-wake/
- Remove stale references to src/council/ and src/loop/
- Refresh task-session-manager, tools, utils, agents, config, cli,
  interview, hooks, and foreground-fallback maps for new/changed files
- Add new root assets (health-check, plugin-entry, tui-preset)
- Update runtime control flow and integration points for v2 adapter,
  cache monitor, orchestrator wake, and cache-safe injection
Michael Henke 3 недель назад
Родитель
Сommit
e09d4c68de

+ 170 - 133
.slim/codemap.json

@@ -1,8 +1,8 @@
 {
   "metadata": {
     "version": "1.0.0",
-    "last_run": "2026-07-16T23:33:10.792Z",
-    "root": "/home/mhenke/Projects/oh-my-opencode-slim/.slim/worktrees/update-codemaps-796",
+    "last_run": "2026-08-22T21:40:44.787Z",
+    "root": "/home/mhenke/Projects/oh-my-opencode-slim",
     "include_patterns": [
       "src/**/*.ts",
       "src/**/*.d.ts",
@@ -27,54 +27,55 @@
     "exceptions": []
   },
   "file_hashes": {
-    "AGENTS.md": "a2286c06f62ff5f9540b8d49308c60d4",
-    "README.md": "df4ce9c97b53f8efeb43a610f004ccbb",
+    "AGENTS.md": "6ac9ea1695fd566a3c824fd15383dde4",
+    "README.md": "a29623bd4957aa13f4a301d1a8cd2a30",
     "biome.json": "b68da34425b83fddbde5718ac6eb82f9",
-    "package.json": "ac69ea41de9813d2e2916a929878fc03",
+    "package.json": "19560bcc11990726917efcd759cf808c",
     "scripts/benchmark-opencode-cache.ts": "7b35c826831a94b76331d873a20870b9",
+    "scripts/cache-smoke.ts": "f27f5fa53efeb9ec0b59caeddeb32c0b",
     "scripts/generate-schema.ts": "007f340e39adf6c3fd76feda72b71df1",
     "scripts/verify-opencode-cache-stability.ts": "5b864c4c4098215bc7bb36a465722333",
-    "scripts/verify-opencode-host-smoke.ts": "a87fdb08b123501edf81618a49bc421d",
-    "scripts/verify-release-artifact.ts": "b9e3ccf7be9dfd22d7edf3f1aa96fc74",
-    "src/agents/council.ts": "e41958aea7a5e8d1c56c2c4d00a9658a",
-    "src/agents/councillor.ts": "f2a0b7d0f9722e1b32e4b385d6b7b716",
-    "src/agents/designer.ts": "aa9cea2bea0f1732965739114559956d",
-    "src/agents/explorer.ts": "d0852357f5f54d9091ce32a7576cbd4e",
-    "src/agents/fixer.ts": "1717c67d9900a9d1fe8d99f2f3b968af",
-    "src/agents/index.ts": "b1820fc922d0caef8f9125b8f9884e74",
-    "src/agents/librarian.ts": "25e64317fd9ef5f8b6759150c44c0ff8",
-    "src/agents/observer.ts": "5387a97e67b194f12c6a57a35b9d8025",
-    "src/agents/oracle.ts": "ef1581f9c8f06cfcec1837f85f69d06e",
-    "src/agents/orchestrator.ts": "ab71eb42a7dfe0a2fd7d9600b70c0058",
-    "src/agents/permissions.ts": "c7916999c6e0edbf4666db6c02bed3cb",
-    "src/cli/background-subagents.ts": "adfda967b577ad4f0494d85447977913",
+    "scripts/verify-opencode-host-smoke.ts": "aeaeda7fbd5b484280a18756b3107832",
+    "scripts/verify-release-artifact.ts": "fc37faf8dfff4391b6668f60b8414729",
+    "src/agents/council-agents.ts": "5adce96026507b3953c085ca4fe8c251",
+    "src/agents/council.ts": "de3c23939de36b2654f16486858ba689",
+    "src/agents/councillor.ts": "b64a90962b39e73ca016b22bb3e5cbab",
+    "src/agents/designer.ts": "6aa3488ef2118e62b31f37062fb716e8",
+    "src/agents/explorer.ts": "663902e14a5d122d37617af464691ef0",
+    "src/agents/fixer.ts": "9b389689f41e3fbfd8d6909a114c82ff",
+    "src/agents/index.ts": "7b5bcb1011f676be24a7857bf3105430",
+    "src/agents/librarian.ts": "f7d841c29b86fb0914ec22c1515c614f",
+    "src/agents/observer.ts": "5e693d44383b87f9ba792edae7c7562a",
+    "src/agents/oracle.ts": "996fed110730313118df6282450b983b",
+    "src/agents/orchestrator.ts": "63729402ca6b77da79f86f2dba2f656f",
+    "src/agents/permissions.ts": "27778e0df22bdfcd1298e3aca3600d63",
+    "src/agents/task-rejection.ts": "f0f7f68b6bb1f4cbe200cc0ee3d4415c",
+    "src/cli/background-subagents.ts": "c5e5103bd90c5baed2bb382147016641",
     "src/cli/companion.ts": "f3031226ff810b9fc703dbd08726f71d",
-    "src/cli/config-io.ts": "5f03ec3adf6e86e550c75f3d9c3252a5",
+    "src/cli/config-io.ts": "3eda5de7f8c1e70f028c13c6289d5c38",
     "src/cli/config-manager.ts": "7f2960f55aaebab21d822c586c2b12eb",
     "src/cli/custom-skills-registry.ts": "a99e63531e71688decc13155e2541611",
     "src/cli/custom-skills.ts": "105f2bd9a36490bfd35858ac36bf5bd6",
-    "src/cli/doctor.ts": "deb359777d243984b6a6ced6aee32651",
-    "src/cli/index.ts": "fdd07aa92581de053e0efc87e0fa0939",
-    "src/cli/install.ts": "379516229bd985e99d518aceb0fe424c",
-    "src/cli/model-key-normalization.ts": "7f988cc8109c95382b9ece9730e2a7a5",
+    "src/cli/doctor.ts": "2e7d890f7a1fec88219c2ec211a48236",
+    "src/cli/index.ts": "48c5a87bd7fad19cf487807e5763229b",
+    "src/cli/install.ts": "4c0497ceccc7189858db249f41d807a6",
     "src/cli/paths.ts": "dd032ba57b84ab4a3a8437d51600acd7",
-    "src/cli/providers.ts": "52b163daa1d840c08e7892af97aaf580",
-    "src/cli/skills.ts": "b867492bc2ef473116d5e39e38957b0c",
-    "src/cli/system.ts": "68f0a50e4fd994dd44eb430572725d82",
-    "src/cli/types.ts": "7fb0770e7aa0e010f0107df45ab5572b",
-    "src/companion/manager.ts": "3a70fe4187581ca9501761e07bc12a8f",
-    "src/companion/updater.ts": "80e8e4d15e299d527b29de0985366d69",
-    "src/config/agent-mcps.ts": "ce2c54b4f82a8a6ab42ed7acb1fc58bf",
-    "src/config/constants.ts": "56cdf3227b18211aee9c0f71fe20f6aa",
-    "src/config/council-schema.ts": "4c44ea0a6e653027f808e2d14649657a",
+    "src/cli/providers.ts": "ed3a68eef81450bc271188ad8c26a15f",
+    "src/cli/skills.ts": "91c1860bc39688143123a8da236dd1b4",
+    "src/cli/system.ts": "073ab15779c286be3898cb88127b3371",
+    "src/cli/types.ts": "bc8e03cc676b45020a5e3a99106ccc2e",
+    "src/companion/manager.ts": "af9ab0205396759188dc3d5aceb8e0fa",
+    "src/companion/updater.ts": "baca2c83da6ac48b1c1c547ec41c5524",
+    "src/config/agent-mcps.ts": "261b538aedd15095f3d003e4396a23d8",
+    "src/config/constants.ts": "656e831d7a85e9b64ec3a7ab8d646a39",
+    "src/config/council-schema.ts": "1e8d7ac163f3ed96185e14782278db32",
     "src/config/index.ts": "8a61e02aa676fc86cc8d9d6d30a2e617",
-    "src/config/loader.ts": "a75402f4d7973e809cf567feaad37af8",
-    "src/config/runtime-preset.ts": "7f924629c21ed1f438bcea8f4a54da02",
-    "src/config/schema.ts": "8622c8a11fc3aa950bd3bba5034f8813",
+    "src/config/loader.ts": "503f768251a9e31764f7f7dc118f8206",
+    "src/config/runtime.ts": "88d28b280d3ccc976e4c295b22e4b32f",
+    "src/config/schema.ts": "eba82c2b06cd2433221d4273cd5a2362",
     "src/config/strip-orchestrator-model.ts": "40f71ea6af0dc37471ec02c6feca65ba",
     "src/config/utils.ts": "ea6fe8ef6dff0848f42f03c7d6983727",
-    "src/council/council-manager.ts": "ef6fda9a031978f353a1f8ed2ae01099",
-    "src/council/index.ts": "24cab5b06b4bfd91d2496692650eb18a",
+    "src/health-check.ts": "a5ce27e6c909c85d479f3c51ee766f3b",
     "src/hooks/apply-patch/codec.ts": "ba2086f51f88c47a67ccf930f0b1e268",
     "src/hooks/apply-patch/errors.ts": "fd2c9d9d185494f2f8b22862bd14700b",
     "src/hooks/apply-patch/execution-context.ts": "b44fb8ae4c672ab7c0b18fb1aa1915a0",
@@ -86,146 +87,182 @@
     "src/hooks/apply-patch/rewrite.ts": "581c23e0f46c26e413cb65df64858582",
     "src/hooks/apply-patch/test-helpers.ts": "27b74cc1c0dec6c9dfdbbea4a9724468",
     "src/hooks/apply-patch/types.ts": "bff517a2050313703b3e8c4af35617d0",
-    "src/hooks/auto-update-checker/cache.ts": "306b85a4beef7fd9959ecdfc655f8c3c",
-    "src/hooks/auto-update-checker/checker.ts": "616bd0fa5e2d00464ef0f2b99ed47a3b",
-    "src/hooks/auto-update-checker/constants.ts": "22f2a2bd7f617601ccb329acd01b85a4",
-    "src/hooks/auto-update-checker/index.ts": "2694ba0b1f252c67d08286b7d776ebe3",
-    "src/hooks/auto-update-checker/skill-sync.ts": "cfabbd86c122ea31dd4c5ac1d45a5407",
-    "src/hooks/auto-update-checker/types.ts": "59800bc1d2a3d189623b56cf49273892",
-    "src/hooks/chat-headers.ts": "282ca8c90c7313aa2085470bf0e64ea3",
+    "src/hooks/auto-update-checker/cache.ts": "a7059ac721e3a8331ee173c03e28a42a",
+    "src/hooks/auto-update-checker/checker.ts": "b859eb88b08c8ba27f73c2df3322ecf3",
+    "src/hooks/auto-update-checker/constants.ts": "72c366a011c637d6f319f8f055b22a9e",
+    "src/hooks/auto-update-checker/index.ts": "8ca4d6a19d51823ccc55559a9e0e7d8b",
+    "src/hooks/auto-update-checker/skill-sync.ts": "0121524151b19f802ddf46e982bbd419",
+    "src/hooks/auto-update-checker/types.ts": "0caaddaa41d694aec5df8f0fe70d1ce3",
+    "src/hooks/cache-monitor/index.ts": "8fa6416cc1d9e1185b40dce0db999c3b",
+    "src/hooks/cache-safe-injection.ts": "471f2b69e91bb09a65d4a9e669f68f12",
+    "src/hooks/chat-headers.ts": "01f0ced532af8408cc6cccaa901f6308",
     "src/hooks/command-hook-utils.ts": "f7ce65b34074d6e489e72be909758524",
-    "src/hooks/deepwork/index.ts": "5e44843e7cb88afad6858dda28c5884d",
-    "src/hooks/filter-available-skills/index.ts": "4278d46c9018b0a86f0e63349f007f4d",
-    "src/hooks/foreground-fallback/index.ts": "bff09c691b6cb004781c2d47a69f15df",
-    "src/hooks/image-hook.ts": "088893355e67c36fb83833cb426e3091",
-    "src/hooks/index.ts": "099abd08860cefd96d756d9a7534ac50",
-    "src/hooks/json-error-recovery/hook.ts": "6b86f68cdf202725ed856c07de622b62",
+    "src/hooks/deepwork/index.ts": "3683d90377fea21a8f149802513b3809",
+    "src/hooks/filter-available-skills/index.ts": "c7fc05c21dff474d5c459763d5ef476b",
+    "src/hooks/foreground-fallback/index.ts": "088f64c017acaa9f1faef2d00c662b2a",
+    "src/hooks/image-hook.ts": "d8dc438943809a20fe23487c5a2096df",
+    "src/hooks/index.ts": "508bf51a8c83d19632ea37e9a3c4d4cb",
+    "src/hooks/json-error-recovery/hook.ts": "532f293e313c81ccc0c6860c928c9792",
     "src/hooks/loop-command/index.ts": "8ec5f5a6b060e73c3522a013e0a7a547",
-    "src/hooks/phase-reminder/index.ts": "fe27f2315b3db06d89688cd480816f03",
-    "src/hooks/post-file-tool-nudge/index.ts": "78dff408792c6860b8ed714119fa148a",
+    "src/hooks/orchestrator-wake/index.ts": "a77faffae34cc7a90a22a379f90bb7cd",
+    "src/hooks/orchestrator-wake/wake-gate.ts": "08278eddab36ee324e09a8435ff082f3",
+    "src/hooks/phase-reminder/index.ts": "ae637a3a1cf9c94f71cad62deb54cd49",
+    "src/hooks/post-file-tool-nudge/index.ts": "dfa47c756086436140b89da7cb8a32da",
     "src/hooks/reflect/index.ts": "1e740d6dc3087d0a3e889a4574adea9e",
     "src/hooks/session-lifecycle.ts": "995a0d52e82f2d27f8bbcad770e7a901",
-    "src/hooks/task-session-manager/index.ts": "ba423e1fe628a920cb9c3044eddec94d",
-    "src/hooks/task-session-manager/pending-call-tracker.ts": "df93dc4ad3e83b3e9a76291bc0da7f3a",
+    "src/hooks/task-session-manager/board-injection.ts": "11f2c64a51dcdb8489affae6cc3e94e6",
+    "src/hooks/task-session-manager/continuation-model-selection.ts": "0283a3f3ce0eee84b99f56e49857342b",
+    "src/hooks/task-session-manager/event-router.ts": "d2ceb196155075be52efd58693bf4f70",
+    "src/hooks/task-session-manager/idle-reconciliation.ts": "1d42e5cb1337cc48988cdf02e458b482",
+    "src/hooks/task-session-manager/idle-session-tokens.ts": "f4b6be104418f51f57d7f86e21bb1e9d",
+    "src/hooks/task-session-manager/index.ts": "c014a0366f206c72ea71e21679d025af",
+    "src/hooks/task-session-manager/input-wait-tracker.ts": "b6d8f2a4741cbd9c357501f19b27091b",
+    "src/hooks/task-session-manager/pending-call-tracker.ts": "dd04ffecf9069ff58225eb7f039dc34b",
+    "src/hooks/task-session-manager/revived-run-tracker.ts": "9c1f86413316474546faa91a630554a2",
+    "src/hooks/task-session-manager/runtime-status-reconciliation.ts": "b7cd33ac5a4adca883b83f65ef392503",
+    "src/hooks/task-session-manager/status-utils.ts": "ee34890653774a5cb21584bc69e75ee4",
+    "src/hooks/task-session-manager/stop-confirmation.ts": "3ad8673125002a232779a25a884c872f",
     "src/hooks/task-session-manager/task-context-tracker.ts": "e6dc74e72aedd014643134afb2c123a6",
-    "src/hooks/types.ts": "6915ec35709366ca261fefbdbf82d106",
+    "src/hooks/task-session-manager/tool-execute-hooks.ts": "8997cc8277aa6cf4e0c52e8eda7485ab",
+    "src/hooks/task-session-manager/user-wait-gate.ts": "c5729f82659d380db63269ff449d42af",
+    "src/hooks/types.ts": "aace1678cede8f0103a3ba5e3ddb26ad",
     "src/index-event.ts": "6b8a88cb4d46536145f2e97fbedfaf63",
-    "src/index.ts": "2fe60e0032400a31dcd8563a0c01bb35",
-    "src/interview/dashboard-manager.ts": "40475436feb2773a825db89827ab28f5",
-    "src/interview/dashboard.ts": "cfff71b7ca3a38b9e58e3ed96262ccea",
-    "src/interview/document.ts": "bfafc0e7874a61889c1555be4e8972a7",
+    "src/index.ts": "7ce2f37ed4084af8b789e85ae5d71357",
+    "src/interview/dashboard-manager.ts": "48736644f9b7eb238ae93f1b4c7efe99",
+    "src/interview/dashboard.ts": "b0ff1951b78c54e989f986dff57ac947",
+    "src/interview/document.ts": "5796f654d689fe660df2a39dd65dbed3",
     "src/interview/helpers.ts": "b95a7e299bb4ab38ab66a272b3ba3612",
     "src/interview/index.ts": "ab5c9a50b6c08826cfd53233cac75f38",
-    "src/interview/manager.ts": "c9c61d5a5914c6cffba33ff6962e93aa",
+    "src/interview/manager.ts": "e6060963f6c3fe0f8b84818819ffeeae",
     "src/interview/parser.ts": "aa6101cf5bebfafcbca845ba532856cf",
     "src/interview/prompts.ts": "b94ef5117d4e720cb5045080b240d890",
+    "src/interview/runtime.ts": "c22f32fba6a2299723596f96300a3221",
     "src/interview/server.ts": "fe5230962e2d44c6bec9909049c971f6",
-    "src/interview/service.ts": "0f202ad1189c858a47c6d75e14ce041f",
-    "src/interview/session-server.ts": "b1e0169aa0720bfc92c63c09007890db",
-    "src/interview/types.ts": "c09bb5def45c25f2a9add1327d88d881",
-    "src/interview/ui.ts": "91e40f593b56547aaae36cbe2d6ad29c",
-    "src/loop/loop-session.ts": "f57ea3e3f0441443b8608e2d1af96414",
+    "src/interview/service.ts": "f6ef9e49e19c85d0bd8b1513dd144428",
+    "src/interview/session-server.ts": "886aa8dfa59655703d8b34bc1a2a61e1",
+    "src/interview/types.ts": "2bb911f02dba3c4d62f3659afb98da07",
+    "src/interview/ui.ts": "4095c18e36ee456263dd5be1e91cf113",
     "src/mcp/context7.ts": "4e02e8ef204b6eb7e99a3209078428b5",
     "src/mcp/grep-app.ts": "53dba799724a92e491b57c30cdbd471d",
-    "src/mcp/index.ts": "e9aec0cf22bc802c343caccd25f39fda",
+    "src/mcp/index.ts": "a860feff331954d72eef4788f0d18e78",
     "src/mcp/types.ts": "a67078f79aa8b99c41fb5be5d9fa9319",
-    "src/mcp/websearch.ts": "7c507eff1d6f9c01d3ccb928ea648ca7",
     "src/multiplexer/cmux/close-policy.ts": "308d7cee31241fadd36d50beeb0a780a",
-    "src/multiplexer/cmux/index.ts": "0baaeee557310c66d09b6fe049a9796b",
-    "src/multiplexer/cmux/session-lifecycle.ts": "5440c777b70464a60b234a5f9ad63a76",
-    "src/multiplexer/cmux/session-state.ts": "d5e717c241b000f87ff0d18615b7df61",
+    "src/multiplexer/cmux/index.ts": "79a26eba1ef063d9625e60568f24213c",
+    "src/multiplexer/cmux/session-lifecycle.ts": "377ce33814614e8632daeedb017e7604",
+    "src/multiplexer/cmux/session-state.ts": "1e70a2f84947aec7d0744532e50cd25b",
     "src/multiplexer/factory.ts": "89ff38238d3472603dc0aa745501d4dc",
-    "src/multiplexer/herdr/index.ts": "7d69e92a23544b26c86b4317461ff118",
-    "src/multiplexer/index.ts": "283b14804726e845668a35cce87e5156",
+    "src/multiplexer/herdr/index.ts": "c96da34945c4846a428f91c53eb738df",
+    "src/multiplexer/index.ts": "46dc33d38285455d468ddb07a9b47a38",
     "src/multiplexer/kitty/index.ts": "e0bd994cb985b38585c96cc6d146b0af",
-    "src/multiplexer/session-manager.ts": "c39e188d74833084046e992317ab8aca",
-    "src/multiplexer/shared.ts": "683394c41053a58fe86208efb40392d3",
-    "src/multiplexer/tmux/index.ts": "0a321fb2a47389cf9049b7d2e82babf0",
-    "src/multiplexer/types.ts": "f3ddc7c01253e7bb1789739412961e89",
-    "src/multiplexer/zellij/index.ts": "4aaaf98818c0481b908c201bc3594351",
+    "src/multiplexer/session-manager.ts": "adf06c4927e2a36dc52064e5f2fc8f28",
+    "src/multiplexer/shared.ts": "599aa49a3ee753d955adb60450f9b23b",
+    "src/multiplexer/tmux-pane-registry.ts": "1ed25325cd8f794175bac7eaea93cf33",
+    "src/multiplexer/tmux/index.ts": "a9ec2f1465c05e63ac2fcdf4d8b52fb7",
+    "src/multiplexer/types.ts": "3792c87c608ad0257d9e7088cf80d6df",
+    "src/multiplexer/zellij/index.ts": "0b510d970929e6da166c63e094c88dc7",
+    "src/plugin-entry.ts": "b80c21813d8ac28854487326d81ea6bb",
     "src/skills/clonedeps/README.md": "1e7ee3fb1032ca64141fe133a3af1cc7",
     "src/skills/codemap/README.md": "fbb3e9fd31ae685b87e630df96c3c60a",
     "src/skills/simplify/README.md": "2786c6e4e6b9f972193353b49741c8e3",
-    "src/tools/acp-run.ts": "f36014b8d84fc415db8067019c123ae4",
+    "src/tools/acp-run.ts": "3ff1e18315aa22f046e21c81bd570fae",
     "src/tools/ast-grep/cli.ts": "94eea47198f97a4169f009e5249c3f7f",
-    "src/tools/ast-grep/constants.ts": "ef016f4d4c5a6861fed9c28e968cad07",
+    "src/tools/ast-grep/constants.ts": "bd764773cbd87214a564e8818dc29e71",
     "src/tools/ast-grep/downloader.ts": "eda4a6bc69a3290a2e54f4d46c639bc1",
-    "src/tools/ast-grep/index.ts": "a2e6261cdd8f4ddfd5d89dcd5ad175eb",
+    "src/tools/ast-grep/index.ts": "3d86a71c4cc44a1d4c7302b88106a5ef",
     "src/tools/ast-grep/tools.ts": "a0d7b252fb2240c8e064b495c19e1f26",
     "src/tools/ast-grep/types.ts": "34ad28b5b1e9617b584f082dba9a427c",
     "src/tools/ast-grep/utils.ts": "1dd3b2133c4b8c847a26eea0423bc0b2",
-    "src/tools/cancel-task.ts": "c55e4173b619dcf199d72c6ecd6f4d09",
-    "src/tools/council.ts": "b00898efae8f045b36eab8719348656b",
-    "src/tools/index.ts": "b562a39a524d55c1b0b33041b62437e8",
-    "src/tools/preset-manager.ts": "7de532fe8a3ca3c439b48796a2182f82",
+    "src/tools/cancel-task.ts": "33f89e0e2082d0abaed6136667940acd",
+    "src/tools/index.ts": "d80d8156fe66d833a4fe0b0fbada90fc",
+    "src/tools/preset-switch.ts": "3cf9d256b24ddeaf630f82fb95cc89e8",
     "src/tools/smartfetch/binary.ts": "a65d816f46ebef11c39bda1764f82bb7",
-    "src/tools/smartfetch/cache.ts": "9a4e272b897b6914f0925919357bfce1",
+    "src/tools/smartfetch/cache.ts": "f9858aa428da313b0572c56797833a6e",
     "src/tools/smartfetch/constants.ts": "1ba20e00a4d3f4717eba62f381f9cd4c",
     "src/tools/smartfetch/index.ts": "5bbf7898199c2764351dac4bc0b28b84",
-    "src/tools/smartfetch/network.ts": "8d4084e73e0ecef33816578a1ca6b398",
-    "src/tools/smartfetch/secondary-model.ts": "a086195fafce7eadc064138f772a4e25",
-    "src/tools/smartfetch/tool.ts": "03e91727dc3d408bdb7f751ac647c0de",
-    "src/tools/smartfetch/types.ts": "2576efe959365f34b7160c409fb54d26",
-    "src/tools/smartfetch/utils.ts": "e2cda2d4ed3f7c20c795c0805a9ebed7",
-    "src/tui-state.ts": "a2ba1a65b1a793a9e21c56ef683d853d",
-    "src/tui.ts": "d8e4a04fb5718efeab270d2e326e0682",
-    "src/utils/agent-variant.ts": "6e112fb56a0eef55c8c1dbff3e9d7c8e",
-    "src/utils/background-job-board.ts": "83827e99a0c0d25daf661ff8ba5fc3cb",
-    "src/utils/background-job-coordinator.ts": "e972bdc1bbab9f4f458a0828ddb0af69",
-    "src/utils/background-job-store.ts": "2114ed7af09bb37e207b0969385707e8",
-    "src/utils/compat.ts": "efb1d9db45c0926079cb780e949fb5dd",
-    "src/utils/councillor-models.ts": "5155941c035ecfd11a4b6248e6c497aa",
+    "src/tools/smartfetch/network.ts": "763a80c161ec12c70be76397ec72330a",
+    "src/tools/smartfetch/secondary-model.ts": "c78e63d451b898cbbf57f774b221f70f",
+    "src/tools/smartfetch/tool.ts": "2e5c44649a0316e275b50eae6d6c35be",
+    "src/tools/smartfetch/types.ts": "570b4b3f2c0df278279912cc63bb9818",
+    "src/tools/smartfetch/utils.ts": "fc973c63b751edc71dbe05dcc4c6d488",
+    "src/tools/task-activity.ts": "ee5948ca23b9b81199e17189d7fe0120",
+    "src/tools/task-message.ts": "d41745c81ddfc0e163939fe660471215",
+    "src/tools/task-policy.ts": "767e005da7815eb251e18233db025125",
+    "src/tools/task-result.ts": "783412d8c041b076128e2348355c654a",
+    "src/tools/task-revive.ts": "d18a9f86d0582991b7d5855d11f0ac42",
+    "src/tools/task-status.ts": "4e34b095489d1d75a9a1a97aa26a9fe1",
+    "src/tools/wait-for-user.ts": "99ee5fa19100e913a0ced0ba211f7c1d",
+    "src/tui-preset.ts": "6c319115381b7a8680e128ccbb9eddf2",
+    "src/tui-state.ts": "2af3c1dc7da26db4c0eb8f35b53ea2ab",
+    "src/tui.ts": "cc221d8418be699a3ff22ec3938af09b",
+    "src/utils/agent-variant.ts": "54ae8809a64d756a3ada7a43b2c3d1ca",
+    "src/utils/background-job-board.ts": "8feaeadc4a67ac8e96070e97d474c579",
+    "src/utils/background-job-coordinator.ts": "b32acbd19d65ed1c792775c919834adb",
+    "src/utils/background-job-store.ts": "4f743da8a90c11e79cf7978e3948455a",
+    "src/utils/background-job-supervisor.ts": "c40cde15b515e7bee6539ac72e14198c",
+    "src/utils/compat.ts": "25668750756e2985d742c8240241a505",
+    "src/utils/councillor-models.ts": "3574e6054a14ca2a02b8f0f5ba279844",
     "src/utils/env.ts": "c4d56b5c308c1047c26d494be45cb86b",
     "src/utils/escape-html.ts": "7ed535f85db49f0c0bc32bfc66b277dd",
     "src/utils/frontmatter.ts": "96e4f25db0c79be5881ee7010c42f002",
     "src/utils/guards.ts": "83af4d036dd573e9008f0c1125e4918c",
-    "src/utils/index.ts": "f301643fe3e74ee3e85d74747f90e72b",
-    "src/utils/internal-initiator.ts": "1a80afe78b5d31dc009981916c56b98d",
-    "src/utils/logger.ts": "965804c3600ab4beddbb5eede3ec53f5",
+    "src/utils/index.ts": "eaa4917ae7dd992f9492c985172cbf56",
+    "src/utils/internal-initiator.ts": "6ed87570892ce481bb62bcb20e6ea773",
+    "src/utils/logger.ts": "b70c54263e00ba69f9813ca0d8186c5c",
+    "src/utils/opencode-client.ts": "164b9e43356eb294455d43973b56705e",
     "src/utils/polling.ts": "b1d9c52df1fae7391234d0f5476d53b5",
-    "src/utils/session.ts": "011831df0cf164aa5adf3048248182dd",
+    "src/utils/session-calls.contract.ts": "436bf8193b2f6cbb1efced175826e513",
+    "src/utils/session-metadata.ts": "6d76baa7665da470bbb9351d06bbca34",
+    "src/utils/session-runtime-status.ts": "9298beea2c391e48408f1134e2ec902f",
+    "src/utils/session.ts": "7ba43387b6d28bfbcade0ddefa947fff",
     "src/utils/system-collapse.ts": "05370b9db1a8dbd4ace4958cc807b912",
-    "src/utils/task.ts": "379ec59e07b805ecc4516387a301c9c2",
+    "src/utils/task.ts": "5ad9ece7c7a26e66aef930833822f99f",
     "src/utils/zip-extractor.ts": "11e6d1913e049f46099bb61d4a77e62b",
+    "src/v2/adapters.ts": "a1e4b2db989aeeb8494ab2f3286417cb",
+    "src/v2/client-shim.ts": "e08ce515c3ef7c7bfc691c239a7f5f13",
+    "src/v2/index.ts": "b94da442bc84923324301382bc649dfc",
+    "src/v2/interview-bridge.ts": "989ee0e898c92da19e57b3a79360a3d7",
+    "src/v2/setup.ts": "c8c00305ac9b806663c6541ca79e2240",
+    "src/v2/types.ts": "0497335fadba103100bacb0bf565f419",
     "tsconfig.json": "1d2bb6e93a43366843785a156c8e538a"
   },
   "folder_hashes": {
-    ".": "a92fa8a3b48cebc741db85c685014408",
-    "scripts": "2e468cad071bd54a61ac8a40474d48bc",
-    "src": "39c025c6925d8d587e8be2995ebf7431",
-    "src/agents": "ac3df2ecd7a4ff7551a7e2d9a9de0b31",
-    "src/cli": "352ed5638f4b50e41b7f1587f1415f0f",
-    "src/companion": "8b4575fe67539633cdcf2b60aa518c30",
-    "src/config": "044488f443b498a9fa730951363c6b3d",
-    "src/council": "2f03fdb968a855548f26aee817a07db7",
-    "src/hooks": "ec9bbfa019da751700f140395a05ccd7",
+    ".": "ca962342638f883cc85f60da004b7eaf",
+    "scripts": "427f1785387eb3d31a39cc8ee2fce816",
+    "src": "9fc74909e8c8e4845769a480f061d40f",
+    "src/agents": "d6a87c4e96654a088147685d4731c6c9",
+    "src/cli": "09307d949d99a450d2237d31fdf0cb7d",
+    "src/companion": "4cdbedd61a0b5a7e5ae17d58ae3cfa10",
+    "src/config": "eee5892cf9a6f292407bdac558bedb5e",
+    "src/hooks": "abeda213368f3b1a6c72e225fb37861b",
     "src/hooks/apply-patch": "d20e3c103082283c3c126b7e936bc041",
-    "src/hooks/auto-update-checker": "afe6d8213cc900b772b9c04ab6a31fd6",
-    "src/hooks/deepwork": "b702d56c5521a7e2d8c43cb93cde8846",
-    "src/hooks/filter-available-skills": "2f0f2cbced0fbe91931733f645209019",
-    "src/hooks/foreground-fallback": "926372a94fc581ef0be0e38a058aa5e8",
-    "src/hooks/json-error-recovery": "fbe725b787123f203b78dd8dfd47db67",
+    "src/hooks/auto-update-checker": "6c765d9a6c1ba8f96fd530cf88758faf",
+    "src/hooks/cache-monitor": "b002bd93d4fa778b9bb4637778ee93a4",
+    "src/hooks/deepwork": "b62186eb9283a40d5048c5f9e28bf899",
+    "src/hooks/filter-available-skills": "f79c51c979f08a72e354261b67830f88",
+    "src/hooks/foreground-fallback": "ed25bdbf42c210ae80c78062ef837d8b",
+    "src/hooks/json-error-recovery": "9a6f5e0605ce6c1a6cd212df4133f030",
     "src/hooks/loop-command": "364539dd39587dabfdc97d5528e28c0c",
-    "src/hooks/phase-reminder": "6fe12077008f7b98b186526dff5c0d26",
-    "src/hooks/post-file-tool-nudge": "0ea51ddc5b163ed1b1edf2e6f4c7258f",
+    "src/hooks/orchestrator-wake": "df741052101b52acfd418930e6918944",
+    "src/hooks/phase-reminder": "418bf027ca7212d758253b0873ad816b",
+    "src/hooks/post-file-tool-nudge": "6b93208fffe68a74dc29c299065a405c",
     "src/hooks/reflect": "2a7700cf8e7f605836d535ebf186b732",
-    "src/hooks/task-session-manager": "b1fcd51c5db5dc7ee94c36cad4338d26",
-    "src/interview": "0a42662dfb4b414a15b8a64bc1bcfcb2",
-    "src/loop": "366bf2141b605deb1849f9783c993810",
-    "src/mcp": "1db30ec46ae0b577ec22b74e2b4d19ea",
-    "src/multiplexer": "bba220d6226456e375acd9fa63a14273",
-    "src/multiplexer/cmux": "db07e581541cafb14fd4e7dca5aba252",
-    "src/multiplexer/herdr": "fa083f9f91998079f8a5ef7fdbc864f5",
+    "src/hooks/task-session-manager": "f76815fed6002becdba0d3996cf1e1ef",
+    "src/interview": "1a21426858761f6d9b015d40ca2de0b6",
+    "src/mcp": "58b40695f80c8a652702524133efc27f",
+    "src/multiplexer": "5b18052486c4a525c3d7c5d3378bee0e",
+    "src/multiplexer/cmux": "12210a7bd5d0d893466af544124b2788",
+    "src/multiplexer/herdr": "ae8bafbad9967bd2a9822556559220fa",
     "src/multiplexer/kitty": "2c2948ba8d8520fd531f7664a2b6533c",
-    "src/multiplexer/tmux": "8ff587c2dd9f1d6d566250f012597876",
-    "src/multiplexer/zellij": "30f51096a0a8c6ffbfc41365326248fc",
+    "src/multiplexer/tmux": "a4e8606b39ca243a68df33520134510e",
+    "src/multiplexer/zellij": "eaf45abb78ca22887a2d497fd5ae96fb",
     "src/skills": "3afb58b43174496617ece428d8deb50d",
     "src/skills/clonedeps": "d1d19753438fdb845f4efca93314a147",
     "src/skills/codemap": "1e82ef833612703b786daceb091f2422",
     "src/skills/simplify": "9c745d8113135e3103af5f1a49d67dfe",
-    "src/tools": "014be624ba388b6761d7e9034d5e8f61",
-    "src/tools/ast-grep": "7091c20c0d028c22effa2b5c1e64cc58",
-    "src/tools/smartfetch": "ca0b801feb29912128015465354cc293",
-    "src/utils": "4e65c5d67f98529ea8b57ff49df2f640"
+    "src/tools": "36bea6fc10b299122b69d4a222adff1c",
+    "src/tools/ast-grep": "c86fba1ffcb3fefe83f0eb85f8de001f",
+    "src/tools/smartfetch": "9a0ed15c66e9a7ed15377a72a3d253f1",
+    "src/utils": "6dcccf25af07f7a934708eb5a6fb6176",
+    "src/v2": "2eea0480ac94330b4414545023adf9a0"
   }
 }

+ 29 - 19
codemap.md

@@ -18,10 +18,10 @@ This codemap covers the plugin repository itself and excludes the nested `openco
 | Path | Role |
 |---|---|
 | `package.json` | Package manifest, dependency graph, release scripts, published file list. |
-| `src/index.ts` | Main plugin bootstrap: wires agents, tools, MCPs, hooks, council managers, shared background job board, multiplexer session mirroring, interview/preset managers, task-session tracking, and config merge behavior. |
+| `src/index.ts` | Main plugin bootstrap: wires agents (incl. dynamic councillors), tools, MCPs, hooks, shared background job board + supervisor, multiplexer session mirroring, interview support, cache monitor, orchestrator-wake scheduler, TUI preset switching, and health checks. Exports the dual `default.server`/`default.setup` so v1 and v2 hosts share one build. |
 | `src/cli/index.ts` | CLI entrypoint for installation/bootstrap workflows. |
 | `src/config/schema.ts` | Source-of-truth runtime config schema used by validation and schema generation. |
-| `src/config/runtime.ts` | Per-directory `RuntimeConfig` singleton: derived getters over the frozen plugin config, host-config capture, and runtime preset state. |
+| `src/config/runtime.ts` | Per-directory `RuntimeConfig` singleton: derived getters over the frozen plugin config, pre-mutation host-config snapshot, and preset/model overrides. |
 | `scripts/generate-schema.ts` | Generates `oh-my-opencode-slim.schema.json` from the Zod config schema. |
 
 ## Repository Directory Map
@@ -29,11 +29,11 @@ This codemap covers the plugin repository itself and excludes the nested `openco
 | Directory | Responsibility Summary | Detailed Map |
 |---|---|---|
 | `src/` | Main application surface that composes plugin bootstrap, runtime model chains, hook orchestration, task-session aliasing, and installer-facing code. | [View Map](src/codemap.md) |
-| `src/agents/` | Agent factory layer for orchestrator and specialists, including prompt/model overrides, display-name normalization, MCP assignment, and permission shaping. | [View Map](src/agents/codemap.md) |
+| `src/agents/` | Agent factory layer for orchestrator and specialists (incl. dynamic `councillor-<name>` agents from council presets), including prompt/model overrides, task-rejection instruction, display-name normalization, MCP assignment, and permission shaping. | [View Map](src/agents/codemap.md) |
 | `src/cli/` | Installer, config editing, provider preset generation, and built-in skill installation. | [View Map](src/cli/codemap.md) |
 | `src/config/` | Configuration schema, layered loaders, preset merging, compatibility migrations, constant tables, the `RuntimeConfig` runtime-state singleton, and agent/MCP policy helpers. | [View Map](src/config/codemap.md) |
 
-| `src/hooks/` | Aggregated runtime hook surface for prompt transforms, recovery logic, task-session aliasing, nudges, and lifecycle policies. | [View Map](src/hooks/codemap.md) |
+| `src/hooks/` | Aggregated runtime hook surface: prompt transforms, cache-safe injection, recovery logic, task-session aliasing, cache monitoring, orchestrator wake, nudges, and lifecycle policies. | [View Map](src/hooks/codemap.md) |
 | `src/hooks/apply-patch/` | Structured `apply_patch` parsing, matching, recovery, and rewrite pipeline. | [View Map](src/hooks/apply-patch/codemap.md) |
 | `src/hooks/auto-update-checker/` | Startup update detection, cache handling, and optional install prompt flow. | [View Map](src/hooks/auto-update-checker/codemap.md) |
 | `src/hooks/filter-available-skills/` | Skill-visibility filtering based on agent permission policy. | [View Map](src/hooks/filter-available-skills/codemap.md) |
@@ -41,7 +41,10 @@ This codemap covers the plugin repository itself and excludes the nested `openco
 | `src/hooks/json-error-recovery/` | JSON/tool-output recovery helpers for malformed model responses. | [View Map](src/hooks/json-error-recovery/codemap.md) |
 | `src/hooks/phase-reminder/` | Message-transform reminder enforcing orchestrator workflow phases. | [View Map](src/hooks/phase-reminder/codemap.md) |
 | `src/hooks/post-file-tool-nudge/` | Post-read/write reminder path that nudges delegation-aware next steps. | [View Map](src/hooks/post-file-tool-nudge/codemap.md) |
-| `src/hooks/task-session-manager/` | Resumable `task` session tracking, short alias resolution, prompt injection, stale-session cleanup, and terminal task reconciliation. | [View Map](src/hooks/task-session-manager/codemap.md) |
+| `src/hooks/task-session-manager/` | Resumable `task` session tracking: job-board injection, short alias resolution, cache-safe prompt injection, idle/stop-confirmation reconciliation, live runtime-status reads, HITL wait gating, and revived-run tracking. | [View Map](src/hooks/task-session-manager/codemap.md) |
+| `src/hooks/cache-monitor/` | Observation-only runtime watchdog over provider cache telemetry (`tokens.cache.read/write`) that warns on prompt-cache busts and frozen-prefix plateaus. | [View Map](src/hooks/cache-monitor/codemap.md) |
+| `src/hooks/orchestrator-wake/` | Periodic orchestrator wake scheduler: after continuous parent idle, sends a static internal wake prompt when incomplete TODOs remain; process-global one-flight/no-progress gate. | [View Map](src/hooks/orchestrator-wake/codemap.md) |
+| `src/hooks/loop-command/` | `/loop` runtime command: extracts goal/successCriteria/maxAttempts and drives an iterative retry loop with a per-run history directory. | [View Map](src/hooks/loop-command/codemap.md) |
 | `src/interview/` | `/interview` feature: per-session and dashboard prompt/state orchestration, persistence, local UI, and cross-process coordination. | [View Map](src/interview/codemap.md) |
 | `src/mcp/` | Built-in MCP registry and per-provider MCP definitions. | [View Map](src/mcp/codemap.md) |
 | `src/multiplexer/` | Terminal multiplexer abstraction layer with backend selection, session mirroring, polling fallback, and shutdown lifecycle orchestration. | [View Map](src/multiplexer/codemap.md) |
@@ -53,33 +56,34 @@ This codemap covers the plugin repository itself and excludes the nested `openco
 | `src/skills/codemap/` | Repository-mapping skill package and codemap state-management script. | [View Map](src/skills/codemap/codemap.md) |
 | `src/skills/clonedeps/` | Workflow-only dependency source mirroring skill that routes discovery/ref resolution through librarian and direct orchestrator git operations. | [View Map](src/skills/clonedeps/codemap.md) |
 | `src/skills/simplify/` | Behavior-preserving simplification skill package. | [View Map](src/skills/simplify/codemap.md) |
-| `src/tools/` | Tool and runtime-command export surface for AST-grep, smartfetch, council orchestration, and `/preset` switching. | [View Map](src/tools/codemap.md) |
+| `src/tools/` | Tool factory surface for AST-grep, smartfetch, ACP, and task lifecycle controls (cancel/message/status/result/revive/wait-for-user), plus shared task-status policy and activity trackers and on-disk preset-switching helpers. | [View Map](src/tools/codemap.md) |
 | `src/tools/ast-grep/` | AST-grep binary management and AST-aware search/replace tool flow. | [View Map](src/tools/ast-grep/codemap.md) |
 | `src/tools/smartfetch/` | Fetch/extract/cache pipeline for web content and secondary-model summarization. | [View Map](src/tools/smartfetch/codemap.md) |
-| `src/utils/` | Cross-cutting helpers for logging, session metadata, resumable task aliases, system-message normalization, environment, and runtime operations. | [View Map](src/utils/codemap.md) |
+| `src/utils/` | Cross-cutting helpers: logging, session metadata, background job board/store/coordinator/supervisor, live session-status reads, in-process opencode client access, task parsing, env, compat/zip, and client call-shape contracts. | [View Map](src/utils/codemap.md) |
 | `src/v2/` | OpenCode v2 (`opencode2`) adapter: bridges the v1 plugin factory into v2's promise-plugin transform/runtime-hook API. Loaded via `default.setup`; v1 uses `default.server` unchanged. | [View Map](src/v2/codemap.md) |
 | `scripts/` | Build/release validation and generated-artifact maintenance scripts. | [View Map](scripts/codemap.md) |
 
 ## Runtime Control Flow
 
 1. **Plugin startup**
-   - OpenCode loads `src/index.ts`.
-   - Config is loaded and normalized through `src/config/`.
-   - Agent definitions are produced by `src/agents/`.
+   - OpenCode loads `src/index.ts` (v1 via `default.server`; v2 via `default.setup` through `src/v2/`).
+   - Config is loaded and normalized through `src/config/`; the `RuntimeConfig` singleton captures the pre-mutation host config.
+   - Agent definitions (incl. dynamic councillors) are produced by `src/agents/`.
    - Tool factories from `src/tools/` and MCP definitions from `src/mcp/` are registered.
-   - Hooks from `src/hooks/` are attached.
-   - Delegation/council orchestration, multiplexer session mirroring, interview support, task-session aliasing, and runtime preset handling are initialized.
+   - Hooks from `src/hooks/` are attached; the observation-only cache monitor is created before config loads and sees every event.
+   - Delegation orchestration, multiplexer session mirroring, interview support, task-session aliasing, orchestrator-wake scheduling, TUI preset switching, and the init health check are initialized.
 
 2. **Interactive request handling**
    - The orchestrator prompt drives routing decisions.
    - Tool calls resolve through `src/tools/` or built-in OpenCode tools.
    - Hooks can transform prompts/messages, normalize system message arrays, repair tool failures, or intercept runtime commands before/after execution.
+   - Prompt content is injected only through the cache-safe helpers in `src/hooks/cache-safe-injection.ts` so provider prompt-cache prefixes stay byte-stable.
 
 3. **Delegated execution**
-   - Native OpenCode background tasks are parsed from `task` output and injected completion messages and tracked in the shared background job board.
-   - `src/hooks/task-session-manager/` updates job-board state, resolves short aliases, and injects background/reusable job context into the orchestrator prompt.
-   - `src/multiplexer/` optionally mirrors those sessions into tmux, Zellij,
-     Herdr, or cmux panes/surfaces.
+   - Native OpenCode background tasks are parsed from `task` output and tracked in the shared background job board (board + store + coordinator + supervisor in `src/utils/`).
+   - `src/hooks/task-session-manager/` updates job-board state, resolves short aliases, and injects background/reusable job context; a delayed runtime-status reconciliation and stop-confirmation grace keep board state honest against live session status.
+   - `src/hooks/orchestrator-wake/` periodically nudges an idle parent orchestrator when incomplete TODOs remain and reacts to jobs that stop without a terminal result.
+   - `src/multiplexer/` optionally mirrors those sessions into tmux, Zellij, Herdr, cmux, or kitty panes/surfaces (tmux routing resolves the attached parent-session pane registration).
    - Results flow back into the parent session through notifications/output polling.
 
 4. **Install/release path**
@@ -96,9 +100,12 @@ This codemap covers the plugin repository itself and excludes the nested `openco
 - cmux-specific readiness, retry, orphan, and cleanup state lives under
   `src/multiplexer/cmux/`; the generic manager delegates cmux events so other
   multiplexer behavior remains on the upstream path.
-- Council mode is implemented in `src/agents/`; the orchestrator dispatches councillors as subagents and the council agent synthesizes responses.
-- `src/tools/preset-manager.ts` hooks command execution and updates runtime agent models from configured presets.
-- `src/hooks/task-session-manager/` depends on `src/utils/background-job-board.ts` and `src/utils/task.ts` to support background task tracking, task output parsing, terminal task reconciliation, and safe alias reuse.
+- Council mode is implemented in `src/agents/`; `council-agents.ts` builds dynamic `councillor-<name>` subagents from council presets, the orchestrator dispatches them, and the council agent synthesizes responses.
+- `src/tools/preset-switch.ts` + `src/tui-preset.ts` implement `/preset` switching: the preset name (or preset edits) is persisted to the user config file and takes effect on the next reload; the agent registry is never hot-swapped mid-session.
+- `src/hooks/task-session-manager/` depends on `src/utils/background-job-board.ts`, `background-job-store.ts`, `background-job-coordinator.ts`, `background-job-supervisor.ts`, `session-runtime-status.ts`, and `task.ts`, and injects prompt content only through `src/hooks/cache-safe-injection.ts`.
+- `src/hooks/cache-monitor/` watches `message.updated` cache telemetry across all sessions and logs prompt-cache-bust/plateau warnings; it is observation-only and never mutates messages.
+- `src/hooks/orchestrator-wake/` reads host todo/children/status APIs, gates on the task-session-manager's `hasInputWait` and continuation-model seams, and shares one-flight/no-progress state via a process-global wake gate.
+- `src/v2/` wraps the v1 factory for the v2 host: `setup(ctx)` shims a v1 `PluginInput`, runs the v1 `config()` hook, and adapts agent/tool/command/hook registrations into v2 domains.
 - `src/hooks/filter-available-skills/` and agent permission logic rely on shared skill names from the CLI/config layer.
 - `src/interview/` hooks into plugin command/event surfaces exposed by `src/index.ts`.
 
@@ -110,6 +117,9 @@ This codemap covers the plugin repository itself and excludes the nested `openco
 - `tsconfig.json`: TypeScript compiler settings.
 - `.slim/codemap.json`: codemap change-detection state for this repository.
 - `scripts/verify-release-artifact.ts`: release artifact validation script.
+- `src/health-check.ts`: plugin init health-check thresholds (`HEALTH_CHECK`) and `minimumExpectedToolCount` (accounts for disabled baseline tools); kept internal — never re-exported from the package root — so the legacy plugin loader cannot mis-invoke helpers as plugin factories (issue #894).
+- `src/plugin-entry.ts`: `INSTALLER_MANAGED_PLUGIN_OPTION` marker and `PluginEntry` type for installer-managed config entries.
+- `src/tui-preset.ts`: three-level TUI `/preset` manager (preset list → agents → agent edit) using `api.ui` dialogs, persisting via `src/tools/preset-switch.ts`.
 
 ## Recommended Reading Order
 

+ 8 - 4
src/agents/codemap.md

@@ -20,7 +20,7 @@ Each agent is a **prompt-driven specialist** with a factory function that create
 | **fixer** | `createFixerAgent()` | Fast implementation specialist for bounded tasks | Read/write (read, glob, grep, write, edit) | DEFAULT_MODELS.fixer |
 | **observer** | `createObserverAgent()` | Visual analysis specialist (images, PDFs, diagrams) | Read-only (read, glob, grep, ast_grep_search) | DEFAULT_MODELS.observer |
 | **council** | `createCouncilAgent()` | Multi-LLM consensus synthesis from councillor responses | Read-only | DEFAULT_MODELS.council |
-| **councillor** | `createCouncillorAgent()` | Read-only council advisor; registered dynamically per preset seat as `councillor-<name>` | Read-only (read, glob, grep, ast_grep_search) | Inherited from council preset |
+| **councillor** | `createCouncillorAgent()` | Read-only council advisor; registered dynamically per preset seat as `councillor-<name>` by `buildCouncillorAgents()` (`council-agents.ts`) | Read-only (read, glob, grep, ast_grep_search) | Inherited from council preset |
 
 ### Configuration System
 
@@ -33,9 +33,11 @@ Each agent is a **prompt-driven specialist** with a factory function that create
 ### Agent Lifecycle
 
 1. **Agent creation**: `createAgents(config)` instantiates all agents with merged configuration
-2. **Permission application**: `applyDefaultPermissions()` sets read/write permissions based on agent type
-3. **Display name injection**: Orchestrator prompt rewrites `@agent` mentions to user-configured display names
-4. **Configuration export**: `getAgentConfigs()` converts `AgentDefinition` to OpenCode SDK format with classification metadata
+2. **Dynamic councillors**: `buildCouncillorAgents()` (`council-agents.ts`) creates one `councillor-<name>` subagent per council preset seat, attaching `_modelArray` fallback chains for multi-model councillors
+3. **Permission application**: `applyDefaultPermissions()` sets read/write permissions based on agent type
+4. **Task-rejection instruction**: `appendTaskRejectionInstruction()` appends the "outside your role" instruction to specialist prompts (`task-rejection.ts`)
+5. **Display name injection**: Orchestrator prompt rewrites `@agent` mentions to user-configured display names
+6. **Configuration export**: `getAgentConfigs()` converts `AgentDefinition` to OpenCode SDK format with classification metadata
 
 ## Flow
 
@@ -180,6 +182,8 @@ These rules are filtered based on disabled agents and injected into the orchestr
 - `observer.ts` - Visual analysis specialist
 - `council.ts` - Multi-LLM council agent
 - `councillor.ts` - Read-only council advisor (internal)
+- `council-agents.ts` - Dynamic `councillor-<name>` agent builders from council presets
+- `task-rejection.ts` - Task-rejection instruction appended to specialist prompts
 - `permissions.ts` - Permission factory for read-only agents
 
 ## Design Patterns

+ 4 - 1
src/cli/codemap.md

@@ -11,14 +11,17 @@ The CLI follows a command pattern with two primary commands:
 - `doctor`: Diagnoses plugin configuration issues and validates setup
 
 ### Architecture Pattern: Command Router
-- **index.ts**: Routes CLI arguments to appropriate command handlers
+- **index.ts**: Routes CLI arguments to appropriate command handlers (install/doctor)
 - **install.ts**: Orchestrates multi-step installation workflow
 - **doctor.ts**: Validates configuration and environment
+- **types.ts**: Shared CLI argument types (`InstallArgs`, `BooleanArg`, `SkillsArg`, `CompanionArg`, `OpenCodeConfig`, `InstallConfig`)
 
 ### Configuration Management Pattern
+- **config-manager.ts**: Barrel re-exporting `config-io`, `paths`, `providers`, and `system` for a single import surface
 - **config-io.ts**: Handles reading, parsing, and writing configuration files (supports both .json and .jsonc)
 - **paths.ts**: Resolves configuration file paths across different environments (XDG_CONFIG_HOME, custom paths, defaults)
 - **providers.ts**: Generates configuration presets and manages model mappings for different providers
+- **system.ts**: Resolves the `opencode` binary path (Windows-aware `where`/`which` + shell handling) and related system checks
 
 ### Permission and Skill Management
 - **custom-skills.ts**: Registry of custom skills bundled with the plugin and their installation logic

+ 26 - 14
src/codemap.md

@@ -4,8 +4,12 @@
 
 Core plugin implementation for **oh-my-opencode-slim**, providing:
 - Main plugin initialization and OpenCode integration (`index.ts`)
+- Dual v1/v2 host export: `default.server` (v1) + `default.setup` (v2 adapter via `src/v2/`)
 - Terminal User Interface (TUI) sidebar plugin for agent status display (`tui.ts`)
 - TUI state persistence and synchronization across sessions (`tui-state.ts`)
+- Three-level TUI `/preset` manager (`tui-preset.ts`)
+- Installer-managed plugin-entry marker (`plugin-entry.ts`)
+- Plugin init health-check thresholds and helpers (`health-check.ts`)
 
 This directory serves as the primary entry point for the plugin's runtime behavior, configuration system, and user-facing UI components.
 
@@ -26,34 +30,38 @@ OpenCode Core → Plugin Initialization (index.ts)
   → Agent Registration (createAgents/getAgentConfigs)
   → Tool Registration (createCancelTaskTool, etc.)
   → MCP Registration (createBuiltinMcps)
-  → Hook Registration (auto-update, phase reminders, etc.)
+  → Hook Registration (auto-update, phase reminders, cache monitor, etc.)
   → Event Subscription (session lifecycle, message updates, tool execution)
   → Runtime State Tracking (tui-state.ts)
   → TUI Rendering (tui.ts → sidebar_content slot)
+  → TUI /preset Management (tui-preset.ts → preset-switch.ts)
 ```
 
 ### Key Components
 
 | File | Role | Dependencies |
 |------|------|--------------|
-| `index.ts` | Main plugin entry, orchestrates all subsystems | Config system, agent factories, tool creators, multiplexer |
-| `tui.ts` | TUI sidebar plugin for agent model display | tui-state.ts, config constants |
+| `index.ts` | Main plugin entry, orchestrates all subsystems; exports dual `server`/`setup` default | Config system, agent factories, tool creators, multiplexer, hooks, v2 adapter |
+| `tui.ts` | TUI sidebar plugin for agent model display | tui-state.ts, config constants, tmux-pane-registry |
 | `tui-state.ts` | Persistent state management for TUI | Node.js fs/promises, os module |
+| `tui-preset.ts` | Three-level `/preset` manager (preset list → agents → agent edit) using `api.ui` dialogs | preset-switch.ts, config loader/constants |
+| `plugin-entry.ts` | Installer-managed plugin entry marker and `PluginEntry` type | none |
+| `health-check.ts` | Init health-check thresholds and disabled-tool-aware minimum tool count | none (kept internal, not re-exported) |
 
 ## Flow
 
 ### Plugin Initialization Flow (index.ts)
 
-1. **Config Loading**: `loadPluginConfig()` reads and validates plugin configuration
-2. **Agent Creation**: `createAgents()` instantiates agent definitions with prompts and permissions
+1. **Config Loading**: `loadPluginConfig()` reads and validates plugin configuration; `RuntimeConfig` singleton seeded and host config captured
+2. **Agent Creation**: `createAgents()` instantiates agent definitions (incl. dynamic councillors) with prompts and permissions
 3. **Agent Configuration**: `getAgentConfigs()` merges defaults with user overrides and runtime presets
-4. **Tool Registration**: Tools are created conditionally based on config (council, task_cancel, task_message, task_revive, webfetch, AST-grep)
-5. **MCP Registration**: Built-in MCPs are created (filesystem, resource, tools, etc.)
+4. **Tool Registration**: Tools are created conditionally based on config (task_cancel, task_message, task_revive, task_status, task_result, wait_for_user, webfetch, AST-grep, acp_run)
+5. **MCP Registration**: Built-in MCPs are created (context7, gh_grep)
 6. **Multiplexer Setup**: Multiplexer session manager initialized for task tool sessions
-7. **Hook Initialization**: Auto-update checker, phase reminders, skill filters, etc.
+7. **Hook Initialization**: Auto-update checker, phase reminders, skill filters, task-session manager, cache monitor, orchestrator-wake scheduler, etc.
 8. **Runtime Model Resolution**: Resolves model arrays to single models for startup
 9. **TUI State Sync**: `recordTuiAgentModels()` captures resolved models/variants for TUI display
-10. **Health Check**: Validates minimum agent/tool/MCP registrations
+10. **Health Check**: Validates agent/tool/MCP counts against `HEALTH_CHECK` thresholds, adjusted for disabled baseline tools via `minimumExpectedToolCount`
 11. **Companion Management**: Ensures companion version compatibility
 
 ### TUI Rendering Flow (tui.ts)
@@ -104,7 +112,10 @@ Key event flows:
    - `experimental.chat.messages.transform` → phase reminders, skill filtering, image attachment processing
 
 5. **Command Execution**:
-   - `command.execute.before` → interview, preset, deepwork, and reflect command hooks
+   - `command.execute.before` → interview, deepwork, reflect, and loop command hooks (preset switching moved to the TUI)
+
+6. **Cache Telemetry**:
+   - `message.updated` (completed assistant requests) → cache monitor observes `tokens.cache.read/write` and logs prompt-cache bust/plateau warnings
 
 ## Integration
 
@@ -120,12 +131,13 @@ Key event flows:
 
 - **Config System** (`src/config/`): Configuration loading, validation, the `RuntimeConfig` runtime-state singleton, and runtime presets
 - **Agents** (`src/agents/`): Agent personalities and permission sets
-- **Tools** (`src/tools/`): Tool implementations (council, webfetch, AST operations)
-- **Hooks** (`src/hooks/`): Lifecycle hooks for auto-update, phase reminders, etc.
+- **Tools** (`src/tools/`): Tool implementations (task lifecycle controls, webfetch, AST operations, ACP)
+- **Hooks** (`src/hooks/`): Lifecycle hooks for auto-update, phase reminders, cache monitor, orchestrator wake, etc.
 - **Multiplexer** (`src/multiplexer/`): Tmux/Zellij session management for child sessions
 - **Council** (`src/agents/council.ts`, `src/agents/council-agents.ts`): Multi-LLM council orchestration
 - **Companion** (`src/companion/`): Companion version management
-- **Utils** (`src/utils/`): Logger, environment checks
+- **Utils** (`src/utils/`): Logger, environment checks, background job board/supervisor, session status
+- **V2 Adapter** (`src/v2/`): Wraps the v1 factory for the v2 host via `default.setup`
 
 ### Cross-Directory Flow
 
@@ -138,7 +150,7 @@ Key event flows:
 
 - Plugin config loaded via `loadPluginConfig()` with support for:
   - User overrides from `~/.config/opencode/oh-my-opencode-slim.json`
-  - Runtime presets via `/preset` command
+  - Preset switching via the TUI `/preset` manager (persisted to the config file, applied on next reload)
   - Environment-based disablement via `OH_MY_OPENCODE_SLIM_DISABLE`
 - Agent configurations merged with user settings from OpenCode config
 - Model resolution supports both string models and array-based fallback chains

+ 8 - 6
src/config/codemap.md

@@ -28,7 +28,8 @@ The config system follows a layered architecture:
 | `AgentOverrideConfig` | Per-agent configuration (model, temperature, skills, MCPs) | schema.ts |
 | `CouncilConfig` | Multi-LLM council configuration with presets and execution modes | council-schema.ts |
 | `MultiplexerConfig` | Unified pane management configuration (tmux/zellij) | schema.ts |
-| `RuntimeConfig` | Per-directory runtime config singleton with derived getters and preset state | runtime.ts |
+| `AgentMcpPolicy` | Per-agent default MCP lists and wildcard/exclusion parsing | agent-mcps.ts |
+| `RuntimeConfig` | Per-directory runtime config singleton with derived getters, host-config snapshot, and preset/model overrides | runtime.ts |
 
 ## Flow
 
@@ -53,6 +54,7 @@ The config system follows a layered architecture:
 
 4. Runtime Phase
    ├─ RuntimeConfig seeded with deep-frozen plugin config snapshot
+   ├─ captureHostConfig() snapshots the host opencode.json BEFORE the config hook mutates it
    └─ Derived getters (agents, modelArrays, disabled*, presets) computed on demand
 ```
 
@@ -129,6 +131,7 @@ This allows consumers to import directly from `src/config` rather than individua
 - `getCustomAgentNames(config)`: List custom agents declared in config.agents
 - `getAcpAgentNames(config)`: List ACP agent names from config.acpAgents
 - `loadAgentPrompt(agentName, preset?)`: Load custom prompt files for agents
+- `stripOrchestratorModel` / `applyOrchestratorModelConfig` (strip-orchestrator-model.ts): Strip the orchestrator's single model/variant when a fallback chain is configured
 
 ### Runtime State
 
@@ -136,14 +139,13 @@ This allows consumers to import directly from `src/config` rather than individua
 - `RuntimeConfig.get(directory)`: Get (lazily creating) the singleton for a directory
 - `RuntimeConfig.reset(directory)`: Clear the singleton for a directory
 - `RuntimeConfig.captureHostConfig(opencodeConfig)`: Capture host-side config before the config hook mutates it
-- `setRuntimePreset(name)`: Set the currently active runtime preset (stale names clear it)
-- `getRuntimePreset()`: Get the currently active runtime preset
-- Derived getters: `agents()`, `agent(name)`, `disabledAgents`, `disabledTools`, `disabledSkills`, `disabledMcps`, `imageRouting`, `multiplexer`, `backgroundJobs`, `fallback`, `webfetch`, `acpAgents`, `companion`, `council`, `modelArrays`, `runtimeChains`, `primaryModel`, `smallModel()`, `hostAgent(name)`
+- `setRuntimePreset(name)` / `getRuntimePreset()`: Runtime preset override (stale names clear it)
+- Derived getters: `plugin`, `preset`, `agents()`, `agent(name)`, `disabledAgents`, `disabledTools`, `disabledSkills`, `customAgentNames`, `disabledMcps`, `imageRouting`, `multiplexer`, `backgroundJobs` (incl. `orchestratorWake`), `fallback`, `webfetch`, `acpAgents`, `companion`, `council`, `autoUpdate`, `stripOrchestratorModel`, `setDefaultAgent`, `compactSidebar`, `modelArrays` (incl. councillor chains), `runtimeChains`, `primaryModel`, `smallModel()`, `hostAgent(name)`
 
 ### MCP Management
 
-- `getAgentMcpList(agentName, config?)`: Resolve MCP permissions for an agent
-- `parseList(items, allAvailable)`: Parse wildcard and exclusion syntax in MCP lists
+- `DEFAULT_AGENT_MCPS` + `parseList` (agent-mcps.ts): Per-agent default MCP lists and wildcard/exclusion parsing
+- `getAgentMcpList(agentName, config?)`: Resolve effective MCP permissions for an agent
 
 ## Configuration Schema Overview
 

+ 81 - 0
src/hooks/cache-monitor/codemap.md

@@ -0,0 +1,81 @@
+# src/hooks/cache-monitor/
+
+## Responsibility
+
+Runtime watchdog for provider prompt-cache busts. Offline tests prove the
+plugin projects a byte-stable payload, but only the provider knows whether a
+cache prefix was actually reused. OpenCode surfaces per-request cache
+telemetry on assistant messages (`tokens.cache.read` / `tokens.cache.write`);
+this hook watches those numbers and logs a loud warning when a session that
+previously enjoyed cache hits suddenly reports zero cached tokens on a
+sizeable request — the field signature of a mid-session prompt-prefix change.
+
+Observation only: it never mutates messages or state, and it fails open on any
+unexpected event shape. See `docs/cache-verification.md` for the full story.
+
+## Design
+
+- **Factory** (`index.ts`): `createCacheMonitorHook(options)` returns a single
+  `event` hook. Created at plugin start before config loads so it sees every
+  event; sits outside the init try-block.
+- **Per-session state**: `Map<sessionID, SessionCacheState>` tracking completed
+  request count, `everReportedCache`, last `cache.read`, warned-since-last-hit
+  flag, never-cached streak/input totals, and plateau streak/input totals.
+  Deduplicated by processed message IDs; bounded at `MAX_TRACKED_SESSIONS`
+  (256) and `MAX_TRACKED_MESSAGES_PER_SESSION` (512).
+- **Three detection modes**:
+  1. **Mid-session bust** — a session that previously hit the cache reports
+     `cacheRead === 0` on a request ≥ 2048 input tokens (the classic
+     prompt-prefix-change signature).
+  2. **Never-cached streak** — ≥ 3 consecutive sizeable zero-cache requests
+     and ≥ 100k cumulative uncached input tokens with no cache write ever
+     (busted from turn one; the first-mode warning never arms).
+  3. **Cache-read plateau** (issue #874 signature) — `cache.read` frozen at
+     the same nonzero value across ≥ 4 sizeable requests while ≥ 50k uncached
+     input accumulates (the reusable prefix has stopped growing).
+- Small requests (< 2048 input tokens) are ignored: they sit under provider
+  minimum-cacheable-prefix thresholds and legitimately report zero.
+- Warnings are hedged and reference `docs/cache-verification.md`.
+
+## Flow
+
+```
+message.updated (completed assistant, role=assistant, time.completed set)
+    ↓
+parseCompletedAssistantMessage() → { sessionID, messageID, inputTokens, cacheRead, cacheWrite }
+    ↓
+observe() (dedup by messageID)
+    ├─ busted? (everReportedCache && cacheRead === 0 && inputTokens ≥ 2048) → warn (once per hit)
+    ├─ never cached? (cacheRead === 0 && cacheWrite === 0 && sizeable)
+    │     → extend streak; warn at thresholds
+    ├─ plateau? (cacheRead > 0 && cacheRead === lastCacheRead)
+    │     → extend streak; warn at thresholds (any change resets)
+    └─ cacheRead > 0 → re-arm warnedSinceLastHit; update everReportedCache/lastCacheRead
+
+session.deleted → drop per-session state
+```
+
+## Integration
+
+- **Consumer**: `src/index.ts` creates the hook at plugin factory start and
+  routes every event through it.
+- **Dependencies**: `isRecord` (`src/utils/guards.ts`) for safe event shape
+  parsing, `log` (`src/utils/logger.ts`) for warnings (injectable via
+  `CacheMonitorOptions.logger` for tests).
+- **Relationships**: complements the offline cache-safety tests
+  (`src/hooks/cache-safety.property.test.ts`, `cache-payload.snapshot.test.ts`,
+  `src/cache-safety-tripwire.test.ts`) — this is the online half that only the
+  provider can confirm.
+
+## Error Handling
+
+- Every event is wrapped in try/catch: telemetry must never break event
+  handling (fails open).
+- Non-numeric/missing token fields are treated as unobservable; events without
+  a completed timestamp are skipped (streaming updates carry no final counts).
+
+## Performance Considerations
+
+- Observation only — no timers, no I/O, no message mutation.
+- Bounded state per session and capped session count; message-ID sets are
+  cleared when they hit the cap.

+ 109 - 52
src/hooks/codemap.md

@@ -1,85 +1,142 @@
 # src/hooks/
 
 ## Responsibility
-Implements OpenCode lifecycle hooks that transform, process, and manage chat messages and attachments during the plugin's message pipeline. These hooks are invoked by OpenCode's `experimental.chat.messages.transform` API to modify message content before it reaches models or after responses are generated.
+
+Implements the plugin's OpenCode lifecycle hooks: message/prompt transforms,
+tool-execute interception, event handling, cache-safe prompt injection, and
+runtime command interception. Each hook is a factory function (barrel-exported
+from `index.ts`) that returns the hook points OpenCode invokes.
 
 ## Design
 
 ### Core Architecture
-- **Factory Pattern**: Each hook is created via a factory function (e.g., `createApplyPatchHook()`, `createAutoUpdateCheckerHook()`) that returns a hook function matching the OpenCode hook signature.
-- **HookRegistry**: Central ordered dispatcher (`src/hooks/hook-registry.ts`). Hooks register handlers via `registry.register(hookPoint, handler)`; `src/index.ts` dispatches through `registry.dispatch()` instead of calling each hook directly.
-- **SessionLifecycle**: Coordinator (`src/hooks/session-lifecycle.ts`) that owns cleanup callback registration and pending-session signaling channel with timestamp TTL. Stateful hooks register cleanup callbacks instead of implementing their own `session.deleted` handlers.
-- **Stateful Factories**: Hook factories may maintain closure state between invocations (e.g., `createAutoUpdateCheckerHook` guards with `hasChecked`; `createTaskSessionManagerHook` manages session lifecycle). Other hooks remain stateless - each factory decides based on its needs.
-- **Message Transformation Pipeline**: Hooks operate on the `MessageWithParts[]` type, allowing transformation of user messages, assistant responses, and system messages.
 
-### Key Types & Interfaces
-- `MessageInfo`: Metadata about a message (role, agent, sessionID, id)
-- `MessagePart`: Individual content part of a message (text, file, image, tool use, etc.)
-- `MessageWithParts`: Complete message with metadata and array of parts
+- **Factory barrel** (`index.ts`): Exports every hook factory plus the shared
+  helpers (`cache-safe-injection`, `chat-headers`, `command-hook-utils`,
+  `image-hook`, `session-lifecycle`, `types`). `src/index.ts` imports from here
+  rather than individual files.
+- **SessionLifecycle** (`session-lifecycle.ts`): Coordinator that owns
+  `session.deleted` cleanup-callback registration and a pending-session
+  signaling channel with consume-once semantics. Stateful hooks register
+  cleanup callbacks instead of implementing their own `session.deleted`
+  handlers.
+- **Cache-safe injection** (`cache-safe-injection.ts`): The single supported
+  way to add content to the outgoing prompt payload:
+  - `appendTaggedSyntheticPart` — deterministic content appended to the tail of
+    an existing message.
+  - `stripTaggedContent` + `appendTrailingVolatileMessage` — volatile content
+    (job boards, status blocks): strip previously injected occurrences, then
+    re-append one synthetic trailing message so churn only costs the prompt
+    tail.
+  Never mutates/reorders earlier messages and never injects unmarked parts —
+  enforced by the cache-safety property/snapshot/tripwire tests.
+- **Command hook helper** (`command-hook-utils.ts`): `registerCommandHook`
+  shared by command-style hooks (deepwork, reflect, loop).
+- **Message types** (`types.ts`): `MessageInfo`, `MessagePart`,
+  `MessageWithParts`, plus replay helpers used by foreground-fallback.
 
 ### Hook Categories
-1. **Attachment Processing**: `processImageAttachments` - Extracts image data URLs from messages, saves them to `.opencode/images/` directory, and replaces image parts with text references containing file paths.
-2. **State Management**: Hooks like `createTaskSessionManagerHook` that manage session state and lifecycle.
-3. **Error Recovery**: Hooks like `createJsonErrorRecoveryHook` that detect and recover from JSON parsing errors.
-4. **UI/UX Enhancement**: Hooks like `createPhaseReminderHook` that add contextual reminders to messages.
+
+| Category | Factories | Hook points |
+|---|---|---|
+| Prompt transforms | `createApplyPatchHook`, `createPhaseReminderHook`, `createPostFileToolNudgeHook`, `createChatHeadersHook`, task-session-manager board injection, `processImageAttachments` | `experimental.chat.messages.transform`, `chat.headers` |
+| Tool interception | `createApplyPatchHook` (tool), task-session-manager | `tool.execute.before` / `tool.execute.after` |
+| Error recovery | `createJsonErrorRecoveryHook`, `createAutoUpdateCheckerHook` | message transform, tool-execute after |
+| Lifecycle/event | task-session-manager, `createCacheMonitorHook`, `createOrchestratorWakeScheduler` | `event` |
+| Runtime commands | `createDeepworkCommandHook`, `createReflectCommandHook`, `createLoopCommandHook` | `command.execute.before` |
+| Skill visibility | `createFilterAvailableSkillsHook` | message transform |
+| Model fallback | `ForegroundFallbackManager` | event-driven (message.updated/session.error/session.status) |
 
 ## Flow
 
 ### Message Processing Pipeline
-```
-1. OpenCode receives chat messages
-2. Plugin's `experimental.chat.messages.transform` hook is invoked
-3. Each registered hook receives the message array sequentially
-4. Hooks transform messages (e.g., extract images, add metadata, validate structure)
-5. Transformed messages are sent to the model
-6. Model responses are transformed by hooks in reverse order
-7. Final messages are returned to OpenCode
-```
 
-### Image Attachment Flow (processImageAttachments)
 ```
-1. Hook receives messages with image parts (type='image' or type='file' with image/* mime)
-2. For each user message with images:
-   a. Decode data URLs to binary data
-   b. Generate SHA1 hash of image data for unique identification
-   c. Save image to `.opencode/images/[sessionID]/` directory
-   d. Create unique filename with hash to prevent collisions
-   e. Replace image parts with text reference containing file paths
-   f. Add informational text about image attachment for model context
-3. Cleanup old images older than 60 minutes (debounced every 10 minutes)
+1. OpenCode receives chat messages
+2. Plugin's experimental.chat.messages.transform hook is invoked (src/index.ts
+   composes: apply-patch → phase-reminder → filter-available-skills →
+   task-session-manager board injection, in that order)
+3. Task-session-manager first stabilizes still-running task tool parts, then
+   rehydrates historical running tasks, then injects the Background Job Board
+   via cache-safe helpers
+4. Transformed messages are sent to the model
+5. chat.headers is forwarded to OpenCode's header slot
+6. Model responses/events are observed by the cache monitor (telemetry) and
+   orchestrator-wake scheduler (idle nudge timing)
 ```
 
 ### Hook Registration
+
 ```
 1. Plugin initializes (src/index.ts)
-2. Hook factories are called, returning handler maps
-3. Handlers are registered with HookRegistry via `hookRegistry.register(hookPoint, handler)`
-4. `src/index.ts` dispatches via `hookRegistry.dispatch()` per hook point
-5. OpenCode invokes hooks during message lifecycle
+2. Hook factories are called, returning handler objects
+3. src/index.ts wires them directly into the plugin's hook object
+   (no central registry; factories are composed at the call site)
+4. Stateful hooks register session.deleted cleanup with SessionLifecycle
+5. OpenCode invokes hooks during the message/tool/event lifecycle
 ```
 
+### Event Observation (event hook)
+
+- task-session-manager routes session lifecycle events (created, idle, busy,
+  error, deleted, server.instance.disposed) to its reconcilers.
+- `createCacheMonitorHook` watches completed assistant messages for
+  `tokens.cache.read/write` and logs prompt-cache bust/plateau warnings
+  (observation only, fails open).
+- `createOrchestratorWakeScheduler` tracks continuous parent idle and triggers
+  periodic wake prompts (see its sub-map).
+
 ## Integration
 
 ### Consumers
-- **Main Plugin**: `src/index.ts` - registers hooks with OpenCode during plugin initialization
-- **OpenCode Runtime**: Invokes hooks during `experimental.chat.messages.transform` API calls
+
+- **Main Plugin** (`src/index.ts`): imports every factory from `index.ts` and
+  wires the returned handlers into the plugin's hook object.
+- **Task-session-manager**: depends on `cache-safe-injection.ts` for all prompt
+  injection and on `session-lifecycle.ts` for delete coordination.
+- **Orchestrator-wake**: gates on the task-session-manager's `hasInputWait`
+  and continuation-model seams.
+- **Foreground-fallback**: uses `types.ts` replay helpers
+  (`isReplayableUserMessage`, `partsFromReplayMessage`) and reports
+  retryable/deferred errors to the task-session-manager event router.
+
+### Subdirectories
+
+| Directory | Responsibility |
+|---|---|
+| `apply-patch/` | Structured `apply_patch` parsing, matching, recovery, rewrite pipeline |
+| `auto-update-checker/` | Startup update detection, cache handling, optional install prompt |
+| `cache-monitor/` | Observation-only prompt-cache telemetry watchdog |
+| `deepwork/` | `/deepwork` runtime command |
+| `filter-available-skills/` | Skill-visibility filtering by agent permission policy |
+| `foreground-fallback/` | Interactive-session model fallback on rate-limit/errors |
+| `json-error-recovery/` | Malformed JSON/tool-output recovery helpers |
+| `loop-command/` | `/loop` iterative retry command |
+| `orchestrator-wake/` | Periodic orchestrator wake scheduler + process-global gate |
+| `phase-reminder/` | Message-transform reminder enforcing orchestrator workflow phases |
+| `post-file-tool-nudge/` | Post-read/write reminder nudging delegation-aware next steps |
+| `reflect/` | `/reflect` runtime command |
+| `task-session-manager/` | Resumable task session tracking, job-board injection, reconciliation |
 
 ### Dependencies
-- **OpenCode SDK**: Type definitions for `MessageWithParts`, `MessageInfo`, and hook signatures
-- **Node.js FS Module**: For saving image attachments to disk
-- **Crypto Module**: For generating unique image hashes
-- **Observer Agent**: Disabled agents check prevents image processing when observer is unavailable
 
-### Configuration
-- **Disabled Agents**: Hooks check `disabledAgents` set to skip processing when required agents are unavailable
-- **Workspace Directory**: Images are saved to `.opencode/images/` within the project workspace
+- **OpenCode SDK**: `MessageWithParts`, `MessageInfo`, and hook signature types
+- **Node.js**: `fs`, `crypto` (image attachments, tagged-part hashing)
+- **Utils**: `logger`, `guards`, task parsing, internal-initiator parts
 
 ### Error Handling
-- **File System Errors**: Logged but don't halt processing; hook continues with remaining messages
-- **Collision Handling**: Unique filenames generated via counter suffix when hash collisions occur
-- **Cleanup Failures**: Non-fatal; old images may persist but are periodically cleaned up
+
+- Hooks are best-effort: file-system/transform failures are logged and the
+  hook continues with remaining messages.
+- The cache monitor fails open on any unexpected event shape.
+- The orchestrator-wake scheduler suppresses on SDK errors instead of retrying
+  storming.
 
 ### Performance Considerations
-- **Debounced Cleanup**: Image cleanup runs every 10 minutes per directory to avoid frequent filesystem operations
-- **Session Isolation**: Images organized by sessionID to prevent cross-session contamination
-- **Early Returns**: Hooks return immediately when no relevant messages found (e.g., no images to process)
+
+- **Cache safety**: all injection goes through the tagged/volatile helpers to
+  preserve provider prompt-cache prefixes.
+- **Debounced cleanup**: image cleanup and runtime-status reconciliation run on
+  timers, not per-event.
+- **Bounded state**: cache monitor and wake gate cap tracked sessions; idle
+  reconciliation uses per-session tokens to invalidate stale timers.

+ 13 - 8
src/hooks/foreground-fallback/codemap.md

@@ -2,11 +2,12 @@
 
 ## Responsibility
 Runtime model fallback system for foreground (interactive) agent sessions. When OpenCode emits rate-limit signals via `message.updated`, `session.error`, or `session.status` events, this manager:
-- Detects rate-limit conditions using pattern matching against error messages and status codes
-- Aborts the rate-limited prompt via `client.session.abort()`
+- Detects retryable conditions using pattern matching against error messages and status codes (rate limits, 429, 403/Forbidden, 401/410 failover errors)
+- Aborts the rate-limited prompt via `client.session.abort()` on the `session.status` retry path; `session.error` and `message.updated` paths re-prompt directly without abort
 - Retrieves the last user message from the session history
 - Re-prompts the session with the next available model from the agent's configured fallback chain
 - Operates reactively through the event system (cannot wrap `prompt()` directly for interactive sessions)
+- Defers terminal job-board bookkeeping for inline 401/410 errors while recovery is still possible (cooperates with task-session-manager's `willAttemptFallback`)
 
 ## Design
 
@@ -27,8 +28,8 @@ Runtime model fallback system for foreground (interactive) agent sessions. When
   3. Merged list (last resort) → preserve insertion order across all agents
 - **No cross-agent bleed**: When agent is identified, only that agent's chain is used (prevents re-prompting with wrong agent's models)
 
-### Rate-Limit Detection
-- **Pattern matching**: Comprehensive regex patterns for rate-limit error messages (429, "rate limit", "too many requests", "quota exceeded", etc.)
+### Retryable Error Detection
+- **Pattern matching**: Comprehensive regex patterns for rate-limit error messages (429, "rate limit", "too many requests", "quota exceeded", etc.) plus `isFailoverError` / `isInlineFailoverError` classification for persistent 401/410 provider-model errors
 - **Event coverage**: Handles three OpenCode event types:
   - `message.updated`: Error in message metadata
   - `session.error`: Session-level error event
@@ -47,15 +48,15 @@ OpenCode Event (message.updated/session.error/session.status)
 ForegroundFallbackManager.handleEvent()
-Retryable error detection via isRetryableError()
+Retryable error detection via isRetryableError() / isFailoverError()
 tryFallback(sessionID) [deduplicated, in-progress guarded]
 Resolve fallback chain for session
-Abort current rate-limited prompt (with timeout)
+Abort current rate-limited prompt (session.status retry path only, with timeout)
-Retrieve last user message from session history
+Retrieve last user message from session history (replayed via isReplayableUserMessage/partsFromReplayMessage)
 Re-prompt session with next model via promptAsync()
@@ -69,6 +70,7 @@ Log fallback event
 2. **Message retrieval**: Queries session messages via `client.session.messages()` and finds last user message
 3. **Model switching**: Uses `parseModelReference()` to extract providerID/modelID from chain entry
 4. **Re-prompting**: Calls `promptAsync()` which queues prompt and returns immediately (non-blocking); appends trusted internal-initiator provenance so the replay is not mistaken for new external user input
+5. **Failover deferral**: 401/410 errors (`isFailoverError`) leave terminal job-board bookkeeping to the task-session-manager event router, which defers it while `willAttemptFallback` holds
 
 ## Integration
 
@@ -77,11 +79,14 @@ Log fallback event
 - **Event source**: OpenCode plugin event system provides `message.updated`, `session.error`, `session.status`, `session.deleted` events
 
 ### Dependencies
-- **OpenCode SDK**: `PluginInput['client']` for session management and event handling
+- **OpenCode SDK**: `PluginInput['client']` for session management and event handling (accessed via `getClient()` from `src/utils/opencode-client.ts`)
 - **Utilities**:
   - `abortSessionWithTimeout()`: Graceful session termination
   - `parseModelReference()`: Model string parsing ("providerID/modelID")
+  - `createInternalAgentTextPart()`: Internal-initiator provenance for replays
   - `log()`: Structured logging for observability
+- **SessionLifecycle** (`src/hooks/session-lifecycle.ts`): registers `session.deleted` cleanup
+- **Message types** (`src/hooks/types.ts`): `isReplayableUserMessage` / `partsFromReplayMessage` for safe replay
 - **Configuration**: Fallback chains provided at construction from agent configurations
 
 ### Configuration Schema

+ 97 - 0
src/hooks/orchestrator-wake/codemap.md

@@ -0,0 +1,97 @@
+# src/hooks/orchestrator-wake/
+
+## Responsibility
+
+Periodic orchestrator wake scheduler. After continuous parent-idle time,
+capability-gated host session APIs may receive a static internal wake prompt
+when incomplete TODOs remain (or when a background job stopped without a
+terminal result). Active children do not suppress wakes; host responses are
+authoritative and the local job board is never consulted. Progress/reservation
+state is process-global so independently created hook instances share
+one-flight and the two-wake no-progress cap.
+
+## Design
+
+- **Scheduler** (`index.ts`): `createOrchestratorWakeScheduler(ctx, options)`
+  returns `{ event, observeChatMessage, triggerStoppedJobRecovery, suppress }`.
+  - Tracks per-session local state (`generation` symbol, timer, continuous
+    idle flag) only; progress lives in the process gate.
+  - Gates (`canSchedule`): config enabled, required session APIs present
+    (`get`/`todo`/`children`/`status`/`promptAsync`), managed session,
+    no input wait (`hasInputWait`), no fallback in progress, gate not stopped.
+  - Reads a host snapshot (todos + children + status map + session model) and
+    computes a fingerprint; unchanged fingerprints across wake attempts hit
+    `ORCHESTRATOR_WAKE_UNCHANGED_CAP` (2) and stop.
+  - Wakes via `promptAsync` with a static `<system-reminder>` text
+    (`ORCHESTRATOR_WAKE_TEXT` or `ORCHESTRATOR_STOPPED_JOB_WAKE_TEXT`),
+    reserving the wake before prompt so a failed call cannot storm retries.
+  - `triggerStoppedJobRecovery`: immediate recovery wake for jobs that stopped
+    without a native terminal result (separate from the periodic TODO wake).
+  - `observeChatMessage`: real external user activity rearms the no-progress
+    cap and records the observed model for continuation prompts.
+- **Gate** (`wake-gate.ts`): Process-local reservation/progress store shared
+  via `globalThis` + `Symbol.for` (`oh-my-opencode-slim.orchestrator-wake-gate`):
+  - `tryBeginWakeEvaluation` / `releaseWakeEvaluation` / `retryAfterWakeEvaluation`:
+    single in-flight evaluation per session with waiter re-queueing.
+  - `commitWakeReservation`: marks a committed wake and sets `expectingWakeBusy`
+    so the next busy preserves (not rearms) the no-progress cap.
+  - `noteHostProgress` / `rearmWakeProgress`: fingerprint-unchanged counting
+    and external-activity resets.
+  - `getObservedWakeModel` / `setObservedWakeModel`: last-seen model for
+    continuation prompts.
+  - Bounded at `MAX_TRACKED_SESSIONS` (256) with insertion-ordered eviction.
+
+## Flow
+
+```
+session.idle / session.status(idle)
+    ↓
+beginContinuousIdle() → arm interval timer
+    ↓
+evaluate() (one-flight via gate)
+    ├─ read host snapshot (todo/children/status)
+    ├─ active status? → end idle spell
+    ├─ no incomplete todos (and not recovery)? → end idle spell
+    ├─ fingerprint unchanged ≥ cap? → stop
+    ├─ recheck immediately before promptAsync
+    ├─ commitWakeReservation
+    └─ promptAsync(internal wake reminder)
+    ↓
+busy (wake-initiated) → endIdleSpell(rearm=false)   [cap survives]
+busy (external) / errors / user activity → rearm cap
+```
+
+## Integration
+
+- **Consumer**: `src/index.ts` creates the scheduler and routes `event`,
+  `chat.message` (`observeChatMessage`), `wait_for_user` (`suppress`), and
+  job-stopped recovery triggers to it; config comes from
+  `runtime.backgroundJobs.orchestratorWake` (`{ enabled, intervalMs }`).
+- **Task-session-manager seams**: `hasInputWait` (input-wait-tracker) and
+  `parseContinuationModelSelection` (continuation-model-selection) gate and
+  parameterize wake prompts.
+- **SessionLifecycle**: registers `session.deleted` cleanup via the
+  coordinator.
+- **Dependencies**: `createInternalAgentTextPart` /
+  `isInternalInitiatorPart` (`src/utils/internal-initiator.ts`), `log`,
+  `isRecord`, `SessionLifecycle`, and the task-session-manager status/selection
+  helpers.
+- **Foreground-fallback**: `isFallbackInProgress` suppresses scheduling during
+  fallback cycles.
+
+## Error Handling
+
+- SDK failures during evaluation suppress the wake (reservation already
+  committed), clear the expecting-busy marker, and log; the timer re-arms via
+  the finally block unless stopped.
+- `server.instance.disposed` clears timers, releases owners, and drops pending
+  recovery state.
+- Model enrichment from `session.get` is fail-soft.
+
+## Performance Considerations
+
+- One unref'd timer per continuously-idle managed session; timers are cleared
+  on any busy/error/wait/deletion.
+- All process-global state is bounded and evicted LRU-style.
+- Host snapshot reads are `Promise.all`-parallel and only happen inside the
+  one-flight evaluation.

+ 152 - 61
src/hooks/task-session-manager/codemap.md

@@ -2,28 +2,91 @@
 
 ## Responsibility
 
-Manages V2 background job-board state for task execution and injected completion messages, enabling the orchestrator to track active jobs and reuse only completed, reconciled child sessions by short aliases (e.g., `exp-1`, `ora-2`). The implementation is split into focused submodules to improve separation of concerns and maintainability.
+Manages background job-board state for `task` execution and injected
+completion messages, enabling the orchestrator to track active jobs and reuse
+only completed, reconciled child sessions by short aliases (e.g., `exp-1`,
+`ora-2`). The implementation is split into focused submodules to improve
+separation of concerns and maintainability.
 
 ## Design
 
-The directory follows a **Facade + Strategy** pattern where `index.ts` acts as the facade that composes and orchestrates behavior across specialized strategy modules:
-
-- **index.ts**: Main facade that wires hooks into OpenCode's lifecycle and coordinates between the job board, pending calls, task context tracking, and explicit user waits. Implements the plugin hook interface (`tool.execute.before`, `tool.execute.after`, `experimental.chat.messages.transform`, `event`) and exposes `beginUserWait()` to the `wait_for_user` tool.
-- **stop-confirmation.ts**: Shared 5s grace for idle/absent runtime observations. Transient non-busy evidence stays provisional; confirmed durable stop evidence calls `markStopped` and can wake the parent. Busy/retry/live-busy reset the clock.
-- **input-wait-tracker.ts**: Provides the single `hasInputWait()` seam used by idle reconciliation and continuation evaluation. It combines local question/permission waits with the process-global explicit user-wait latch.
-- **continuation-attempt-gate.ts**: Owns process-global continuation epochs, reservations, and explicit user waits across hook recreation. The wait is encoded as an `attempts` sentinel so pre-upgrade #856 hooks sharing the store also fail closed. Distinct external user-message identity rearms both states.
-- **continuation-model-selection.ts**: Normalizes current-session and chat-hook model shapes before forwarding runtime model and variant choices to idle continuation prompts.
-- **pending-call-tracker.ts**: Tracks in-flight task calls using a capped ordered map (`MAX_PENDING_TASK_CALLS`) to correlate launch output safely. Provides call ID generation, storage, retrieval, and cleanup for pending task invocations.
-- **task-context-tracker.ts**: Manages read context from child sessions with line-count and file caps. Stores context per task ID and provides pruning to prevent unbounded growth.
-
-All modules depend on `BackgroundJobBoard` from `src/utils/background-job-board.ts` as the single source of truth for active jobs, terminal unreconciled jobs, reusable completed sessions, aliases, read context, and LRU caps.
+The directory follows a **Facade + Strategy** pattern where `index.ts` acts as
+the facade that composes and orchestrates behavior across specialized modules:
+
+- **index.ts**: Main facade wiring hooks into OpenCode's lifecycle
+  (`tool.execute.before`, `tool.execute.after`,
+  `experimental.chat.messages.transform`, `event`) and exposing
+  `beginUserWait()`, `hasInputWait()`, and `observeChatMessage()` to the
+  `wait_for_user` tool, orchestrator-wake scheduler, and TUI. Also rehydrates
+  historical running task parts into the board on transform.
+- **board-injection.ts**: Cache-safe injection of Background Job Board state
+  into the message stream via `cache-safe-injection.ts` helpers. Owns
+  `injectBackgroundJobBoard`, injected-completion processing/fences, synthetic
+  terminal part observation, running-task part stabilization (byte-stable
+  running results), and retained board snapshots.
+- **tool-execute-hooks.ts**: `tool.execute.before` (pending call creation,
+  reusable/recoverable `task_id` resolution) and `tool.execute.after` (read
+  context tracking, launch registration/update from task output).
+- **event-router.ts**: Routes lifecycle events (`session.created`,
+  `server.instance.disposed`, `session.idle`, `session.error`,
+  `session.status`, `session.deleted`) to the appropriate subsystems; defers
+  terminal bookkeeping for inline 401/410 errors while foreground-fallback
+  can still recover.
+- **idle-reconciliation.ts**: Delayed idle reconciliation (2s default) for
+  parents and child jobs; child idle is a stop candidate with provisional
+  observations; terminalizes deferred errors and reconciles injected terminal
+  jobs on the backstop path.
+- **runtime-status-reconciliation.ts**: Bounded (5s timeout) live
+  session-status map reads (via `session-runtime-status.ts`) on a 5s delay,
+  feeding the same stop-confirmation policy.
+- **stop-confirmation.ts**: Shared 5s grace for idle/absent runtime
+  observations. Transient non-busy evidence stays provisional; confirmed
+  durable stop evidence calls `markStopped` and can wake the parent.
+  Busy/retry/live-busy reset the clock.
+- **idle-session-tokens.ts**: Per-instance session tokens that invalidate
+  delayed idle-reconciliation timers when the parent becomes busy, errors,
+  waits, or is deleted; real external user messages clear the process-global
+  wait and rearm.
+- **input-wait-tracker.ts**: Provides the single `hasInputWait()` seam used by
+  idle reconciliation, orchestrator wake, and continuation evaluation. Combines
+  local question/permission waits with the process-global explicit user-wait
+  latch.
+- **user-wait-gate.ts**: Process-global `wait_for_user` HITL latch shared via
+  `globalThis` + `Symbol.for` across hook recreation; last-rearm identity
+  (message ID or same-process object) prevents stale releases.
+- **revived-run-tracker.ts**: Tracks revived task runs with notification
+  retries, pending delivery, and a terminal-notification timeout so revived
+  generations surface their completion reliably.
+- **continuation-model-selection.ts**: Normalizes current-session and
+  chat-hook model shapes before forwarding runtime model/variant choices to
+  idle continuation and orchestrator-wake prompts.
+- **status-utils.ts**: Output/status helpers (`extractTaskSummary`,
+  `isActiveStatus`, `isLateCancelledTaskError`,
+  `normalizeLateCancelledTaskOutput`).
+- **pending-call-tracker.ts**: Tracks in-flight task calls using a capped
+  ordered map (`MAX_PENDING_TASK_CALLS`) to correlate launch output safely.
+- **task-context-tracker.ts**: Manages read context from child sessions with
+  line-count and file caps; prunes to prevent unbounded growth.
+
+All modules depend on `BackgroundJobBoard` (`src/utils/background-job-board.ts`)
+as the single source of truth for active jobs, terminal unreconciled jobs,
+reusable completed sessions, aliases, read context, and LRU caps, with
+`background-job-store.ts` / `background-job-coordinator.ts` /
+`background-job-supervisor.ts` providing the atomic store, lifecycle policy,
+and wall-clock supervision.
 
 ### Key Abstractions
 
-- **BackgroundJobBoard**: Central state store for task sessions (active, reusable, terminal unreconciled).
-- **PendingTaskCall**: Tracks in-flight task invocations with call ID, parent session ID, agent type, label, and optional resumed task ID.
-- **ContextFile**: Represents read context from child sessions with path, line numbers, and last-read timestamp.
-- **User wait**: Explicit text-only HITL latch armed by `wait_for_user` and released by a distinct real external user message.
+- **BackgroundJobBoard / BackgroundJobStore**: Central state store for task
+  sessions (active, reusable, terminal unreconciled).
+- **PendingTaskCall**: In-flight task invocation with call ID, parent session
+  ID, agent type, label, and optional resumed task ID.
+- **ContextFile**: Read context from child sessions with path, line numbers,
+  and last-read timestamp.
+- **User wait**: Explicit text-only HITL latch armed by `wait_for_user` and
+  released by a distinct real external user message.
+- **Stop confirmation**: 5s grace distinguishing provisional idle observations
+  from confirmed durable stops.
 
 ## Flow
 
@@ -31,83 +94,111 @@ All modules depend on `BackgroundJobBoard` from `src/utils/background-job-board.
 
 1. **Before Execution (`tool.execute.before`)**
    - Intercepts `task` tool calls on managed sessions
-   - Generates a task label from `description`/`prompt` via `deriveTaskSessionLabel`
-   - Creates a `PendingTaskCall` record with call ID, parent session ID, agent type, and label
-   - Resolves reusable task IDs from the job board; completed/reconciled jobs
-     are reusable by alias, while timed-out running jobs become recoverable
-     only after a live busy signal confirms they are safe to resume
-   - If no reusable task exists, allows fresh task creation
+   - Generates a task label from `description`/`prompt` via
+     `deriveTaskSessionLabel`
+   - Creates a `PendingTaskCall` record; resolves reusable task IDs from the
+     job board (completed/reconciled jobs reusable by alias; timed-out running
+     jobs recoverable only after a live busy signal)
+   - Falls through to fresh task creation when nothing is reusable
 
 2. **Task Launch (`tool.execute.after`)**
-   - Registers task launches in the job board with task ID, parent session ID, agent type, and description
-   - Parses task output to extract task ID, status, or launch information
-   - Adds read context to the job board for completed or terminal unreconciled tasks
-   - Handles late-cancelled tasks by normalizing output and updating state accordingly
+   - Registers launches in the job board with task ID, parent session ID,
+     agent type, and description
+   - Parses task output for task ID/status/launch info; adds read context
+   - Handles late-cancelled tasks by normalizing output and updating state;
+     clears rehydrate tombstones for genuinely new launches
 
 3. **Context Tracking**
-   - Extracts read files from `read` tool outputs using `extractReadFiles`
-   - Stores context per task ID in the task context tracker
-   - Prunes stale context during lifecycle events and status transitions
+   - Extracts read files from `read` tool outputs; stores per task ID; prunes
+     stale context during lifecycle events and status transitions
 
 4. **Message Injection (`experimental.chat.messages.transform`)**
-    - Injects a `<system-reminder>` part containing the `### Background Job Board` section into user messages for managed sessions
-    - Lists active, unreconciled, and reusable sessions
-    - Remembers injected terminal jobs to reconcile them on the next request after the completion was surfaced to the model (via `reconcileConsumedTerminalJobs`)
-    - The idle timer remains a backstop for when the model ends its turn without further requests; after reconciling injected terminal results, the opt-in continuation evaluator can run in the same idle cycle under its existing guards
+   - Stabilizes still-running task tool parts byte-for-byte (cache safety),
+     rehydrates historical running tasks, then injects the `### Background Job
+     Board` section as a tagged synthetic part via `cache-safe-injection.ts`
+   - Remembers injected terminal jobs and reconciles them on the next request
+     after the completion was surfaced to the model
 
 5. **Lifecycle Events (`event`)**
-    - `session.created`: Adds new task IDs to pending managed set
-    - `session.idle` / `session.status` (idle): Reconciles injected terminal jobs for the parent session (backstop path), then can run the opt-in continuation evaluator in the same idle cycle under its existing guards. Child idle is a stop candidate: the first observation stays provisional, and only a confirmed idle/absent after the 5s grace marks `stopped`
-    - `session.status` (busy): Marks sessions as running from live session state and resets pending stop confirmation
-    - `session.deleted`: Clears job state, child jobs, and pending call records for the session
+   - `session.created`: adds new task IDs to pending managed set
+   - `session.idle` / `session.status` (idle): schedules delayed
+     reconciliation; child idle is a stop candidate subject to the 5s grace
+   - `session.status` (busy): marks sessions running and resets pending stop
+     confirmation
+   - `session.error` (401/410): defers terminal bookkeeping while
+     foreground-fallback may still recover
+   - `session.deleted`: clears job state, child jobs, and pending calls
+     (suppression tombstones kept)
 
 6. **Human-in-the-loop Waits**
-   - `wait_for_user` calls the facade's `beginUserWait()` only after tool validation
-   - The shared latch cancels pending continuation timers/reservations
-   - Foreground-fallback replay provenance and shared fallback teardown state preserve the latch across plugin-manager recreation
-   - Idle continuation remains suppressed until a distinct real user message arrives
+   - `wait_for_user` calls the facade's `beginUserWait()` after tool
+     validation; the process-global latch cancels pending continuation and
+     idle work until a distinct real user message arrives
 
 ### Data & Control Flow
 
 ```
 User task call → tool.execute.before → PendingTaskCall created → task ID resolved/reused
 → tool.execute.after → BackgroundJobBoard.registerLaunch() → context extracted/added
-→ Message transform → BackgroundJobBoard.formatForPrompt() injected as a system-reminder message part
-→ session.idle → reconcileInjectedTerminalJobs() → BackgroundJobBoard.markReconciled()
-→ opt-in continuation evaluator (same idle cycle, existing guards)
+→ supervisor.onLaunch() arms wall-clock deadline
+→ Message transform → stabilize running parts → inject board as tagged synthetic part
+→ session.idle → idle-reconciliation (delayed) / runtime-status reconciliation (5s)
+→ stop-confirmation grace → markStopped or busy reset
+→ revived-run-tracker delivers terminal notifications for revived generations
 ```
 
 ## Integration
 
 ### Consumers
 
-- **Main Plugin (`src/index.ts`)**: Wires the task session manager hook into OpenCode's lifecycle via `createTaskSessionManagerHook()`.
+- **Main Plugin (`src/index.ts`)**: wires the hook via
+  `createTaskSessionManagerHook()`; forwards `hasInputWait`,
+  `beginUserWait`, and `observeChatMessage` to the orchestrator-wake
+  scheduler and TUI; shares `BackgroundJobSupervisor` for wall-clock
+  deadlines.
+- **Foreground-fallback**: `isFallbackInProgress` / `willAttemptFallback`
+  guards keep the board from terminalizing sessions mid-fallback.
+- **Orchestrator-wake**: reads `hasInputWait` and continuation-model state.
 
 ### Dependencies
 
-- **BackgroundJobBoard** (`src/utils/background-job-board.ts`): Central state store for task sessions and context.
-- **Task Output Parsing Utilities** (`src/utils/index.ts`): `parseTaskIdFromTaskOutput`, `parseTaskLaunchOutput`, `parseTaskStatusOutput`, `deriveTaskSessionLabel`.
-- **Guards & Logger**: `isRecord` utility and `log` for diagnostics.
+- **BackgroundJobBoard / Store / Coordinator / Supervisor**
+  (`src/utils/`): central state, atomic terminal transitions, lifecycle
+  policy, wall-clock deadlines.
+- **Session runtime status** (`src/utils/session-runtime-status.ts`): bounded
+  live session-status map reads.
+- **Task output parsing** (`src/utils/task.ts`): `parseTaskIdFromTaskOutput`,
+  `parseTaskLaunchOutput`, `parseTaskStatusOutput`, `deriveTaskSessionLabel`.
+- **Cache-safe injection** (`src/hooks/cache-safe-injection.ts`): the only
+  allowed prompt-injection path.
 
 ### Configuration & Caps
 
-- `maxSessionsPerAgent`: Limits reusable sessions per agent type
-- `readContextMinLines`: Minimum lines to include in read context
-- `readContextMaxFiles`: Maximum files to include in read context
-- `shouldManageSession`: Predicate to determine which sessions are managed by this hook
+- `maxSessionsPerAgent`: reusable sessions per agent type
+- `maxRetainedSnapshots`: retained board snapshots for injection rollback
+- `readContextMinLines` / `readContextMaxFiles`: read-context caps
+- `strategy`: `'latest'` or `'checkpoint-compatible'`
+- `orchestratorWake` (in `backgroundJobs`): periodic wake scheduling
+- `wallClockTimeoutMs` / `abortGraceMs`: background job supervision
 
 ### Events & Hooks
 
-- `tool.execute.before` / `tool.execute.after`: Intercept task tool calls and register launches/status
-- `experimental.chat.messages.transform`: Inject background job board status into user messages
-- `event`: Handle session lifecycle events (created, idle, busy, error, deleted)
+- `tool.execute.before` / `tool.execute.after`: intercept task tool calls,
+  register launches/status
+- `experimental.chat.messages.transform`: inject job board state, stabilize
+  running parts, rehydrate historical runs
+- `event`: session lifecycle routing (created, idle, busy, error, deleted,
+  server.instance.disposed)
 
 ## Module Decomposition Rationale
 
 The original monolithic module was split to improve:
-- **Separation of Concerns**: Pending calls, task context, and job board state are now distinct responsibilities.
-- **Testability**: Each module can be tested in isolation with focused contracts.
-- **Maintainability**: Changes to one concern (e.g., context tracking) do not affect unrelated logic.
-- **Scalability**: Capped data structures prevent unbounded memory growth.
-
-Each submodule adheres to the **Single Responsibility Principle** while collaborating through the facade to provide a cohesive user experience.
+- **Separation of Concerns**: injection, reconciliation, wait gating, and
+  revived-run tracking are distinct responsibilities.
+- **Testability**: each module has focused contracts with isolated tests.
+- **Maintainability**: changes to one concern do not affect unrelated logic.
+- **Cache safety**: all prompt injection routes through the cache-safe helpers
+  and is guarded by the cache-safety property/snapshot tests.
+
+Each submodule adheres to the **Single Responsibility Principle** while
+collaborating through the facade to provide a cohesive user experience.

+ 26 - 13
src/interview/codemap.md

@@ -20,21 +20,29 @@
 - `index.ts` exports `createInterviewManager`.
 
 - `runtime.ts` defines the interview-only session boundary (`messages`,
-  `notify`, `continue`, and `rename`). v1 uses nested SDK calls; v2 supplies a
-  context-backed implementation without expanding the global client shim.
+  `notify`, `continue`, and `rename`). v1 uses nested SDK calls
+  (`createV1InterviewSessionRuntime`); v2 supplies a context-backed
+  implementation without expanding the global client shim.
 
 - `manager.ts` (composition root)
-  - Creates `createInterviewService(ctx, interviewConfig)` once.
-  - Chooses mode via
-    `interview.dashboard === true || interview.port > 0`.
-  - In dashboard mode:
-    - calls `tryBecomeDashboard(...)` to elect one process as dashboard,
-    - non-dashboard processes read auth token via `readDashboardAuthFile(port)`,
-    - sessions are registered with `/api/register`, unregister during cleanup via
-      `/api/unregister`, and sync state back via `/api/interviews/{id}/state`,
-    - 10-second fallback polling keeps answer/nudge delivery active if needed.
+  - Chooses mode via `interview.dashboard === true || interview.port > 0`:
+    - per-session mode → `createPerSessionInterviewServer` (`session-server.ts`)
+    - dashboard mode → `createDashboardManager` (`dashboard-manager.ts`)
   - Returns event hooks:
-    `registerCommand`, `handleCommandExecuteBefore`, `handleEvent`.
+    `registerCommand`, `handleCommandExecuteBefore`, `handleEvent`, `dispose`.
+
+- `session-server.ts`
+  - Per-session composition: binds a lazy `createInterviewServer({ port: 0 })`
+    to a single `createInterviewService`, wiring command/event hooks and
+    cleanup.
+
+- `dashboard-manager.ts`
+  - Dashboard composition: creates the dashboard server and service, calls
+    `tryBecomeDashboard(...)` to elect one process as dashboard,
+    non-dashboard processes read auth token via `readDashboardAuthFile(port)`,
+    registers/unregisters sessions over HTTP, and pushes state back via
+    `/api/interviews/{id}/state`; 10-second fallback polling keeps
+    answer/nudge delivery active if needed.
 
 - `createInterviewService` (`service.ts`)
   - Manages interview domain maps:
@@ -59,7 +67,7 @@
     - optional `openBrowser` for initial UI open.
 
 - `createInterviewServer` (`server.ts`)
-  - Owns the per-session HTTP endpoints and HTML renderer binding.
+  - Owns the per-session HTTP endpoints; HTML rendering lives in `ui.ts`.
   - Supports:
     - `GET /`, `GET /api/interviews`, `GET /interview/{id}`
     - `GET /api/interviews/{id}/state`
@@ -67,6 +75,11 @@
     - `POST /api/interviews/{id}/nudge`
   - Maps domain errors to HTTP status in `getSubmissionStatus`.
 
+- `ui.ts`
+  - HTML/JS renderers for interview pages (list/detail), shared
+    client-side helpers (clipboard, polling), and the dashboard brand UI;
+    uses `escapeHtml` from `src/utils/escape-html.ts`.
+
 - `dashboard.ts`
   - Implements a shared dashboard server and state cache.
   - Auth path:

+ 44 - 33
src/tools/codemap.md

@@ -4,12 +4,13 @@
 
 Centralized tool factory and registry for the OpenCode plugin system. This directory defines all executable tools exposed to OpenCode agents, including:
 
-- **Agent orchestration tools**: Multi-LLM council synthesis, background task lifecycle controls, and ACP agent execution
+- **Task lifecycle tools**: Background task communication, cancellation, status (with live-status policy), results, revival, and HITL continuation control
 - **Code intelligence tools**: AST-grep pattern matching and transformation across languages
 - **Web capabilities**: Smart web fetching with caching and secondary model processing
-- **Runtime configuration**: Preset management for dynamic agent configuration switching
+- **ACP integration**: External agent protocol execution
+- **Preset switching**: On-disk preset persistence helpers used by the TUI `/preset` manager
 
-These tools enable agents to perform file operations, orchestrate multi-model consensus, manage background tasks, and interact with external systems while maintaining security boundaries through the OpenCode tool schema.
+These tools enable agents to perform file operations, manage background tasks, and interact with external systems while maintaining security boundaries through the OpenCode tool schema. Multi-LLM council orchestration is agent-level (dynamic `councillor-<name>` subagents in `src/agents/`), not a tool.
 
 ## Design
 
@@ -26,12 +27,12 @@ Each tool is implemented as a factory function that returns a `ToolDefinition` r
 
 | Tool Family | Purpose | Key Components |
 |------------|---------|----------------|
-| **Council** | Multi-LLM consensus synthesis (orchestrator dispatches councillors as subagents) | `agents/council.ts`, `agents/index.ts` |
-| **Task Management** | Background task communication, cancellation, status, results, revival, and HITL continuation control | `task-message.ts`, `cancel-task.ts`, `task-status.ts`, `task-result.ts`, `task-revive.ts`, `wait-for-user.ts`, `background-job-board.ts` |
+| **Task Management** | Background task communication, cancellation, status, results, revival, and HITL continuation control | `task-message.ts`, `cancel-task.ts`, `task-status.ts`, `task-result.ts`, `task-revive.ts`, `wait-for-user.ts` |
+| **Task Policy & Activity** | Shared live-status policy and activity tracking consumed by `task_status` and event wiring | `task-policy.ts` (`summarizeTaskStatus`), `task-activity.ts` (`TaskActivityTracker`) |
 | **ACP Integration** | External agent protocol execution | `acp-run.ts`, ACP client implementation |
 | **Code Intelligence** | AST-based code manipulation | `ast-grep/` directory, `tools.ts` |
 | **Web Fetching** | Intelligent web content retrieval | `smartfetch/` directory, `tool.ts` |
-| **Preset Management** | Runtime agent configuration | `preset-manager.ts`, TUI state integration |
+| **Preset Switching** | On-disk preset persistence for the TUI `/preset` manager | `preset-switch.ts`, TUI state integration |
 
 ### Security & Validation
 
@@ -42,9 +43,8 @@ Each tool is implemented as a factory function that returns a `ToolDefinition` r
 
 ### State Management
 
-- **Runtime Presets**: Preset state persists across plugin reloads via `RuntimeConfig` (`src/config/runtime.ts`)
-- **TUI Integration**: Preset changes persist to the config file only; the sidebar is NOT refreshed mid-session (the agent registry is unchanged until reload) — hot-swapping the agent tree during an active conversation risks context truncation, drifted prior turns, and stale subagent references
-- **Background Jobs**: Task communication, cancellation, status, results, and revival use a centralized job board for tracking and lifecycle coordination
+- **Runtime Presets**: Preset switching (`preset-switch.ts`) persists the preset name to the user config file; the sidebar is NOT refreshed mid-session (the agent registry is unchanged until reload) — hot-swapping the agent tree during an active conversation risks context truncation, drifted prior turns, and stale subagent references
+- **Background Jobs**: Task communication, cancellation, status, results, and revival use a centralized job board for tracking and lifecycle coordination; `task_status` reports live-confirmed host status with explicit uncertainty when the live read is unavailable
 
 ## Flow
 
@@ -99,11 +99,23 @@ Each tool is implemented as a factory function that returns a `ToolDefinition` r
 1. Orchestrator gives the user concrete manual steps
    └─> Invokes wait_for_user as its final tool action
        ├─> Validates session ID, agent identity, and managed-session ownership
-       ├─> Arms task-session-manager.beginUserWait()
+       ├─> Arms task-session-manager.beginUserWait() (process-global latch)
        ├─> Revokes pending automatic-continuation reservations
        └─> Returns the versioned waiting_for_user protocol marker
 ```
 
+### Task Status Policy Flow
+
+```
+1. Agent invokes task_status
+   ├─> Resolves task_id to a BackgroundJobBoard entry
+   ├─> Reads the bounded live session-status snapshot (session-runtime-status)
+   ├─> summarizeTaskStatus() (task-policy.ts) prefers the live-confirmed host
+   │   status; board state is only reported with explicit uncertainty
+   └─> possibly_stuck requires a live-confirmed busy/retry signal beyond the
+       STUCK_IDLE_THRESHOLD_MS idle threshold
+```
+
 ### ACP Agent Execution Flow
 
 ```
@@ -150,13 +162,12 @@ Each tool is implemented as a factory function that returns a `ToolDefinition` r
   - `getToolDefinitions()` - Composes tool set for plugin initialization
   
 - **Agents** (`src/agents/`):
-  - Orchestrator dispatches councillors as subagents
-  - Council agent synthesizes councillor responses
+  - Orchestrator dispatches councillors as subagents (agent-level, not a tool)
   - Individual agents use `acp_run` tool for specialized tasks
   - All agents use `ast_grep_search`/`ast_grep_replace` for code manipulation
 
-- **CLI** (`src/cli/`):
-  - Preset manager integrates with `/preset` command
+- **TUI** (`src/tui-preset.ts`):
+  - `/preset` manager uses `switchPresetOnDisk` / `writePreset` / `deletePreset` from `preset-switch.ts`
   - Tool factories receive CLI configuration for ACP agents
 
 ### Dependencies
@@ -164,8 +175,8 @@ Each tool is implemented as a factory function that returns a `ToolDefinition` r
 | Dependency | Purpose |
 |------------|---------|
 | `@opencode-ai/plugin` | Tool schema and execution framework |
-| `Council Config` (`src/config/council-schema.ts`) | Councillor model/preset definitions |
 | `BackgroundJobBoard` (`src/utils/`) | Background task tracking and cleanup |
+| `Session Runtime Status` (`src/utils/session-runtime-status.ts`) | Bounded live session-status reads for `task_status` |
 | `Config System` (`src/config/`) | ACP agent configurations and presets |
 | `TUI State` (`src/tui-state.ts`) | Preset visualization in terminal UI |
 | `AST-grep CLI` | Pattern matching and transformation engine |
@@ -178,12 +189,13 @@ Tools Layer → Background Layer
 ├─ task_cancel → BackgroundJobBoard.resolve() → abortSessionWithTimeout()
 ├─ task_message → BackgroundJobBoard.resolve() → no-reply prompt transport
 ├─ task_revive → BackgroundJobBoard.resolve() → retained-session relaunch
-└─> Returns lifecycle or transport status
+├─ task_status → BackgroundJobBoard.resolve() → live session-status snapshot
+└─> Returns lifecycle, transport, or status report
 
 Tools Layer → Config Layer
 ├─ acp_run tool → AcpAgentsConfig from config system
-├─ preset-manager → Preset configurations from plugin config
-└─> Validates and applies runtime configuration
+├─ preset-switch → reads/writes the user config file's `presets`/`preset` fields
+└─> Validates and persists preset state
 
 Tools Layer → AST-grep Layer
 ├─ ast_grep_search/ast_grep_replace → CLI binary execution
@@ -196,8 +208,8 @@ Tools Layer → Web Layer
 ### Configuration Integration
 
 - **ACP Agents**: Defined in `src/config/agents.ts`, consumed by `acp_run.ts`
-- **Presets**: Defined in plugin config (`oh-my-opencode-slim.jsonc`), managed by `preset-manager.ts`
-- **Council**: Configured via council presets, validated by `council.ts`
+- **Presets**: Defined in plugin config (`oh-my-opencode-slim.jsonc`), persisted by `preset-switch.ts` for the TUI `/preset` manager
+- **Task Status**: `task-status.ts` consumes `summarizeTaskStatus` from `task-policy.ts` and the live session-status snapshot
 
 
 ### Error Handling & Recovery
@@ -213,9 +225,10 @@ Tools Layer → Web Layer
 ### Exported Tools (src/tools/index.ts)
 
 ```typescript
-// AST-grep tools
+// ACP / code intelligence / web
 export { createAcpRunTool } from './acp-run';
 export { ast_grep_replace, ast_grep_search } from './ast-grep';
+export { createWebfetchTool } from './smartfetch';
 
 // Task management
 export { createCancelTaskTool } from './cancel-task';
@@ -224,15 +237,13 @@ export { createTaskResultTool } from './task-result';
 export { createTaskReviveTool } from './task-revive';
 export { createTaskStatusTool } from './task-status';
 export { createWaitForUserTool } from './wait-for-user';
-
-// Preset management
-export type { PresetManager } from './preset-manager';
-export { createPresetManager } from './preset-manager';
-
-// Web fetching
-export { createWebfetchTool } from './smartfetch';
 ```
 
+Preset switching is not a tool: `preset-switch.ts` exposes on-disk helpers
+(`switchPresetOnDisk`, `writePreset`, `deletePreset`, `setAgentOverride`,
+`removeAgentFromPreset`) consumed by the TUI `/preset` manager
+(`src/tui-preset.ts`).
+
 ### Tool-Specific Configuration
 
 
@@ -241,15 +252,15 @@ export { createWebfetchTool } from './smartfetch';
 - Each agent requires: `command`, `args`, `cwd`, `permissionMode`
 - Supports: `ask` (prompt user), `reject` (auto-deny), `allow` (auto-approve)
 
-#### Council Sessions
+#### Council Sessions (agent-level, not a tool)
 - Configured via council presets in plugin config
-- Orchestrator dispatches each councillor as a prefixed subagent (`councillor-<name>`)
-- Council agent synthesizes responses into a consensus report
+- `src/agents/council-agents.ts` builds a prefixed `councillor-<name>` subagent per preset seat
+- Orchestrator dispatches each councillor as a subagent; the council agent synthesizes responses into a consensus report
 
-#### Presets (preset-manager.ts)
+#### Presets (preset-switch.ts)
 - Defined in plugin config under `presets` field
 - Each preset maps agent names to `AgentOverrideConfig`
-- Changes persist across plugin reloads via user config file
+- `switchPresetOnDisk` persists the preset name to the user config file; changes take effect on the next reload
 
 #### AST-grep (ast-grep/)
 - Auto-downloads CLI binary on first use

+ 56 - 7
src/utils/codemap.md

@@ -3,13 +3,15 @@
 ## Responsibility
 
 Centralized utilities and shared abstractions used across the oh-my-opencode-slim plugin. This folder provides:
-- Background job lifecycle management via BackgroundJobBoard
+- Background job lifecycle management (board + store + coordinator + supervisor)
+- Live session-status reads and session metadata tracking
+- In-process opencode client access and client call-shape contracts
 - Environment and configuration utilities
 - Type guards and validation helpers
 - Session and timeout utilities for council dispatch
 - Logging infrastructure with automatic rotation
 - Task output parsing utilities
-- System message utilities
+- System message utilities, agent-variant/model helpers, and platform compat
 
 ## Design
 
@@ -17,7 +19,19 @@ Centralized utilities and shared abstractions used across the oh-my-opencode-sli
 
 - **BackgroundJobBoard** (`background-job-board.ts`): Singleton registry and lifecycle manager for background tasks spawned by sub-agents. Implements a reusable session pool pattern with automatic cleanup and reconciliation hooks. Tracks task state (running, stopped, completed, error, cancelled), maintains context files, and provides prompt-ready summaries for agent coordination. `stopped` records an ended runtime session without fabricated task success and is never reusable. Idle/absent observations start a 5s stop-confirmation grace (`stopConfirmationStartedAt`); live busy resets it. After a confirmed stop has been acknowledged, stale busy cannot reopen the job.
 
-- **Runtime Session Status** (`session-runtime-status.ts`): Reads and validates the in-process OpenCode session-status map once per observation. It distinguishes a valid absent session (`idle`) from malformed data or lookup failure (`unknown`) so lifecycle policy never treats schema drift as completion.
+- **BackgroundJobStore** (`background-job-store.ts`): Atomic state-store contract (terminal transitions, leases, wall-clock deadline claims) implemented by the board; the single terminal-publication boundary.
+
+- **BackgroundJobCoordinator** (`background-job-coordinator.ts`): Lifecycle policy layer between the board and its consumers — terminal-state subscriptions (replaces fire-and-forget), deferred-close policy, and prompt-metadata shaping.
+
+- **BackgroundJobSupervisor** (`background-job-supervisor.ts`): One-shot wall-clock deadline supervision for background task runs: deadline timer → abort → grace timer → terminal finalization. Owns only timer/generation/abort mechanics.
+
+- **Runtime Session Status** (`session-runtime-status.ts`): Reads and validates the in-process OpenCode session-status map once per observation (5s bounded timeout). It distinguishes a valid absent session (`idle`) from malformed data or lookup failure (`unknown`) so lifecycle policy never treats schema drift as completion.
+
+- **Session Metadata** (`session-metadata.ts`): `SessionMetadataStore` — bounded session → agent/directory map with LRU eviction that never evicts active orchestrator sessions.
+
+- **Opencode Client** (`opencode-client.ts`): `getClient(input)` returns the in-process host client (no loopback HTTP, no caching).
+
+- **Session Calls Contract** (`session-calls.contract.ts`): Type-only compile-time contract pinning the nested `{ path, query, body }` client call shapes and asserting the v2-flat shapes are rejected; compiled by `bun run typecheck`.
 
 - **Logger** (`logger.ts`): File-based logging with 7-day retention, automatic directory creation, and write queuing. Logs are written to `~/.local/share/opencode/log/oh-my-opencode-slim.<sessionId>.log` and cleaned up on initialization.
 
@@ -33,6 +47,16 @@ Centralized utilities and shared abstractions used across the oh-my-opencode-sli
 
 - **System Collapse** (`system-collapse.ts`): Utility for collapsing multiple system messages into a single entry by joining with double-newlines.
 
+- **Agent Variant** (`agent-variant.ts`): `normalizeAgentName` (`@`-strip/trim) and `escapeRegExp` for display-name rewriting.
+
+- **Councillor Models** (`councillor-models.ts`): Pure helpers resolving councillor model fallback chains without pulling zod/schema into runtime consumers.
+
+- **Polling** (`polling.ts`): Generic `poll()` helper with interval/max-time/stable-threshold/abort options.
+
+- **Compat & Zip** (`compat.ts`, `zip-extractor.ts`): `crossSpawn` (cross-platform spawn with stdout/stderr collection) and `extractZip` (Windows-aware tar/pwsh fallbacks).
+
+- **Misc** (`escape-html.ts`, `frontmatter.ts`): HTML escaping (interview UI) and frontmatter parsing (interview documents).
+
 ### Design Patterns
 
 - **Singleton**: BackgroundJobBoard is a singleton registry with global state for all background tasks
@@ -43,11 +67,12 @@ Centralized utilities and shared abstractions used across the oh-my-opencode-sli
 ## Flow
 
 ### Background Job Lifecycle
-1. Agent launches a background task via BackgroundJobBoard.registerLaunch()
+1. Agent launches a background task via BackgroundJobBoard.registerLaunch() (supervisor arms the wall-clock deadline)
 2. Task runs and updates status via BackgroundJobBoard.updateStatus()
-3. On completion/error/cancellation, task is marked terminal and added to reusable pool
+3. On completion/error/cancellation, task is marked terminal and added to reusable pool; supervisor timers are cleared
 4. Subsequent tasks from same agent/session can reuse completed sessions via aliases
 5. Unused reusable sessions are automatically trimmed based on maxReusablePerAgent
+6. A deadline exceeded while running → coordinator claims it, supervisor aborts the session, and a grace timer finalizes the terminal state
 
 ### Logging Flow
 1. Plugin initializes logger with session ID via initLogger(sessionId)
@@ -90,25 +115,49 @@ Centralized utilities and shared abstractions used across the oh-my-opencode-sli
 
 `src/utils/index.ts` re-exports all utilities, providing a single entry point:
 ```typescript
+export * from './agent-variant';
 export * from './background-job-board';
+export * from './background-job-coordinator';
+export * from './background-job-store';
+export * from './background-job-supervisor';
 export * from './internal-initiator';
-export { getLogDir, initLogger, log } from './logger';
+export { initLogger, log } from './logger';
+export * from './polling';
 export * from './session';
+export * from './session-runtime-status';
 export * from './task';
+export { extractZip } from './zip-extractor';
 ```
 
 This allows consumers to import from `src/utils` rather than individual files.
+Session metadata, the opencode client accessor, and the type-only call-shape
+contract are intentionally imported directly from their modules (not
+re-exported).
 
 ## Files
 
 | File | Purpose |
 |------|---------|
-| `index.ts` | Public API re-exporting all utilities |
+| `index.ts` | Public API re-exporting most utilities |
+| `agent-variant.ts` | Agent name normalization and regex escaping |
 | `background-job-board.ts` | Background task registry and lifecycle manager |
+| `background-job-coordinator.ts` | Lifecycle policy and terminal-state subscriptions |
+| `background-job-store.ts` | Atomic store contract and terminal transitions |
+| `background-job-supervisor.ts` | Wall-clock deadline supervision and abort grace |
+| `compat.ts` | Cross-platform spawn with output collection |
+| `councillor-models.ts` | Councillor model fallback chain helpers |
 | `env.ts` | Environment variable utilities |
+| `escape-html.ts` | HTML escaping helper |
+| `frontmatter.ts` | Frontmatter parsing for interview documents |
 | `guards.ts` | Type guard utilities |
 | `internal-initiator.ts` | Internal agent message marker system |
 | `logger.ts` | File-based logging with rotation |
+| `opencode-client.ts` | In-process host client accessor |
+| `polling.ts` | Generic poll helper |
+| `session-calls.contract.ts` | Compile-time client call-shape contract (type-only) |
+| `session-metadata.ts` | Bounded session → agent/directory store |
+| `session-runtime-status.ts` | Bounded live session-status map reads |
 | `session.ts` | Session timeout, abort, and extraction utilities |
 | `system-collapse.ts` | System message collapsing utility |
 | `task.ts` | Task output parsing utilities |
+| `zip-extractor.ts` | Cross-platform zip extraction |