eawf 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (538) hide show
  1. eawf/__init__.py +5 -0
  2. eawf/__main__.py +4 -0
  3. eawf/_data/service_templates/dev.eawf.eawfd.plist.j2 +26 -0
  4. eawf/_data/service_templates/eawfd.service.j2 +14 -0
  5. eawf/_version.py +22 -0
  6. eawf/kernel/__init__.py +12 -0
  7. eawf/kernel/config/__init__.py +26 -0
  8. eawf/kernel/config/defaults.py +416 -0
  9. eawf/kernel/config/layered.py +538 -0
  10. eawf/kernel/config/loader.py +70 -0
  11. eawf/kernel/config/migration.py +374 -0
  12. eawf/kernel/config/profile.py +237 -0
  13. eawf/kernel/config/registry/__init__.py +63 -0
  14. eawf/kernel/config/registry/coercion.py +195 -0
  15. eawf/kernel/config/registry/config_keys.py +508 -0
  16. eawf/kernel/config/registry/leaf_catalog.py +1366 -0
  17. eawf/kernel/config/registry/leaf_keys.py +121 -0
  18. eawf/kernel/migrations/__init__.py +49 -0
  19. eawf/kernel/migrations/_base.py +510 -0
  20. eawf/kernel/migrations/v1_0_to_v1_1.py +259 -0
  21. eawf/kernel/spec/__init__.py +90 -0
  22. eawf/kernel/spec/audit.py +64 -0
  23. eawf/kernel/spec/cache.py +194 -0
  24. eawf/kernel/spec/common.py +104 -0
  25. eawf/kernel/spec/heuristics.py +117 -0
  26. eawf/kernel/spec/iter.py +74 -0
  27. eawf/kernel/spec/phase.py +97 -0
  28. eawf/kernel/spec/validators.py +165 -0
  29. eawf/kernel/spec/wave.py +144 -0
  30. eawf/kernel/spec/writer.py +288 -0
  31. eawf/kernel/state/__init__.py +3 -0
  32. eawf/kernel/state/enums.py +406 -0
  33. eawf/kernel/state/ids.py +144 -0
  34. eawf/kernel/state/io.py +368 -0
  35. eawf/kernel/state/migration.py +133 -0
  36. eawf/kernel/state/models.py +646 -0
  37. eawf/kernel/state/mutations.py +99 -0
  38. eawf/kernel/state/resolve.py +67 -0
  39. eawf/kernel/state/types.py +19 -0
  40. eawf/kernel/state/urn.py +150 -0
  41. eawf/kernel/state/wave_graph.py +198 -0
  42. eawf/kernel/state/writer.py +81 -0
  43. eawf/kernel/store/__init__.py +36 -0
  44. eawf/kernel/store/append.py +54 -0
  45. eawf/kernel/store/compact.py +101 -0
  46. eawf/kernel/store/envelope.py +38 -0
  47. eawf/kernel/store/kinds/__init__.py +45 -0
  48. eawf/kernel/store/kinds/actual.py +41 -0
  49. eawf/kernel/store/kinds/agent_report.py +283 -0
  50. eawf/kernel/store/kinds/audit.py +28 -0
  51. eawf/kernel/store/kinds/config_updated.py +42 -0
  52. eawf/kernel/store/kinds/decision.py +16 -0
  53. eawf/kernel/store/kinds/estimate.py +27 -0
  54. eawf/kernel/store/kinds/event.py +166 -0
  55. eawf/kernel/store/kinds/events/__init__.py +92 -0
  56. eawf/kernel/store/kinds/events/base.py +54 -0
  57. eawf/kernel/store/kinds/events/cache_mislayer.py +62 -0
  58. eawf/kernel/store/kinds/events/dispatch_cost.py +55 -0
  59. eawf/kernel/store/kinds/events/runtime_switched.py +52 -0
  60. eawf/kernel/store/kinds/events/session_continued.py +44 -0
  61. eawf/kernel/store/kinds/events/session_failover.py +46 -0
  62. eawf/kernel/store/kinds/flow.py +130 -0
  63. eawf/kernel/store/kinds/incident.py +29 -0
  64. eawf/kernel/store/kinds/memory.py +35 -0
  65. eawf/kernel/store/kinds/registry_updated.py +37 -0
  66. eawf/kernel/store/kinds/research.py +46 -0
  67. eawf/kernel/store/kinds/spec_updated.py +48 -0
  68. eawf/kernel/store/kinds/subscription_lag.py +34 -0
  69. eawf/kernel/store/paths.py +42 -0
  70. eawf/kernel/validate/__init__.py +27 -0
  71. eawf/kernel/validate/invariants.py +964 -0
  72. eawf/kernel/validate/strict.py +241 -0
  73. eawf/observability/__init__.py +14 -0
  74. eawf/observability/bench/__init__.py +52 -0
  75. eawf/observability/bench/harness.py +345 -0
  76. eawf/observability/bench/seed.py +243 -0
  77. eawf/observability/doctor/__init__.py +0 -0
  78. eawf/observability/doctor/checks.py +536 -0
  79. eawf/observability/doctor/doc_verify.py +148 -0
  80. eawf/observability/doctor/report.py +73 -0
  81. eawf/observability/eval/__init__.py +20 -0
  82. eawf/observability/eval/models.py +41 -0
  83. eawf/observability/eval/score.py +165 -0
  84. eawf/observability/logging/__init__.py +16 -0
  85. eawf/observability/logging/scrub.py +220 -0
  86. eawf/observability/telemetry/_AGENT_LENS_AUDIT_COMMIT.txt +45 -0
  87. eawf/observability/telemetry/__init__.py +14 -0
  88. eawf/observability/telemetry/aggregator.py +365 -0
  89. eawf/observability/telemetry/exporter.py +445 -0
  90. eawf/observability/telemetry/models.py +241 -0
  91. eawf/observability/telemetry/pricing.py +305 -0
  92. eawf/observability/telemetry/projector.py +469 -0
  93. eawf/observability/telemetry/sources/__init__.py +35 -0
  94. eawf/observability/telemetry/sources/base.py +65 -0
  95. eawf/observability/telemetry/sources/claude_session.py +228 -0
  96. eawf/observability/telemetry/sources/codex_session.py +236 -0
  97. eawf/observability/telemetry/sources/event_jsonl.py +92 -0
  98. eawf/observability/telemetry/sources/opencode_session.py +265 -0
  99. eawf/observability/telemetry/store/__init__.py +42 -0
  100. eawf/observability/telemetry/store/base.py +407 -0
  101. eawf/observability/telemetry/store/duckdb_store.py +111 -0
  102. eawf/observability/telemetry/store/sqlite_store.py +51 -0
  103. eawf/platform/__init__.py +18 -0
  104. eawf/platform/artifacts/__init__.py +19 -0
  105. eawf/platform/artifacts/references.py +109 -0
  106. eawf/platform/artifacts/validation.py +198 -0
  107. eawf/platform/backup/__init__.py +39 -0
  108. eawf/platform/backup/service.py +180 -0
  109. eawf/platform/backup/store.py +401 -0
  110. eawf/platform/docs/__init__.py +12 -0
  111. eawf/platform/docs/autogen.py +570 -0
  112. eawf/platform/install/__init__.py +0 -0
  113. eawf/platform/install/instrument_probe.py +361 -0
  114. eawf/platform/install/steps.py +244 -0
  115. eawf/platform/install/wizard.py +717 -0
  116. eawf/platform/lint/__init__.py +76 -0
  117. eawf/platform/lint/_conditional.py +187 -0
  118. eawf/platform/lint/eawf001.py +200 -0
  119. eawf/platform/lint/eawf002.py +182 -0
  120. eawf/platform/lint/eawf003.py +129 -0
  121. eawf/platform/lint/eawf010.py +168 -0
  122. eawf/platform/lint/eawf011.py +296 -0
  123. eawf/platform/memory/__init__.py +9 -0
  124. eawf/platform/memory/gc.py +149 -0
  125. eawf/platform/memory/markdown_view.py +230 -0
  126. eawf/platform/memory/promotion.py +363 -0
  127. eawf/platform/memory/prune.py +189 -0
  128. eawf/platform/memory/render_context.py +183 -0
  129. eawf/platform/memory/staleness.py +89 -0
  130. eawf/platform/memory/store.py +178 -0
  131. eawf/platform/profiles/__init__.py +74 -0
  132. eawf/platform/profiles/compose.py +537 -0
  133. eawf/platform/profiles/data/a11y.yaml +3 -0
  134. eawf/platform/profiles/data/agent_driven.yaml +110 -0
  135. eawf/platform/profiles/data/apps.yaml +27 -0
  136. eawf/platform/profiles/data/core.yaml +730 -0
  137. eawf/platform/profiles/data/docs.yaml +3 -0
  138. eawf/platform/profiles/data/game.yaml +3 -0
  139. eawf/platform/profiles/data/infra.yaml +27 -0
  140. eawf/platform/profiles/data/ml.yaml +34 -0
  141. eawf/platform/profiles/data/python.yaml +65 -0
  142. eawf/platform/profiles/data/quality.yaml +97 -0
  143. eawf/platform/profiles/data/quant.yaml +33 -0
  144. eawf/platform/profiles/data/re.yaml +3 -0
  145. eawf/platform/profiles/data/research.yaml +27 -0
  146. eawf/platform/profiles/data/robotics.yaml +3 -0
  147. eawf/platform/profiles/discovery.py +299 -0
  148. eawf/platform/profiles/loader.py +127 -0
  149. eawf/platform/profiles/models.py +225 -0
  150. eawf/platform/profiles/trust.py +180 -0
  151. eawf/platform/registry/__init__.py +61 -0
  152. eawf/platform/registry/models.py +232 -0
  153. eawf/platform/registry/staleness.py +178 -0
  154. eawf/platform/scrub/__init__.py +7 -0
  155. eawf/platform/scrub/scan.py +94 -0
  156. eawf/platform/templates/AGENTS.md.j2 +42 -0
  157. eawf/platform/templates/CLAUDE.md.j2 +1 -0
  158. eawf/platform/templates/__init__.py +15 -0
  159. eawf/platform/templates/claude/SKILL.md.j2 +14 -0
  160. eawf/platform/templates/claude/__init__.py +17 -0
  161. eawf/platform/templates/claude/agent.md.j2 +17 -0
  162. eawf/platform/templates/claude/hook.sh.j2 +37 -0
  163. eawf/platform/templates/claude/marketplace.json.j2 +13 -0
  164. eawf/platform/templates/claude/plugin-readme.md.j2 +48 -0
  165. eawf/platform/templates/claude/plugin.json.j2 +27 -0
  166. eawf/platform/templates/claude/settings.json.fragment.j2 +42 -0
  167. eawf/platform/templates/init/__init__.py +21 -0
  168. eawf/platform/templates/init/engineering.yaml +31 -0
  169. eawf/platform/templates/init/research.yaml +27 -0
  170. eawf/platform/templates/init/reverse-engineering.yaml +32 -0
  171. eawf/platform/templates/themes.yaml +72 -0
  172. eawf/py.typed +0 -0
  173. eawf/runtime/__init__.py +18 -0
  174. eawf/runtime/budget/__init__.py +63 -0
  175. eawf/runtime/budget/policy.py +193 -0
  176. eawf/runtime/budget/service.py +249 -0
  177. eawf/runtime/ci_loop/__init__.py +46 -0
  178. eawf/runtime/ci_loop/parser.py +254 -0
  179. eawf/runtime/ci_loop/policy.py +80 -0
  180. eawf/runtime/daemon/__init__.py +7 -0
  181. eawf/runtime/daemon/auth.py +440 -0
  182. eawf/runtime/daemon/bus.py +347 -0
  183. eawf/runtime/daemon/dispatch_runner.py +761 -0
  184. eawf/runtime/daemon/idle.py +109 -0
  185. eawf/runtime/daemon/main.py +404 -0
  186. eawf/runtime/daemon/methods/__init__.py +192 -0
  187. eawf/runtime/daemon/methods/agent.py +567 -0
  188. eawf/runtime/daemon/methods/config.py +736 -0
  189. eawf/runtime/daemon/methods/daemon.py +169 -0
  190. eawf/runtime/daemon/methods/event.py +261 -0
  191. eawf/runtime/daemon/methods/registry.py +440 -0
  192. eawf/runtime/daemon/methods/spec.py +711 -0
  193. eawf/runtime/daemon/methods/state.py +906 -0
  194. eawf/runtime/daemon/methods/state_subscribe.py +54 -0
  195. eawf/runtime/daemon/methods/wal_admin.py +182 -0
  196. eawf/runtime/daemon/recovery.py +222 -0
  197. eawf/runtime/daemon/runtime_dir.py +125 -0
  198. eawf/runtime/daemon/server.py +473 -0
  199. eawf/runtime/daemon/service_install.py +617 -0
  200. eawf/runtime/daemon/session.py +184 -0
  201. eawf/runtime/daemon/session_ttl.py +259 -0
  202. eawf/runtime/daemon/spawn.py +351 -0
  203. eawf/runtime/daemon/wal.py +385 -0
  204. eawf/runtime/daemon/win_service.py +181 -0
  205. eawf/runtime/daemon/windows_pipe.py +313 -0
  206. eawf/runtime/daemon/windows_security.py +151 -0
  207. eawf/runtime/hooks/__init__.py +33 -0
  208. eawf/runtime/hooks/event.py +101 -0
  209. eawf/runtime/hooks/runner.py +304 -0
  210. eawf/runtime/lock/__init__.py +1 -0
  211. eawf/runtime/lock/portalock.py +172 -0
  212. eawf/runtime/lock/sibling.py +23 -0
  213. eawf/runtime/lock/stale.py +74 -0
  214. eawf/runtime/mcp/__init__.py +56 -0
  215. eawf/runtime/mcp/catalog.py +56 -0
  216. eawf/runtime/mcp/env_ref.py +127 -0
  217. eawf/runtime/mcp/installer.py +844 -0
  218. eawf/runtime/runtimes/__init__.py +13 -0
  219. eawf/runtime/runtimes/adapter.py +311 -0
  220. eawf/runtime/runtimes/cache_control.py +246 -0
  221. eawf/runtime/runtimes/capabilities.py +557 -0
  222. eawf/runtime/runtimes/capabilities.yaml +113 -0
  223. eawf/runtime/runtimes/claude/__init__.py +25 -0
  224. eawf/runtime/runtimes/claude/adapter.py +179 -0
  225. eawf/runtime/runtimes/claude/hook_map.py +148 -0
  226. eawf/runtime/runtimes/claude/hooks_router.py +167 -0
  227. eawf/runtime/runtimes/claude/plugin_conflict.py +72 -0
  228. eawf/runtime/runtimes/claude/plugin_doctor.py +331 -0
  229. eawf/runtime/runtimes/claude/plugin_install.py +537 -0
  230. eawf/runtime/runtimes/claude/plugin_package.py +542 -0
  231. eawf/runtime/runtimes/claude/plugin_update.py +80 -0
  232. eawf/runtime/runtimes/claude/statusline.py +291 -0
  233. eawf/runtime/runtimes/claude/statusline_modules/__init__.py +16 -0
  234. eawf/runtime/runtimes/claude/statusline_modules/context_tokens.py +77 -0
  235. eawf/runtime/runtimes/claude/statusline_modules/git.py +102 -0
  236. eawf/runtime/runtimes/claude/statusline_modules/hooks_plugins.py +103 -0
  237. eawf/runtime/runtimes/claude/statusline_modules/mcp_health.py +80 -0
  238. eawf/runtime/runtimes/claude/statusline_modules/memory.py +85 -0
  239. eawf/runtime/runtimes/claude/statusline_modules/model_session_cwd.py +93 -0
  240. eawf/runtime/runtimes/claude/statusline_modules/state.py +83 -0
  241. eawf/runtime/runtimes/claude/statusline_modules/token_saving.py +86 -0
  242. eawf/runtime/runtimes/coauthor.py +157 -0
  243. eawf/runtime/runtimes/codex/__init__.py +43 -0
  244. eawf/runtime/runtimes/codex/adapter.py +159 -0
  245. eawf/runtime/runtimes/codex/hook_map.py +23 -0
  246. eawf/runtime/runtimes/codex/plugin_conflict.py +62 -0
  247. eawf/runtime/runtimes/codex/plugin_doctor.py +227 -0
  248. eawf/runtime/runtimes/codex/plugin_install.py +477 -0
  249. eawf/runtime/runtimes/codex/plugin_package.py +267 -0
  250. eawf/runtime/runtimes/dispatch.py +261 -0
  251. eawf/runtime/runtimes/fallback.py +221 -0
  252. eawf/runtime/runtimes/helpers/__init__.py +70 -0
  253. eawf/runtime/runtimes/helpers/fs.py +78 -0
  254. eawf/runtime/runtimes/helpers/json_canonical.py +85 -0
  255. eawf/runtime/runtimes/helpers/sidecar.py +60 -0
  256. eawf/runtime/runtimes/manifest.py +147 -0
  257. eawf/runtime/runtimes/opencode/__init__.py +39 -0
  258. eawf/runtime/runtimes/opencode/adapter.py +174 -0
  259. eawf/runtime/runtimes/opencode/plugin_conflict.py +80 -0
  260. eawf/runtime/runtimes/opencode/plugin_doctor.py +282 -0
  261. eawf/runtime/runtimes/opencode/plugin_install.py +560 -0
  262. eawf/runtime/runtimes/opencode/templates/__init__.py +1 -0
  263. eawf/runtime/runtimes/opencode/templates/plugin.js +48 -0
  264. eawf/runtime/runtimes/plugin_doctor.py +505 -0
  265. eawf/runtime/runtimes/plugin_manifest.py +111 -0
  266. eawf/runtime/runtimes/plugin_sync.py +332 -0
  267. eawf/runtime/runtimes/probes/__init__.py +15 -0
  268. eawf/runtime/runtimes/probes/sdk_baseline.py +394 -0
  269. eawf/runtime/runtimes/selector.py +138 -0
  270. eawf/runtime/sandbox/__init__.py +0 -0
  271. eawf/runtime/sandbox/policy.py +114 -0
  272. eawf/runtime/session/__init__.py +8 -0
  273. eawf/runtime/session/recovery.py +124 -0
  274. eawf/runtime/session/store.py +265 -0
  275. eawf/runtime/vcs/__init__.py +19 -0
  276. eawf/runtime/vcs/coauthor.py +203 -0
  277. eawf/runtime/worktree/__init__.py +129 -0
  278. eawf/runtime/worktree/cleanup.py +162 -0
  279. eawf/runtime/worktree/create.py +326 -0
  280. eawf/runtime/worktree/git.py +494 -0
  281. eawf/runtime/worktree/locks.py +71 -0
  282. eawf/runtime/worktree/merge_back.py +392 -0
  283. eawf/runtime/worktree/wave_land.py +375 -0
  284. eawf/schemas/config.schema.json +6 -0
  285. eawf/schemas/plan-view.schema.json +530 -0
  286. eawf/schemas/skill-output.schema.json +180 -0
  287. eawf/schemas/state.schema.json +2854 -0
  288. eawf/surfaces/__init__.py +11 -0
  289. eawf/surfaces/cli/__init__.py +0 -0
  290. eawf/surfaces/cli/_daemon_client.py +418 -0
  291. eawf/surfaces/cli/_dispatch.py +356 -0
  292. eawf/surfaces/cli/_mutation.py +249 -0
  293. eawf/surfaces/cli/_stdin.py +40 -0
  294. eawf/surfaces/cli/app.py +237 -0
  295. eawf/surfaces/cli/commands/__init__.py +7 -0
  296. eawf/surfaces/cli/commands/agent_report.py +210 -0
  297. eawf/surfaces/cli/commands/backup.py +177 -0
  298. eawf/surfaces/cli/commands/bench.py +309 -0
  299. eawf/surfaces/cli/commands/calibrate.py +109 -0
  300. eawf/surfaces/cli/commands/cc.py +121 -0
  301. eawf/surfaces/cli/commands/clone_repo.py +286 -0
  302. eawf/surfaces/cli/commands/coauthor.py +91 -0
  303. eawf/surfaces/cli/commands/completion.py +234 -0
  304. eawf/surfaces/cli/commands/config.py +954 -0
  305. eawf/surfaces/cli/commands/daemon.py +464 -0
  306. eawf/surfaces/cli/commands/doc.py +173 -0
  307. eawf/surfaces/cli/commands/doctor.py +409 -0
  308. eawf/surfaces/cli/commands/draft.py +331 -0
  309. eawf/surfaces/cli/commands/estimation.py +839 -0
  310. eawf/surfaces/cli/commands/evidence.py +166 -0
  311. eawf/surfaces/cli/commands/evidence_artifact.py +332 -0
  312. eawf/surfaces/cli/commands/evidence_backlog.py +559 -0
  313. eawf/surfaces/cli/commands/evidence_hypothesis.py +328 -0
  314. eawf/surfaces/cli/commands/evidence_incident.py +366 -0
  315. eawf/surfaces/cli/commands/flow.py +554 -0
  316. eawf/surfaces/cli/commands/help.py +169 -0
  317. eawf/surfaces/cli/commands/hook.py +837 -0
  318. eawf/surfaces/cli/commands/impact.py +79 -0
  319. eawf/surfaces/cli/commands/init.py +464 -0
  320. eawf/surfaces/cli/commands/lifecycle.py +664 -0
  321. eawf/surfaces/cli/commands/lifecycle_iter.py +494 -0
  322. eawf/surfaces/cli/commands/lifecycle_phase.py +714 -0
  323. eawf/surfaces/cli/commands/lifecycle_wave.py +589 -0
  324. eawf/surfaces/cli/commands/lifecycle_wave_read.py +697 -0
  325. eawf/surfaces/cli/commands/mcp.py +826 -0
  326. eawf/surfaces/cli/commands/memory.py +151 -0
  327. eawf/surfaces/cli/commands/memory_read.py +262 -0
  328. eawf/surfaces/cli/commands/memory_write.py +721 -0
  329. eawf/surfaces/cli/commands/metrics.py +403 -0
  330. eawf/surfaces/cli/commands/migrate.py +214 -0
  331. eawf/surfaces/cli/commands/plan.py +247 -0
  332. eawf/surfaces/cli/commands/plugin.py +344 -0
  333. eawf/surfaces/cli/commands/plugin_render.py +387 -0
  334. eawf/surfaces/cli/commands/plugin_verbs.py +660 -0
  335. eawf/surfaces/cli/commands/pr.py +136 -0
  336. eawf/surfaces/cli/commands/pr_review.py +454 -0
  337. eawf/surfaces/cli/commands/profile.py +206 -0
  338. eawf/surfaces/cli/commands/release.py +230 -0
  339. eawf/surfaces/cli/commands/render_output.py +135 -0
  340. eawf/surfaces/cli/commands/repo.py +501 -0
  341. eawf/surfaces/cli/commands/repo_link.py +340 -0
  342. eawf/surfaces/cli/commands/repo_registry.py +630 -0
  343. eawf/surfaces/cli/commands/research.py +86 -0
  344. eawf/surfaces/cli/commands/roadmap.py +995 -0
  345. eawf/surfaces/cli/commands/schema.py +107 -0
  346. eawf/surfaces/cli/commands/session.py +305 -0
  347. eawf/surfaces/cli/commands/skill.py +764 -0
  348. eawf/surfaces/cli/commands/snapshot.py +317 -0
  349. eawf/surfaces/cli/commands/spec.py +557 -0
  350. eawf/surfaces/cli/commands/state.py +262 -0
  351. eawf/surfaces/cli/commands/status.py +359 -0
  352. eawf/surfaces/cli/commands/store.py +105 -0
  353. eawf/surfaces/cli/commands/sync.py +534 -0
  354. eawf/surfaces/cli/commands/telemetry.py +93 -0
  355. eawf/surfaces/cli/commands/validate.py +134 -0
  356. eawf/surfaces/cli/commands/wave_ci.py +463 -0
  357. eawf/surfaces/cli/commands/wave_policy.py +198 -0
  358. eawf/surfaces/cli/commands/wiki.py +82 -0
  359. eawf/surfaces/cli/commands/workspace.py +706 -0
  360. eawf/surfaces/cli/commands/worktree.py +709 -0
  361. eawf/surfaces/cli/error_codes.py +148 -0
  362. eawf/surfaces/cli/errors.py +483 -0
  363. eawf/surfaces/cli/exit_codes.py +74 -0
  364. eawf/surfaces/cli/flags.py +63 -0
  365. eawf/surfaces/cli/help_panels.py +207 -0
  366. eawf/surfaces/cli/output.py +40 -0
  367. eawf/surfaces/cli/registry.py +252 -0
  368. eawf/surfaces/cli/scope.py +255 -0
  369. eawf/surfaces/cli/streaming.py +367 -0
  370. eawf/surfaces/render/__init__.py +34 -0
  371. eawf/surfaces/render/_atomic.py +64 -0
  372. eawf/surfaces/render/agent_report.py +220 -0
  373. eawf/surfaces/render/agents.py +615 -0
  374. eawf/surfaces/render/agents_md.py +478 -0
  375. eawf/surfaces/render/artifact_chassis.py +36 -0
  376. eawf/surfaces/render/audit_report.py +65 -0
  377. eawf/surfaces/render/brand.py +192 -0
  378. eawf/surfaces/render/claude_shim.py +61 -0
  379. eawf/surfaces/render/decision_graph.py +148 -0
  380. eawf/surfaces/render/drift.py +114 -0
  381. eawf/surfaces/render/envelope.py +384 -0
  382. eawf/surfaces/render/hooks.py +156 -0
  383. eawf/surfaces/render/impact.py +176 -0
  384. eawf/surfaces/render/manifest.py +138 -0
  385. eawf/surfaces/render/metrics_view.py +140 -0
  386. eawf/surfaces/render/plan_view.py +947 -0
  387. eawf/surfaces/render/pr_body.py +500 -0
  388. eawf/surfaces/render/regions.py +259 -0
  389. eawf/surfaces/render/release_notes.py +146 -0
  390. eawf/surfaces/render/research.py +49 -0
  391. eawf/surfaces/render/skills/__init__.py +42 -0
  392. eawf/surfaces/render/skills/registry.py +1149 -0
  393. eawf/surfaces/render/skills/render.py +146 -0
  394. eawf/surfaces/render/statusline.py +250 -0
  395. eawf/surfaces/render/wiki.py +117 -0
  396. eawf/surfaces/tui/__init__.py +20 -0
  397. eawf/surfaces/tui/app.py +758 -0
  398. eawf/surfaces/tui/offline.py +310 -0
  399. eawf/surfaces/tui/palette/__init__.py +42 -0
  400. eawf/surfaces/tui/palette/command_palette.py +326 -0
  401. eawf/surfaces/tui/palette/verbs.py +865 -0
  402. eawf/surfaces/tui/scopes/__init__.py +194 -0
  403. eawf/surfaces/tui/scopes/_zoom.py +213 -0
  404. eawf/surfaces/tui/scopes/repo.py +91 -0
  405. eawf/surfaces/tui/scopes/user.py +192 -0
  406. eawf/surfaces/tui/scopes/workspace.py +89 -0
  407. eawf/surfaces/tui/screens/__init__.py +19 -0
  408. eawf/surfaces/tui/screens/help.py +250 -0
  409. eawf/surfaces/tui/screens/overlays/__init__.py +109 -0
  410. eawf/surfaces/tui/screens/overlays/audit_failed.py +274 -0
  411. eawf/surfaces/tui/screens/overlays/audit_running.py +304 -0
  412. eawf/surfaces/tui/screens/overlays/config_modal.py +1021 -0
  413. eawf/surfaces/tui/screens/overlays/config_modal_logic.py +443 -0
  414. eawf/surfaces/tui/screens/overlays/confirm.py +143 -0
  415. eawf/surfaces/tui/screens/overlays/detail.py +662 -0
  416. eawf/surfaces/tui/screens/overlays/edit_field.py +224 -0
  417. eawf/surfaces/tui/screens/overlays/events.py +393 -0
  418. eawf/surfaces/tui/screens/overlays/metrics.py +311 -0
  419. eawf/surfaces/tui/screens/overlays/multichoice_checklist.py +176 -0
  420. eawf/surfaces/tui/screens/overlays/needs_user.py +195 -0
  421. eawf/surfaces/tui/screens/overlays/plan_preview.py +349 -0
  422. eawf/surfaces/tui/screens/overlays/pr_list.py +527 -0
  423. eawf/surfaces/tui/snapshot/__init__.py +60 -0
  424. eawf/surfaces/tui/snapshot/asciinema.py +132 -0
  425. eawf/surfaces/tui/snapshot/pilot_harness.py +220 -0
  426. eawf/surfaces/tui/state_binding.py +181 -0
  427. eawf/surfaces/tui/theme.py +547 -0
  428. eawf/surfaces/tui/theme.tcss +117 -0
  429. eawf/surfaces/tui/toast_emitter.py +391 -0
  430. eawf/surfaces/tui/widgets/__init__.py +44 -0
  431. eawf/surfaces/tui/widgets/backlog_table.py +423 -0
  432. eawf/surfaces/tui/widgets/eu_bar.py +562 -0
  433. eawf/surfaces/tui/widgets/footer.py +234 -0
  434. eawf/surfaces/tui/widgets/git_pane.py +254 -0
  435. eawf/surfaces/tui/widgets/header.py +209 -0
  436. eawf/surfaces/tui/widgets/heartbeat.py +152 -0
  437. eawf/surfaces/tui/widgets/markup.py +75 -0
  438. eawf/surfaces/tui/widgets/roadmap_tree.py +710 -0
  439. eawf/surfaces/tui/widgets/status_pane.py +1191 -0
  440. eawf/surfaces/tui/widgets/variance_tile.py +150 -0
  441. eawf/surfaces/tui/widgets/workspace_table.py +638 -0
  442. eawf/workflow/__init__.py +16 -0
  443. eawf/workflow/agent_report/__init__.py +19 -0
  444. eawf/workflow/agent_report/rollup.py +101 -0
  445. eawf/workflow/agent_report/store.py +160 -0
  446. eawf/workflow/agents/__init__.py +14 -0
  447. eawf/workflow/agents/specs/__init__.py +49 -0
  448. eawf/workflow/agents/specs/models.py +358 -0
  449. eawf/workflow/agents/specs/roles.py +193 -0
  450. eawf/workflow/audit_dsl/__init__.py +23 -0
  451. eawf/workflow/audit_dsl/kinds/__init__.py +21 -0
  452. eawf/workflow/audit_dsl/kinds/criterion_in_diff.py +133 -0
  453. eawf/workflow/audit_dsl/kinds/verify_implements.py +311 -0
  454. eawf/workflow/audit_dsl/models.py +93 -0
  455. eawf/workflow/audit_dsl/registry.py +178 -0
  456. eawf/workflow/audit_dsl/runner.py +97 -0
  457. eawf/workflow/dispatch/__init__.py +41 -0
  458. eawf/workflow/dispatch/renderer.py +529 -0
  459. eawf/workflow/estimation/__init__.py +3 -0
  460. eawf/workflow/estimation/buckets.py +244 -0
  461. eawf/workflow/estimation/eu.py +148 -0
  462. eawf/workflow/estimation/metrics.py +502 -0
  463. eawf/workflow/estimation/recovery.py +172 -0
  464. eawf/workflow/estimation/segments.py +125 -0
  465. eawf/workflow/evidence/__init__.py +18 -0
  466. eawf/workflow/evidence/_io.py +192 -0
  467. eawf/workflow/evidence/artifact.py +176 -0
  468. eawf/workflow/evidence/audit.py +399 -0
  469. eawf/workflow/evidence/backlog.py +249 -0
  470. eawf/workflow/evidence/decision.py +202 -0
  471. eawf/workflow/evidence/goal.py +79 -0
  472. eawf/workflow/evidence/guards.py +64 -0
  473. eawf/workflow/evidence/hypothesis.py +138 -0
  474. eawf/workflow/evidence/incident.py +166 -0
  475. eawf/workflow/evidence/outcome.py +116 -0
  476. eawf/workflow/lifecycle/__init__.py +65 -0
  477. eawf/workflow/lifecycle/_errors.py +16 -0
  478. eawf/workflow/lifecycle/allocator.py +93 -0
  479. eawf/workflow/lifecycle/criterion_drift.py +101 -0
  480. eawf/workflow/lifecycle/iter_.py +179 -0
  481. eawf/workflow/lifecycle/phase.py +397 -0
  482. eawf/workflow/lifecycle/project.py +56 -0
  483. eawf/workflow/lifecycle/spec.py +74 -0
  484. eawf/workflow/lifecycle/transitions.py +90 -0
  485. eawf/workflow/lifecycle/wave.py +528 -0
  486. eawf/workflow/lifecycle/wave_sha.py +141 -0
  487. eawf/workflow/pr_review/__init__.py +30 -0
  488. eawf/workflow/pr_review/parser.py +182 -0
  489. eawf/workflow/pr_review/policy.py +53 -0
  490. eawf/workflow/skills/__init__.py +13 -0
  491. eawf/workflow/skills/_bootstrap.py +54 -0
  492. eawf/workflow/skills/_common.py +318 -0
  493. eawf/workflow/skills/agent_dispatch.py +128 -0
  494. eawf/workflow/skills/audit.py +434 -0
  495. eawf/workflow/skills/blitz.py +171 -0
  496. eawf/workflow/skills/bodies/__init__.py +79 -0
  497. eawf/workflow/skills/bodies/agent_dispatch.py +29 -0
  498. eawf/workflow/skills/bodies/audit.py +122 -0
  499. eawf/workflow/skills/bodies/blitz.py +22 -0
  500. eawf/workflow/skills/bodies/coauthor.py +30 -0
  501. eawf/workflow/skills/bodies/compress.py +31 -0
  502. eawf/workflow/skills/bodies/differentiate.py +38 -0
  503. eawf/workflow/skills/bodies/flow.py +61 -0
  504. eawf/workflow/skills/bodies/init.py +39 -0
  505. eawf/workflow/skills/bodies/memory.py +31 -0
  506. eawf/workflow/skills/bodies/polish.py +80 -0
  507. eawf/workflow/skills/bodies/prep.py +68 -0
  508. eawf/workflow/skills/bodies/research.py +83 -0
  509. eawf/workflow/skills/bodies/review.py +48 -0
  510. eawf/workflow/skills/bodies/roadmap.py +38 -0
  511. eawf/workflow/skills/bodies/security_review.py +40 -0
  512. eawf/workflow/skills/bodies/ship.py +79 -0
  513. eawf/workflow/skills/bodies/user_question.py +55 -0
  514. eawf/workflow/skills/bodies/wave_spec.py +31 -0
  515. eawf/workflow/skills/coauthor.py +154 -0
  516. eawf/workflow/skills/compress.py +168 -0
  517. eawf/workflow/skills/differentiate.py +226 -0
  518. eawf/workflow/skills/discovery.py +234 -0
  519. eawf/workflow/skills/engine.py +561 -0
  520. eawf/workflow/skills/flow/__init__.py +786 -0
  521. eawf/workflow/skills/flow/store_io.py +296 -0
  522. eawf/workflow/skills/init.py +275 -0
  523. eawf/workflow/skills/memory.py +136 -0
  524. eawf/workflow/skills/needs_user.py +372 -0
  525. eawf/workflow/skills/polish.py +175 -0
  526. eawf/workflow/skills/prep.py +393 -0
  527. eawf/workflow/skills/registry.py +96 -0
  528. eawf/workflow/skills/research.py +407 -0
  529. eawf/workflow/skills/review.py +181 -0
  530. eawf/workflow/skills/roadmap.py +411 -0
  531. eawf/workflow/skills/security_review.py +122 -0
  532. eawf/workflow/skills/ship.py +779 -0
  533. eawf/workflow/skills/wave_spec.py +128 -0
  534. eawf-0.3.0.dist-info/METADATA +135 -0
  535. eawf-0.3.0.dist-info/RECORD +538 -0
  536. eawf-0.3.0.dist-info/WHEEL +4 -0
  537. eawf-0.3.0.dist-info/entry_points.txt +4 -0
  538. eawf-0.3.0.dist-info/licenses/LICENSE +21 -0
eawf/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from eawf._version import __version__
4
+
5
+ __all__ = ["__version__"]
eawf/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ from eawf.surfaces.cli.app import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Label</key>
6
+ <string>dev.eawf.eawfd</string>
7
+ <key>ProgramArguments</key>
8
+ <array>
9
+ {% for arg in eawfd_argv %}<string>{{ arg }}</string>
10
+ {% endfor %}
11
+ </array>
12
+ <key>KeepAlive</key>
13
+ <true/>
14
+ <key>RunAtLoad</key>
15
+ <true/>
16
+ <key>StandardOutPath</key>
17
+ <string>{{ runtime_dir }}/eawfd.log</string>
18
+ <key>StandardErrorPath</key>
19
+ <string>{{ runtime_dir }}/eawfd.err</string>
20
+ <key>EnvironmentVariables</key>
21
+ <dict>
22
+ <key>EAWF_RUNTIME_DIR</key>
23
+ <string>{{ runtime_dir }}</string>
24
+ </dict>
25
+ </dict>
26
+ </plist>
@@ -0,0 +1,14 @@
1
+ [Unit]
2
+ Description=eawf coordinator daemon (eawfd)
3
+ After=default.target
4
+
5
+ [Service]
6
+ Type=simple
7
+ ExecStart={{ eawfd_argv | join(' ') }} --foreground
8
+ Restart=on-failure
9
+ RestartSec=5
10
+ TimeoutStopSec=30
11
+ Environment="EAWF_RUNTIME_DIR={{ runtime_dir }}"
12
+
13
+ [Install]
14
+ WantedBy=default.target
eawf/_version.py ADDED
@@ -0,0 +1,22 @@
1
+ """Single source of truth for the package version.
2
+
3
+ Hatchling reads ``__version__`` from this module via the
4
+ ``[tool.hatch.version]`` table in ``pyproject.toml`` (``dynamic =
5
+ ["version"]``), and the package re-exports it from
6
+ :mod:`eawf` so ``eawf --version`` and ``importlib.metadata`` agree.
7
+
8
+ The version string is **PEP-440-compatible** so ``pip install
9
+ eawf==0.3.0a1`` resolves; the semver core (``MAJOR.MINOR.PATCH``)
10
+ plus an optional PEP-440 pre-release segment (``a`` / ``b`` / ``rc``
11
+ + a number) is the only shape this module carries. The
12
+ human-readable build-metadata long form (``0.3.0-alpha.1+phase.PNN``)
13
+ is composed by the version-display surface, not stored here.
14
+
15
+ Bump this value with ``tools/version_bump.py`` rather than editing
16
+ by hand — the bumper keeps the semver / PEP-440 grammar consistent
17
+ and is the single rewrite path the release pipeline drives.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ __version__ = "0.3.0"
@@ -0,0 +1,12 @@
1
+ """Kernel layer: typed state, storage, config, validation, specs, migrations.
2
+
3
+ The kernel super-package groups the load-bearing data-model packages that
4
+ the rest of the tree builds on: :mod:`~eawf.kernel.state` (typed entities,
5
+ IDs, URNs, atomic writes), :mod:`~eawf.kernel.store` (JSONL stores),
6
+ :mod:`~eawf.kernel.config` (layered configuration),
7
+ :mod:`~eawf.kernel.validate` (schema + invariant validation),
8
+ :mod:`~eawf.kernel.spec` (typed phase/iter/wave specs), and
9
+ :mod:`~eawf.kernel.migrations` (state-schema migration chain).
10
+ """
11
+
12
+ from __future__ import annotations
@@ -0,0 +1,26 @@
1
+ """Layered configuration subsystem for eawf.
2
+
3
+ Configuration is layered with the following precedence (lowest to
4
+ highest, later overrides earlier):
5
+
6
+ 1. built-in defaults (read-only, baked into the package)
7
+ 2. global ``~/.config/eawf/config.yaml``
8
+ 3. workspace ``<workspace>/.ea/config.yaml``
9
+ 4. repo ``<repo>/.ea/config.yaml``
10
+ 5. local ``<repo>/.ea/local/config.yaml``
11
+ 6. environment variables (``EAWF_*``)
12
+ 7. CLI overrides
13
+
14
+ Required top-level sections of the merged config follow
15
+ ``docs/architecture/envelope.md`` "Config schema required sections".
16
+
17
+ Public API:
18
+
19
+ - :func:`eawf.kernel.config.layered.merge_config` returns ``(merged, source_map)``.
20
+ - :func:`eawf.kernel.config.profile.enable_profile` writes a profile to a layer file
21
+ and materialises any required state-keys.
22
+ - :data:`eawf.kernel.config.defaults.BUILT_IN_DEFAULTS` is the read-only base layer.
23
+ - :func:`eawf.kernel.config.loader.load_yaml_layer` parses a single layer file.
24
+ """
25
+
26
+ from __future__ import annotations
@@ -0,0 +1,416 @@
1
+ """Built-in (read-only) configuration defaults.
2
+
3
+ The contents mirror ``docs/architecture/envelope.md`` "Config schema
4
+ required sections". Every required section listed there appears here so
5
+ the merged config has every key resolvable to ``built-in`` when no later
6
+ layer overrides.
7
+
8
+ This module exposes a single read-only constant: :data:`BUILT_IN_DEFAULTS`.
9
+ Callers that need to mutate the structure (loaders, mergers) MUST deep-copy
10
+ first. The constant itself is treated as immutable; tests assert this contract.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from copy import deepcopy
16
+ from typing import Any
17
+
18
+ # The literal name "built-in" is the canonical layer label everywhere — keep
19
+ # it in lockstep with :mod:`eawf.kernel.config.layered` and ``cli/commands/config.py``.
20
+ BUILT_IN_LAYER: str = "built-in"
21
+
22
+ # Single source of truth for the on-disk ``.ea/config.yaml`` schema version.
23
+ # Bumped to ``"1.0"`` in P25-W14 (C08 spec series) — the canonical layered
24
+ # taxonomy. Earlier marker values ``"1.1"`` (P14-W03 ``runtime.adapters``
25
+ # shim) and ``"2"`` (interim experimental) are auto-upgraded to ``"1.0"``
26
+ # by :mod:`eawf.kernel.config.migration`. The numeric ordering of the marker
27
+ # strings is irrelevant — they are opaque schema-shape identifiers.
28
+ CONFIG_SCHEMA_VERSION: str = "1.0"
29
+
30
+
31
+ _BUILT_IN_DEFAULTS: dict[str, Any] = {
32
+ "schema_version": CONFIG_SCHEMA_VERSION,
33
+ "config": {
34
+ # When ``false``, ``eawf config get`` hides the layer-source column
35
+ # in default output (operators that prefer terse listings).
36
+ "layers_visible": True,
37
+ },
38
+ "cli": {
39
+ "canonical_command": "eawf",
40
+ "preferred_command": "eawf",
41
+ "install_aliases": ["ea"],
42
+ "omit_ea_alias": False,
43
+ },
44
+ "project": {
45
+ "code": None,
46
+ "title": None,
47
+ "slug": None,
48
+ "domains": [],
49
+ "default_subproject": None,
50
+ # Free-form project-level goal strings (one per list item). Surfaced
51
+ # in dispatch envelopes + research/audit briefs so subagents see
52
+ # project intent without re-deriving from state.
53
+ "goals": [],
54
+ # Quantitative goal targets keyed by metric name (e.g. p99 latency,
55
+ # contributor count). Values are floats so the same registry entry
56
+ # can carry rates / ratios / counts.
57
+ "success_metrics": {},
58
+ },
59
+ "workspace": {
60
+ "enabled": False,
61
+ "code": None,
62
+ "state_path": ".ea/state.json",
63
+ "repos": {},
64
+ },
65
+ "profiles": {
66
+ "enabled": ["core"],
67
+ "catalog": [
68
+ "core",
69
+ "research",
70
+ "python",
71
+ "docs",
72
+ "apps",
73
+ "infra",
74
+ "ml",
75
+ "quant",
76
+ "re",
77
+ "game",
78
+ "robotics",
79
+ ],
80
+ "conflict_resolution": "prompt",
81
+ "safety_policy": "strictest_wins",
82
+ # Content-hash trust ledger; key = profile id, value = sha256 of
83
+ # the body the operator last accepted. The composition loader
84
+ # cross-references this map when a profile body changes between
85
+ # loads — drift surfaces as a prompt.
86
+ "trusted": {},
87
+ },
88
+ "runtime": {
89
+ "default": "claude",
90
+ # ``adapters`` is the user-facing selector list. Built-in default
91
+ # opts the project into the Claude adapter only; the wizard /
92
+ # workspace overlay extends or replaces it.
93
+ "adapters": ["claude"],
94
+ # ``preference`` is the C08-canonical fallback ladder; first entry
95
+ # is primary. The legacy-shim path in :mod:`eawf.kernel.config.layered`
96
+ # synthesises ``preference`` from ``adapters`` when only the
97
+ # latter is present.
98
+ "preference": ["claude"],
99
+ # Fallback policy applied when the primary runtime rejects a
100
+ # dispatch (rate-limit / server error / timeout / API error).
101
+ "fallback": {
102
+ "on_errors": [
103
+ "RUNTIME_RATE_LIMIT",
104
+ "RUNTIME_SERVER_ERROR",
105
+ "RUNTIME_TIMEOUT",
106
+ "RUNTIME_API_ERROR",
107
+ ],
108
+ "retry_policy": "hybrid",
109
+ "max_backoff_seconds": 90,
110
+ },
111
+ "slash_commands": [
112
+ "init",
113
+ "roadmap",
114
+ "differentiate",
115
+ "research",
116
+ "prep",
117
+ "audit",
118
+ "ship",
119
+ "review",
120
+ "polish",
121
+ ],
122
+ # ``adapter_catalog`` holds the per-adapter config blocks. Indexed
123
+ # by adapter id; the runtime spine reads it after consulting
124
+ # ``adapters`` for the selector list.
125
+ "adapter_catalog": {
126
+ "claude": {
127
+ "enabled": True,
128
+ "plugin_install": "ask",
129
+ "skills_path": ".claude/skills",
130
+ "agents_path": ".claude/agents",
131
+ },
132
+ "codex": {"enabled": False, "status": "planned"},
133
+ "opencode": {"enabled": False, "status": "deferred"},
134
+ },
135
+ },
136
+ "ui": {
137
+ "bare_command": "tui",
138
+ "color": "auto",
139
+ "glyphs": "auto",
140
+ "refresh_ms": 1000,
141
+ "dashboard_panes": [
142
+ "state",
143
+ "roadmap",
144
+ "hypotheses",
145
+ "audits",
146
+ "ship",
147
+ "memory",
148
+ "config",
149
+ ],
150
+ },
151
+ # C09 (telemetry) projector reads these keys. Telemetry is opt-in
152
+ # (``enabled`` defaults False) and strict-local: there is no export
153
+ # endpoint key, so a projection / export never contacts an external
154
+ # service. ``db_kind`` defaults to the always-available stdlib sqlite
155
+ # backend; ``duckdb`` is the opt-in analytics upgrade.
156
+ "telemetry": {
157
+ "enabled": False,
158
+ "export": {
159
+ "format": "prom",
160
+ },
161
+ "window_default": "7d",
162
+ "aggregate_window": "24h",
163
+ "db_kind": "sqlite",
164
+ },
165
+ # Dispatch defaults — the per-skill or per-profile manifest still
166
+ # wins; these are the bottom-of-stack values.
167
+ "dispatch": {
168
+ "session_policy_default": "hybrid",
169
+ "session_handle_ttl_seconds": 86400,
170
+ },
171
+ # Language-fit knobs. ``runtime`` is locked at ``python`` for
172
+ # v0.3-v0.5 (D6); ``fast_extras`` opts in to PyO3 hot paths.
173
+ "language": {
174
+ "runtime": "python",
175
+ "fast_extras": [],
176
+ },
177
+ "storage": {
178
+ "state_path": ".ea/state.json",
179
+ "stores_dir": ".ea/stores",
180
+ "artifacts_dir": ".ea/artifacts",
181
+ "rendered_dir": ".ea/artifacts/rendered",
182
+ "generated_index": ".ea/indexes/generated.json",
183
+ "content_addressed_blobs": True,
184
+ "commit_jsonl": "all_nonlocal",
185
+ "max_inline_chars": 2000,
186
+ "lock_strategy": "sibling_lockfiles",
187
+ },
188
+ "research": {
189
+ "folder": ".ea/artifacts/rendered/research",
190
+ "auto_save": False,
191
+ "default_depth": "normal",
192
+ "default_sources": "both",
193
+ "agent_count": 4,
194
+ },
195
+ "planning": {
196
+ "approval": "ask",
197
+ "max_parallel_waves": 4,
198
+ "require_research_for_unknowns": True,
199
+ # When False (default), ``/prep`` enters Claude Code plan mode and
200
+ # presents the proposed wave DAG to the operator before any state
201
+ # mutation. Set to True (or pass ``--auto-plan`` on the slash
202
+ # invocation) to skip the proposal and dispatch the plan inline.
203
+ "auto_plan": False,
204
+ },
205
+ "estimation": {
206
+ "enabled": True,
207
+ "eu_minutes": 30,
208
+ "realtime_recalibration": False,
209
+ "calibration_profile": "eawf_v0_lockbox_2026_05",
210
+ "idle_policy": "D30_non_agent_gap",
211
+ "display": {
212
+ "show_category": False,
213
+ "show_raw_eu": True,
214
+ "show_expected_time": True,
215
+ "show_pessimistic_time": True,
216
+ "eu_quantum": 0.25,
217
+ "time_quantum_under_2h_minutes": 15,
218
+ "time_quantum_over_2h_minutes": 30,
219
+ },
220
+ },
221
+ "audit": {
222
+ "default_checks": ["state", "tests", "lint", "typecheck", "docs"],
223
+ "fix_safe": False,
224
+ "flaky_retry_count": 1,
225
+ },
226
+ "ship": {
227
+ "require_audit_pass": True,
228
+ "require_memory_review": True,
229
+ "use_vcs_policy": True,
230
+ },
231
+ "review": {
232
+ "post_default": "ask",
233
+ "template": "default",
234
+ "require_checks_before_approve": True,
235
+ },
236
+ "polish": {
237
+ "auto_apply_safe": False,
238
+ "include_memory": True,
239
+ "include_agent_memory": True,
240
+ "deletion_policy": "recoverable_with_reason",
241
+ },
242
+ "flow": {
243
+ # Per-stage gates. When False (default), ``/flow`` asks the operator
244
+ # via ``AskUserQuestion`` before advancing past the named step. Set
245
+ # the per-stage flag to True (or pass ``--auto-accept=<stage>[,...]``)
246
+ # to advance without a prompt.
247
+ "auto_accept": {
248
+ "research": False,
249
+ "prep": False,
250
+ "audit": False,
251
+ "ship": False,
252
+ "review": False,
253
+ "polish": False,
254
+ },
255
+ # Encourage subagent prompts and skill bodies to surface discrete
256
+ # decisions through ``AskUserQuestion`` rather than free-text prompts.
257
+ "ask_on_decisions": True,
258
+ # Per-wave token-budget enforcement. ``soft`` (default) warns and
259
+ # lets the wave continue past its cap; ``hard`` halts the wave at
260
+ # the cap via the SIGTERM->SIGKILL ladder. ``multiplier`` scales
261
+ # the base budget to derive the enforced cap (1.5 == 50% headroom).
262
+ "budget": {
263
+ "enforce": "soft",
264
+ "multiplier": 1.5,
265
+ },
266
+ },
267
+ "memory": {
268
+ "stores": ["project", "subproject", "agent", "user"],
269
+ "review_on_ship": True,
270
+ "review_on_polish": True,
271
+ "auto_promote": "ask",
272
+ "prune": "ask",
273
+ "max_injected_tokens": 2000,
274
+ },
275
+ "vcs": {
276
+ "commit_template": "state_scoped",
277
+ "pr_template": "iter",
278
+ "branch_pattern": "eawf/{project}/{scope}-{slug}",
279
+ "checkpoint_requires_commit": True,
280
+ "protected_branches": ["main", "master"],
281
+ "auto_commit": "ask",
282
+ "auto_push": "ask",
283
+ "pr_open": "ask",
284
+ "pr_merge_method": "merge",
285
+ "squash_allowed": False,
286
+ "delete_branch_after_merge": False,
287
+ "require_ci_green": True,
288
+ "require_review_before_merge": True,
289
+ "force_push": "forbidden_protected",
290
+ "coauthor": {
291
+ "mode": "runtime",
292
+ "default_runtime": "claude",
293
+ "project": None,
294
+ "trailers": {
295
+ "claude": {
296
+ "name": "Claude",
297
+ "email": "noreply@anthropic.com",
298
+ },
299
+ "codex": {
300
+ "name": "Codex",
301
+ "email": "noreply@openai.com",
302
+ },
303
+ },
304
+ "require_trailer": True,
305
+ },
306
+ },
307
+ "worktrees": {
308
+ "enabled": "auto",
309
+ "root": ".worktrees",
310
+ "merge_mode": "cherry_pick",
311
+ "use_for_parallel_writers": True,
312
+ "use_for_risky_changes": True,
313
+ "use_for_readonly_research": False,
314
+ "preserve_on_conflict": True,
315
+ "remove_when_clean": True,
316
+ },
317
+ "acceptance": {
318
+ "commands": {
319
+ "tests": None,
320
+ "lint": None,
321
+ "typecheck": None,
322
+ "build": None,
323
+ },
324
+ "required_before_ship": ["state"],
325
+ },
326
+ "security": {
327
+ "secrets_policy": "env_refs_only", # pragma: allowlist secret
328
+ "env_ref_syntax": "${ENV:NAME}",
329
+ "permission_mode": "ask_first",
330
+ "secret_scan": True,
331
+ "store_scan_before_checkpoint": True,
332
+ "store_scan_on_finding": "block",
333
+ "allow_destructive": "ask",
334
+ },
335
+ "hooks": {
336
+ "policy": "mixed_strict",
337
+ "timeout_seconds": 30,
338
+ "enabled": ["state_validate", "generated_drift", "post_edit_lint"],
339
+ "fail_closed": ["state_validate", "secret_scan", "protected_vcs"],
340
+ "fail_open": ["post_edit_lint", "statusline", "memory_capture"],
341
+ "ask_on_fail": ["overwrite_conflict", "destructive_action"],
342
+ },
343
+ "mcp": {
344
+ "default_policy": "ask_install",
345
+ "manage_only_owner": "eawf",
346
+ "env_ref_syntax": "${ENV:NAME}",
347
+ "servers": {},
348
+ },
349
+ "statusline": {
350
+ "modules_default": "ask_per_module",
351
+ "modules_available": [
352
+ "state",
353
+ "git",
354
+ "model_session_cwd",
355
+ "context_tokens",
356
+ "mcp_health",
357
+ "hooks_plugins",
358
+ "memory",
359
+ "token_saving",
360
+ ],
361
+ },
362
+ "docs": {
363
+ "generated_default_dir": ".ea/artifacts/rendered",
364
+ "generation_policy": "ask_per_category",
365
+ "categories": [
366
+ "roadmap",
367
+ "research",
368
+ "audit",
369
+ "decisions",
370
+ "incidents",
371
+ "memory",
372
+ "status",
373
+ ],
374
+ },
375
+ "commands": {
376
+ "inventory_policy": "full_io_spec_before_code",
377
+ },
378
+ "state_schema": {
379
+ "strictness": "full_strict_schema_before_code",
380
+ "id_padding": 2,
381
+ },
382
+ "daemon": {
383
+ # When True (default since P24-W10), state + config + registry
384
+ # mutations route through the daemon RPCs (``state.mutate``,
385
+ # ``config.set_layer_value``, ``registry.update``). Flip to
386
+ # False for the V1 daemonless carve-out (CI, read-only one-
387
+ # shot, recovery shell); the in-process portalocker path
388
+ # remains as the fallback. ``EAWF_DAEMONLESS=1`` is the
389
+ # process-level escape hatch and overrides this flag.
390
+ "proxy_enabled": True,
391
+ # Idle window after which the daemon self-shuts-down when no
392
+ # subscribers or in-flight mutations are live (seconds).
393
+ # Aligned with the Anthropic prompt-cache TTL (5 min) so a
394
+ # subscriber reconnect after a cache window does not racing-
395
+ # spawn the daemon mid-warmup.
396
+ "idle_timeout_seconds": 300,
397
+ # Per-handle TTL for the session table sweep (seconds);
398
+ # W07 wires the sweep.
399
+ "session_handle_ttl_seconds": 86400,
400
+ },
401
+ }
402
+
403
+
404
+ def built_in_defaults() -> dict[str, Any]:
405
+ """Return a fresh deep-copy of the built-in defaults.
406
+
407
+ Callers in :mod:`eawf.kernel.config.layered` mutate the returned dict via deep
408
+ merge — they MUST receive a fresh copy each call so successive merges do
409
+ not pollute the read-only baseline.
410
+ """
411
+ return deepcopy(_BUILT_IN_DEFAULTS)
412
+
413
+
414
+ # Public read-only view: callers that just want to inspect (e.g. tests) can
415
+ # use this directly. It MUST NOT be mutated; deep-copy first if needed.
416
+ BUILT_IN_DEFAULTS: dict[str, Any] = _BUILT_IN_DEFAULTS