kenaz 0.3.21 → 0.3.23

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 (481) hide show
  1. package/core/.claude/commands/Ansuz.md +2 -0
  2. package/core/.claude/hooks/__tests__/peer-session-fill.test.js +37 -0
  3. package/core/.claude/hooks/_ansuz-conversation.js +32 -1
  4. package/core/.claude/hooks/_user-scope.js +1 -1
  5. package/core/.claude/hooks/core-resolve.js +1 -1
  6. package/core/.claude/hooks/peer-optin.test.js +74 -0
  7. package/core/.claude/hooks/peer-session-fill.js +38 -0
  8. package/core/.claude/hooks/turn-context.js +5 -4
  9. package/core/.claude/hooks/worktree-create.js +6 -6
  10. package/core/.claude/hooks/worktree-remove.js +4 -4
  11. package/core/.claude/settings.json +9 -0
  12. package/core/.collaboration/core/reconcile.js +16 -1
  13. package/core/.collaboration/core/task-2467-lifecycle.test.js +63 -0
  14. package/core/.collaboration/core/task-api.js +37 -7
  15. package/core/.formation/bifrost/launch.js +1 -1
  16. package/core/.formation/bifrost/openai/codex-hook-shim.js +21 -4
  17. package/core/.formation/bifrost/openai/codex-peer-pull.test.js +42 -0
  18. package/core/.formation/bifrost/provider-launch.js +2 -1
  19. package/core/.formation/tools/kenaz-stats.js +1 -1
  20. package/core/.formation/tools/post-complete/git-merge.js +1 -1
  21. package/core/.formation/tools/prompt.js +1 -1
  22. package/core/.kenaz/specialist/ansuz_rules.yaml +7 -51
  23. package/core/.kenaz/specialist/ansuz_session_handoff.schema.json +2 -6
  24. package/core/.rule/general/project-self-containment.yaml +2 -2
  25. package/core/.specialist/Amelia/README.md +1 -1
  26. package/core/.specialist/Amelia/rule.yaml +1 -1
  27. package/core/.specialist/Ansuz/RULES.md +1 -1
  28. package/core/.specialist/Ansuz/concepts/commitment_layer.yaml +1 -1
  29. package/core/.specialist/Ansuz/concepts/evolvable_guardrails.yaml +1 -1
  30. package/core/.specialist/Ansuz/knowledge.yaml +1 -3
  31. package/core/.specialist/tools/__tests__/task-2409-lessons.test.js +10 -0
  32. package/core/.specialist/tools/__tests__/task-2427-harvest.test.js +25 -0
  33. package/core/.specialist/tools/ansuz-boot-fast.js +1 -1
  34. package/core/.specialist/tools/failure-detector.js +4 -4
  35. package/core/.specialist/tools/handoff-doc.js +1 -1
  36. package/core/.specialist/tools/lessons.js +2 -2
  37. package/core/CLAUDE.md +5 -5
  38. package/core/KENAZ_CORE_VERSION +1 -1
  39. package/core/dashboard/scripts/install-kenaz-cli.js +471 -0
  40. package/core/dev/scripts/check-file-size.js +1 -1
  41. package/core/dev/scripts/ci-feedback.js +1 -1
  42. package/core/dev/scripts/gc-agent-worktrees.js +11 -11
  43. package/core/dev/scripts/kenaz-session.js +3 -3
  44. package/core/dev/scripts/peer-identity-e2e.js +3 -3
  45. package/core/dev/scripts/run-rust-tests.js +2 -2
  46. package/core/dev/scripts/skill-routing-replay.js +3 -3
  47. package/core/dev/scripts/task1961/selftest.js +2 -2
  48. package/core/dev/scripts/windows-hide-guard.test.js +97 -0
  49. package/core/plugins/kenaz/commands/Ansuz.md +2 -0
  50. package/core/plugins/kenaz/guidance.md +2 -0
  51. package/core/plugins/kenaz/hooks/core-resolve.js +1 -1
  52. package/core/plugins/kenaz/hooks/hooks.json +9 -0
  53. package/core/plugins/kenaz/hooks/kenaz-hook.js +53 -4
  54. package/core/plugins/kenaz/scripts/kenaz.test.js +72 -5
  55. package/core/plugins/kenaz/scripts/ygg.js +40 -4
  56. package/core/plugins/kenaz/scripts/ygg.test.js +63 -3
  57. package/core/plugins/kenaz-peer/hooks/register.test.ts +59 -2
  58. package/core/plugins/kenaz-peer/hooks/register.ts +24 -1
  59. package/lib/cli.js +9 -5
  60. package/package.json +6 -6
  61. package/vendor/install-kenaz-cli.js +21 -6
  62. package/core/.kenaz/designs/METAPLASTICITY_CONFIDENCE_DESIGN.md +0 -537
  63. package/core/.kenaz/designs/REFLEX_INITIATOR_DESIGN.md +0 -501
  64. package/core/.kenaz/designs/TASK_1385_handoff_mcp_design.md +0 -426
  65. package/core/.kenaz/designs/TASK_932_hippocampus_consolidation.md +0 -103
  66. package/core/.kenaz/designs/TASK_934_efe_signal_engine.md +0 -97
  67. package/core/.kenaz/designs/TASK_935_self_evolution_framework.md +0 -154
  68. package/core/.kenaz/designs/VISION_cognitive_architecture_roadmap.md +0 -159
  69. package/core/.kenaz/designs/metaplasticity_simulation_results.json +0 -696
  70. package/core/.kenaz/main-memory/README.md +0 -230
  71. package/core/.kenaz/main-memory/kenaz/cortex/001_cortex_overview.md +0 -168
  72. package/core/.kenaz/main-memory/kenaz/cortex/001_rag_engine_overview.md +0 -30
  73. package/core/.kenaz/main-memory/kenaz/memory-system/001_three_tier_architecture.md +0 -361
  74. package/core/.kenaz/main-memory/kenaz/pipeline/001_task_execution_flow.md +0 -117
  75. package/core/.kenaz/main-memory/kenaz/pipeline/001_task_granularity.md +0 -154
  76. package/core/.kenaz/main-memory/kenaz/pipeline/002_team_priority.md +0 -51
  77. package/core/.kenaz/main-memory/kenaz/pipeline/003_feature_id_system.md +0 -46
  78. package/core/.kenaz/main-memory/kenaz/rules/001_gen_007_self_containment.md +0 -108
  79. package/core/.kenaz/main-memory/kenaz/rules/001_rule_priority_system.md +0 -121
  80. package/core/.kenaz/main-memory/kenaz/rules/002_agt_006_pre_check.md +0 -0
  81. package/core/.kenaz/main-memory/kenaz/rules/003_ppl_002_task_archival.md +0 -48
  82. package/core/.kenaz/main-memory/kenaz/system/001_dual_track_task_system.md +0 -197
  83. package/core/.kenaz/main-memory/knowledge/patterns/001_json_bom_issue.md +0 -78
  84. package/core/.kenaz/main-memory/knowledge/patterns/001_leader_worker_pattern.md +0 -0
  85. package/core/.kenaz/main-memory/knowledge/patterns/002_scope_path_conflict.md +0 -115
  86. package/core/.kenaz/main-memory/knowledge/patterns/002_task_dependency_resolution.md +0 -223
  87. package/core/.kenaz/main-memory/knowledge/patterns/003_question_protocol.md +0 -242
  88. package/core/.kenaz/main-memory/knowledge/patterns/004_user_insight_value.md +0 -111
  89. package/core/.kenaz/main-memory/knowledge/patterns/005_file_lock_pattern.md +0 -274
  90. package/core/.kenaz/main-memory/knowledge/references/001_ppl_rules.md +0 -28
  91. package/core/.kenaz/main-memory/knowledge/solutions/001_json_bom_issue.md +0 -137
  92. package/core/.kenaz/main-memory/knowledge/solutions/001_team_invocation.md +0 -0
  93. package/core/.kenaz/main-memory/knowledge/solutions/002_passive_monitoring.md +0 -0
  94. package/core/.kenaz/main-memory/knowledge/solutions/003_windows_file_race_condition.md +0 -239
  95. package/core/.kenaz/main-memory/registry.json +0 -326
  96. package/core/.kenaz/main-memory/version.yaml +0 -58
  97. package/core/.kenaz/specialist/memory_guard_fired.json +0 -1
  98. package/core/.kenaz/specialist/memory_guard_trigger_cache.json +0 -1
  99. package/core/.kenaz/specialist/memory_source_priority.yaml +0 -260
  100. package/core/.kenaz/specialist/prompt_1775.txt +0 -317
  101. package/core/.kenaz/specialist/prompt_1776.txt +0 -326
  102. package/core/.kenaz/specialist/prompt_1791.txt +0 -320
  103. package/core/.kenaz/specialist/prompt_1792.txt +0 -320
  104. package/core/.kenaz/specialist/prompt_1795.txt +0 -281
  105. package/core/.kenaz/specialist/prompt_1813.txt +0 -332
  106. package/core/.kenaz/specialist/prompt_1814.txt +0 -401
  107. package/core/.kenaz/specialist/prompt_1815.txt +0 -394
  108. package/core/.kenaz/specialist/prompt_1816.txt +0 -437
  109. package/core/.kenaz/specialist/prompt_1818.txt +0 -361
  110. package/core/.kenaz/specialist/prompt_1819.txt +0 -421
  111. package/core/.kenaz/specialist/prompt_1821.txt +0 -345
  112. package/core/.kenaz/specialist/prompt_1822.txt +0 -313
  113. package/core/.kenaz/specialist/prompt_1824.txt +0 -348
  114. package/core/.kenaz/specialist/prompt_1826.txt +0 -388
  115. package/core/.kenaz/specialist/rune_efe_salience_gap.md +0 -21
  116. package/core/.kenaz/specialist/task1825_update.json +0 -43
  117. package/core/.kenaz/specialist/taskgen/consolidation_i.json +0 -38
  118. package/core/.kenaz/specialist/taskgen/csharp_a.json +0 -44
  119. package/core/.kenaz/specialist/taskgen/csharp_b.json +0 -40
  120. package/core/.kenaz/specialist/taskgen/embedding_e.json +0 -34
  121. package/core/.kenaz/specialist/taskgen/hygiene_fg.json +0 -39
  122. package/core/.kenaz/specialist/taskgen/pathology_h.json +0 -36
  123. package/core/.kenaz/specialist/taskgen/unity_noise_d.json +0 -38
  124. package/core/.kenaz/specialist/taskgen/visibility_c.json +0 -38
  125. package/core/.specialist/Ansuz/decisions/ADR-requirement-graph-layer.md +0 -390
  126. package/core/.specialist/Ansuz/self_model_seed.backup.json +0 -100
  127. package/core/.specialist/ansuz_session_handoff.json +0 -96
  128. package/core/dev/ALAYA_FIELD_FEEDBACK_DESIGN.md +0 -126
  129. package/core/dev/ANSUZ_SCAFFOLD_DIET_2026-09-20.md +0 -231
  130. package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +0 -355
  131. package/core/dev/ANSUZ_WORKFLOW_MODERNIZATION.md +0 -143
  132. package/core/dev/CORTEX_META_GRAPH_ASSESSMENT.md +0 -99
  133. package/core/dev/FREYA_DOWNSTREAM_BUGS_2026-09-19.md +0 -44
  134. package/core/dev/GLOBAL_MEMORY_IDENTITY_CONSOLIDATION.md +0 -263
  135. package/core/dev/GUARD_EFFECTIVENESS_DESIGN.md +0 -180
  136. package/core/dev/HEALTH_GATE_VARIANCE_ASSESSMENT.md +0 -271
  137. package/core/dev/HOOK_DIET_2026-09-21.md +0 -126
  138. package/core/dev/JEV_INTEGRATION_PLAN.md +0 -189
  139. package/core/dev/KENAZ_AGENT_CONNECT_v1_SPEC.md +0 -139
  140. package/core/dev/MOBILE_DESIGN_SPEC.md +0 -569
  141. package/core/dev/MULTI_ANSUZ_SPEC.md +0 -136
  142. package/core/dev/MUNINN_RETIREMENT.md +0 -115
  143. package/core/dev/PHASE3_ATTRIBUTION_POPULATION_DIAGNOSIS.md +0 -211
  144. package/core/dev/PHASE3_P3-2B_TASKLEVEL_PROBE.md +0 -83
  145. package/core/dev/PHASE3_P3-2_POPULATION_DISJOINTNESS.md +0 -83
  146. package/core/dev/PHASE3_P3-2_REMEASURE_REPORT.md +0 -231
  147. package/core/dev/PREDICTION_GROUNDING_DESIGN.md +0 -376
  148. package/core/dev/PRODUCT_SPEC.md +0 -317
  149. package/core/dev/PROJECT_REGISTRY_DUPLICATE_ASSESSMENT.md +0 -86
  150. package/core/dev/STARTUP_TIMELINE_TASK_1995.md +0 -181
  151. package/core/dev/SYNAPSE_WORKER_PER_PROJECT.md +0 -881
  152. package/core/dev/TASK_1680_P3-3_DISPATCH_SPEC.md +0 -96
  153. package/core/dev/TASK_1684_CALIBRATION_IMPACT_ANALYSIS.md +0 -170
  154. package/core/dev/TASK_1684_FORK_A_GOODHART_DESIGN.md +0 -171
  155. package/core/dev/TASK_1684_P3_2_REMEASURE_VALIDATION.md +0 -262
  156. package/core/dev/TASK_1903_SIGNAL_AUC_MEASUREMENT.md +0 -207
  157. package/core/dev/TASK_1904_BRANCH_INTEGRITY_AUDIT.md +0 -146
  158. package/core/dev/ansuz-eval/README.md +0 -38
  159. package/core/dev/ansuz-eval/build-fixtures.js +0 -87
  160. package/core/dev/ansuz-eval/grade.js +0 -96
  161. package/core/dev/ansuz-eval/grader.test.js +0 -117
  162. package/core/dev/ansuz-eval/tasks.md +0 -32
  163. package/core/dev/archive/ansuz/BOOT_FULL.md +0 -141
  164. package/core/dev/archive/ansuz/agents/ansuz-boot.md +0 -176
  165. package/core/dev/archive/ansuz/designs/alaya-passive-surfacing.md +0 -84
  166. package/core/dev/archive/ansuz/designs/cc_memory_indexing.md +0 -307
  167. package/core/dev/archive/ansuz/designs/check_guard.md +0 -322
  168. package/core/dev/archive/ansuz/designs/consequence_loop.md +0 -227
  169. package/core/dev/archive/ansuz/designs/mcp_kuzudb_lock_architecture.md +0 -312
  170. package/core/dev/archive/ansuz/designs/phase0_git_enrichment.md +0 -278
  171. package/core/dev/archive/ansuz/designs/refactor_mcp_tools_synapse.md +0 -490
  172. package/core/dev/archive/ansuz/designs/semantic_markdown_extraction.md +0 -167
  173. package/core/dev/archive/ansuz/designs/task_1372_prompt_injects_into.md +0 -193
  174. package/core/dev/archive/ansuz/designs/thought_stack.md +0 -286
  175. package/core/dev/archive/ansuz/investigations/reachability_unified_api_2026-04-11.md +0 -330
  176. package/core/dev/archive/ansuz/investigations/synapse_orphans_indexing_bug_2026-04-11.md +0 -352
  177. package/core/dev/archive/ansuz/investigations/synapse_orphans_reindex_verification_2026-04-11.md +0 -48
  178. package/core/dev/archive/ansuz/investigations/synapse_orphans_verification_2026-04-11.md +0 -170
  179. package/core/dev/archive/ansuz/legacy/kernel.yaml +0 -399
  180. package/core/dev/archive/ansuz/legacy/phases/phase_0.yaml +0 -418
  181. package/core/dev/archive/ansuz/legacy/phases/phase_1.yaml +0 -376
  182. package/core/dev/archive/ansuz/legacy/phases/phase_10.yaml +0 -35
  183. package/core/dev/archive/ansuz/legacy/phases/phase_11.yaml +0 -582
  184. package/core/dev/archive/ansuz/legacy/phases/phase_2.yaml +0 -94
  185. package/core/dev/archive/ansuz/legacy/phases/phase_3.yaml +0 -274
  186. package/core/dev/archive/ansuz/legacy/phases/phase_4.yaml +0 -67
  187. package/core/dev/archive/ansuz/legacy/phases/phase_5.yaml +0 -32
  188. package/core/dev/archive/ansuz/legacy/phases/phase_6.yaml +0 -91
  189. package/core/dev/archive/ansuz/legacy/phases/phase_7.yaml +0 -58
  190. package/core/dev/archive/ansuz/legacy/phases/phase_8.yaml +0 -146
  191. package/core/dev/archive/ansuz/legacy/phases/phase_9.yaml +0 -424
  192. package/core/dev/archive/ansuz/specs/INDEX_bifrost_hook_parity.yaml +0 -92
  193. package/core/dev/archive/ansuz/specs/active-inference-formation.yaml +0 -453
  194. package/core/dev/archive/ansuz/specs/brief_TASK_1228_userpromptsubmit.yaml +0 -191
  195. package/core/dev/archive/ansuz/specs/brief_TASK_1229_pretooluse_posttooluse.yaml +0 -250
  196. package/core/dev/archive/ansuz/specs/brief_TASK_1230_sessionstart_stop.yaml +0 -301
  197. package/core/dev/archive/ansuz/specs/brief_TASK_1231_verification.yaml +0 -272
  198. package/core/dev/archive/skills/feature_agent/SKILL.md +0 -289
  199. package/core/dev/design/PHASE4_DESIGN.md +0 -559
  200. package/core/dev/design/dashboard_docs_integration_PLAN.md +0 -388
  201. package/core/dev/design/matrix_format_ABBREVIATIONS.md +0 -655
  202. package/core/dev/design/matrix_format_DESIGN_SPEC.md +0 -601
  203. package/core/dev/design/matrix_format_DISCUSSION_SUMMARY.md +0 -484
  204. package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +0 -13
  205. package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +0 -9
  206. package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +0 -14
  207. package/core/dev/design/matrix_format_SYNTAX_BNF.md +0 -754
  208. package/core/dev/design/matrix_format_TOKEN_COMPARISON.md +0 -484
  209. package/core/dev/design/matrix_v2_COGNITIVE_DESIGN.md +0 -503
  210. package/core/dev/design/matrix_v2_DISCUSSION_SUMMARY.md +0 -414
  211. package/core/dev/design/matrix_v2_EXAMPLE.matrix +0 -67
  212. package/core/dev/designs/EXPANDABLE_CARD_DESIGN_SPEC.md +0 -509
  213. package/core/dev/jev-eval/ACTIVE_CORRECTION.md +0 -52
  214. package/core/dev/jev-eval/ANNOTATION_GUIDE.md +0 -68
  215. package/core/dev/jev-eval/BASELINE_COMPARISON.md +0 -45
  216. package/core/dev/jev-eval/CONTEXT_REVIEW.md +0 -31
  217. package/core/dev/jev-eval/EVALUATION_STATUS.md +0 -39
  218. package/core/dev/jev-eval/HISTORICAL_CORPUS.md +0 -33
  219. package/core/dev/jev-eval/PACKAGING_VERIFICATION.md +0 -42
  220. package/core/dev/jev-eval/README.md +0 -101
  221. package/core/dev/jev-eval/THALAMUS_RANKING.md +0 -58
  222. package/core/dev/jev-eval/VALIDATION_PROGRESS.md +0 -54
  223. package/core/dev/jev-eval/cli.mjs +0 -50
  224. package/core/dev/jev-eval/context.mjs +0 -183
  225. package/core/dev/jev-eval/corpus.mjs +0 -186
  226. package/core/dev/jev-eval/fixtures/conversation-review.seed.jsonl +0 -6
  227. package/core/dev/jev-eval/fixtures/synthetic.jsonl +0 -11
  228. package/core/dev/jev-eval/metrics.mjs +0 -67
  229. package/core/dev/jev-eval/muninn-baseline.mjs +0 -119
  230. package/core/dev/jev-eval/providers.mjs +0 -95
  231. package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +0 -32
  232. package/core/dev/jev-eval/reports/context-review-2026-09-20.json +0 -48
  233. package/core/dev/jev-eval/reports/conversation-review.pending.json +0 -151
  234. package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +0 -52
  235. package/core/dev/jev-eval/reports/length-probe-2026-09-20.json +0 -133
  236. package/core/dev/jev-eval/reports/live-smoke-2026-09-20.json +0 -616
  237. package/core/dev/jev-eval/reports/muninn-baseline-2026-09-20.json +0 -52
  238. package/core/dev/jev-eval/reports/resilience-2026-09-20.json +0 -520
  239. package/core/dev/jev-eval/reports/rules-baseline.json +0 -197
  240. package/core/dev/jev-eval/reports/synthetic-review.pending.json +0 -357
  241. package/core/dev/jev-eval/resilience.mjs +0 -71
  242. package/core/dev/jev-eval/review.mjs +0 -78
  243. package/core/dev/jev-eval/schema.mjs +0 -87
  244. package/core/dev/jev-eval/test/context.test.mjs +0 -95
  245. package/core/dev/jev-eval/test/corpus.test.mjs +0 -102
  246. package/core/dev/jev-eval/test/eval.test.mjs +0 -146
  247. package/core/dev/jev-eval/test/muninn-baseline.test.mjs +0 -71
  248. package/core/dev/jev-eval/test/resilience.test.mjs +0 -72
  249. package/core/dev/jev-eval/test/review.test.mjs +0 -61
  250. package/core/dev/pipeline/PHASE3_PLANNING_SUMMARY.md +0 -338
  251. package/core/dev/pipeline/PROGRESS.md +0 -113
  252. package/core/dev/pipeline/PROGRESS_template.md +0 -860
  253. package/core/dev/pipeline/QA_REPORT_F008.md +0 -431
  254. package/core/dev/pipeline/QA_REPORT_LOCAL_CLAUDE_DIAGNOSIS.md +0 -583
  255. package/core/dev/pipeline/README.md +0 -210
  256. package/core/dev/pipeline/WORKFLOW_GUIDE.md +0 -824
  257. package/core/dev/pipeline/archived/TASK_015_tauri_init.yaml +0 -53
  258. package/core/dev/pipeline/archived/TASK_016_tauri_commands.yaml +0 -54
  259. package/core/dev/pipeline/archived/TASK_017_rust_pty.yaml +0 -54
  260. package/core/dev/pipeline/archived/TASK_018_tauri_bundle.yaml +0 -53
  261. package/core/dev/pipeline/archived/TASK_019_release_workflow.yaml +0 -56
  262. package/core/dev/pipeline/archived/TASK_020_update_ui.yaml +0 -54
  263. package/core/dev/pipeline/archived/TASK_021_update_notification_ui.yaml +0 -55
  264. package/core/dev/pipeline/archived/TASK_022_remove_node_pty.yaml +0 -65
  265. package/core/dev/pipeline/archived/TASK_023_api_routes_migration.yaml +0 -86
  266. package/core/dev/pipeline/archived/TASK_024_feature_id_system.yaml +0 -51
  267. package/core/dev/pipeline/archived/TASK_025_executable_acceptance.yaml +0 -66
  268. package/core/dev/pipeline/archived/TASK_026_spec_versioning.yaml +0 -56
  269. package/core/dev/pipeline/archived/TASK_027_drift_detection.yaml +0 -60
  270. package/core/dev/pipeline/archived/TASK_028_tauri_pty_manager.yaml +0 -60
  271. package/core/dev/pipeline/archived/TASK_029_tauri_pty_commands.yaml +0 -62
  272. package/core/dev/pipeline/archived/TASK_030_frontend_session_adapter.yaml +0 -54
  273. package/core/dev/pipeline/archived/TASK_031_terminal_tauri_events.yaml +0 -56
  274. package/core/dev/pipeline/archived/TASK_041_scheduler_data_models.yaml +0 -54
  275. package/core/dev/pipeline/archived/TASK_042_path_lock_manager.yaml +0 -53
  276. package/core/dev/pipeline/archived/TASK_043_process_manager.yaml +0 -57
  277. package/core/dev/pipeline/archived/TASK_044_git_integration.yaml +0 -85
  278. package/core/dev/pipeline/archived/TASK_045_task_queue_manager.yaml +0 -54
  279. package/core/dev/pipeline/archived/TASK_046_scheduler_dispatcher.yaml +0 -60
  280. package/core/dev/pipeline/archived/TASK_047_tauri_scheduler_commands.yaml +0 -55
  281. package/core/dev/pipeline/archived/TASK_048_realtime_status_push.yaml +0 -92
  282. package/core/dev/pipeline/archived/TASK_049_frontend_scheduler_integration.yaml +0 -58
  283. package/core/dev/pipeline/archived/TASK_050_error_recovery.yaml +0 -56
  284. package/core/dev/pipeline/archived/TASK_051_optimization_proposals_backend.yaml +0 -53
  285. package/core/dev/pipeline/archived/TASK_052_optimization_proposals_ui.yaml +0 -58
  286. package/core/dev/pipeline/archived/TASK_053_optimization_proposals_diff_view.yaml +0 -54
  287. package/core/dev/pipeline/archived/TASK_054_multi_project_scheduler_state.yaml +0 -76
  288. package/core/dev/pipeline/archived/TASK_055_scheduler_api_project_scope.yaml +0 -64
  289. package/core/dev/pipeline/archived/TASK_056_frontend_scheduler_project_scope.yaml +0 -62
  290. package/core/dev/pipeline/archived/TASK_057_scheduler_module_structure.yaml +0 -54
  291. package/core/dev/pipeline/archived/TASK_058_scheduler_models_extract.yaml +0 -51
  292. package/core/dev/pipeline/archived/TASK_059_scheduler_core_extract.yaml +0 -51
  293. package/core/dev/pipeline/archived/TASK_060_scheduler_commands_extract.yaml +0 -51
  294. package/core/dev/pipeline/archived/TASK_061_scheduler_specialized_commands.yaml +0 -53
  295. package/core/dev/pipeline/archived/TASK_062_process_manager_module_structure.yaml +0 -56
  296. package/core/dev/pipeline/archived/TASK_063_process_manager_core_extract.yaml +0 -56
  297. package/core/dev/pipeline/archived/TASK_064_recovery_module_structure.yaml +0 -57
  298. package/core/dev/pipeline/archived/TASK_065_recovery_core_extract.yaml +0 -56
  299. package/core/dev/pipeline/archived/TASK_066_self_enhancement_scheduler_models.yaml +0 -60
  300. package/core/dev/pipeline/archived/TASK_067_agents_section_quick_actions.yaml +0 -53
  301. package/core/dev/pipeline/archived/TASK_067_self_enhancement_scheduler_core.yaml +0 -65
  302. package/core/dev/pipeline/archived/TASK_068_agent_workflow_rule_enhancement.yaml +0 -46
  303. package/core/dev/pipeline/archived/TASK_068_self_enhancement_tauri_commands.yaml +0 -61
  304. package/core/dev/pipeline/archived/TASK_069_agent_wizard_responsive.yaml +0 -46
  305. package/core/dev/pipeline/archived/TASK_069_self_enhancement_ui.yaml +0 -62
  306. package/core/dev/pipeline/archived/TASK_070_preview_panel_redesign.yaml +0 -62
  307. package/core/dev/pipeline/archived/TASK_070_self_enhancement_integration.yaml +0 -57
  308. package/core/dev/pipeline/archived/TASK_071_preview_panel_qa.yaml +0 -98
  309. package/core/dev/pipeline/archived/TASK_071_single_agent_config.yaml +0 -57
  310. package/core/dev/pipeline/archived/TASK_072_preview_modal_esc_fix.yaml +0 -71
  311. package/core/dev/pipeline/archived/TASK_072_product_review_module.yaml +0 -57
  312. package/core/dev/pipeline/archived/TASK_073_agents_page_component_refactor.yaml +0 -68
  313. package/core/dev/pipeline/archived/TASK_073_rename_single_agent.yaml +0 -64
  314. package/core/dev/pipeline/archived/TASK_074_preview_mode_ui_diagnosis.yaml +0 -71
  315. package/core/dev/pipeline/archived/TASK_074_single_agent_ui_toggle.yaml +0 -56
  316. package/core/dev/pipeline/archived/TASK_075_agents_page_component_refactor.yaml +0 -69
  317. package/core/dev/pipeline/archived/TASK_075_single_agent_integration_test.yaml +0 -75
  318. package/core/dev/pipeline/archived/TASK_076_preview_mode_ui_diagnosis.yaml +0 -70
  319. package/core/dev/pipeline/archived/TASK_076_single_agent_continuous_mode.yaml +0 -65
  320. package/core/dev/pipeline/archived/TASK_077_failure_directory_structure.yaml +0 -51
  321. package/core/dev/pipeline/archived/TASK_077_single_agent_typescript_types.yaml +0 -59
  322. package/core/dev/pipeline/archived/TASK_078_fail_001_agent_no_output.yaml +0 -53
  323. package/core/dev/pipeline/archived/TASK_078_single_agent_ui_simplify.yaml +0 -74
  324. package/core/dev/pipeline/archived/TASK_079_dashboard_rwd_responsive.yaml +0 -63
  325. package/core/dev/pipeline/archived/TASK_079_fail_002_json_bom.yaml +0 -56
  326. package/core/dev/pipeline/archived/TASK_080_fail_003_queue_pollution.yaml +0 -56
  327. package/core/dev/pipeline/archived/TASK_080_http_server_module.yaml +0 -55
  328. package/core/dev/pipeline/archived/TASK_081_failure_logging_tools.yaml +0 -57
  329. package/core/dev/pipeline/archived/TASK_081_http_api_routes.yaml +0 -62
  330. package/core/dev/pipeline/archived/TASK_082_frontend_api_adapter.yaml +0 -51
  331. package/core/dev/pipeline/archived/TASK_082_integrate_failure_to_workflow.yaml +0 -60
  332. package/core/dev/pipeline/archived/TASK_083_cleanup_nextjs_api.yaml +0 -48
  333. package/core/dev/pipeline/archived/TASK_083_task_queue_cleanup.yaml +0 -67
  334. package/core/dev/pipeline/archived/TASK_084_rust_dead_code_cleanup.yaml +0 -66
  335. package/core/dev/pipeline/archived/TASK_084_scheduler_sync_logic_fix.yaml +0 -68
  336. package/core/dev/pipeline/archived/TASK_085_http_api_web_mode_fixes.yaml +0 -46
  337. package/core/dev/pipeline/archived/TASK_085_memory_consolidation_0204_0205.yaml +0 -98
  338. package/core/dev/pipeline/archived/TASK_086_collapsible_preview_panel.yaml +0 -161
  339. package/core/dev/pipeline/archived/TASK_086_web_mode_feature_parity.yaml +0 -62
  340. package/core/dev/pipeline/archived/TASK_087_manual_memory_archival.yaml +0 -163
  341. package/core/dev/pipeline/archived/TASK_087_mobile_http_control.yaml +0 -68
  342. package/core/dev/pipeline/archived/TASK_088_fail_003_to_ppl_002_rule.yaml +0 -63
  343. package/core/dev/pipeline/archived/TASK_088_mobile_http_qa.yaml +0 -121
  344. package/core/dev/pipeline/archived/TASK_089_agent_collaboration_topic.yaml +0 -60
  345. package/core/dev/pipeline/archived/TASK_089_web_mode_monitor_fix.yaml +0 -58
  346. package/core/dev/pipeline/archived/TASK_090_cli_detection_fix.yaml +0 -61
  347. package/core/dev/pipeline/archived/TASK_090_ui_ux_lessons_topic.yaml +0 -63
  348. package/core/dev/pipeline/archived/TASK_091_expandable_card_design.yaml +0 -56
  349. package/core/dev/pipeline/archived/TASK_091_move_agent_section_components.yaml +0 -65
  350. package/core/dev/pipeline/archived/TASK_092_expandable_card_component.yaml +0 -60
  351. package/core/dev/pipeline/archived/TASK_092_refactor_agent_create_wizard.yaml +0 -84
  352. package/core/dev/pipeline/archived/TASK_093_taskcard_detail_integration.yaml +0 -57
  353. package/core/dev/pipeline/archived/TASK_093_update_barrel_exports_test.yaml +0 -84
  354. package/core/dev/pipeline/archived/TASK_094_ai_agent_generation_enhancement.yaml +0 -115
  355. package/core/dev/pipeline/archived/TASK_094_proposalcard_detail_integration.yaml +0 -55
  356. package/core/dev/pipeline/archived/TASK_095_preview_fixes.yaml +0 -129
  357. package/core/dev/pipeline/archived/TASK_095_single_agent_task_selector.yaml +0 -60
  358. package/core/dev/pipeline/archived/TASK_096_agents_page_ux_improvements.yaml +0 -163
  359. package/core/dev/pipeline/archived/TASK_096_single_agent_status_sync.yaml +0 -60
  360. package/core/dev/pipeline/archived/TASK_097_local_claude_error_logging.yaml +0 -59
  361. package/core/dev/pipeline/archived/TASK_097_single_agent_monitor_events.yaml +0 -59
  362. package/core/dev/pipeline/archived/TASK_098_product_manager_team_phase2.yaml +0 -60
  363. package/core/dev/pipeline/archived/TASK_098_single_agent_refactor_test.yaml +0 -58
  364. package/core/dev/pipeline/archived/TASK_099_backend_team_creation.yaml +0 -258
  365. package/core/dev/pipeline/archived/TASK_100_frontend_team_creation.yaml +0 -61
  366. package/core/dev/pipeline/archived/TASK_101_orchestrator_system.yaml +0 -403
  367. package/core/dev/pipeline/archived/TASK_102_designer_sre_teams.yaml +0 -90
  368. package/core/dev/pipeline/archived/TASK_103_integration_testing.yaml +0 -86
  369. package/core/dev/pipeline/archived/TASK_128_integration_testing.yaml +0 -83
  370. package/core/dev/pipeline/archived/TASK_134_cortex_v2_phase3_file_watcher.yaml +0 -65
  371. package/core/dev/pipeline/archived/TASK_134_team_http_api.yaml +0 -96
  372. package/core/dev/pipeline/archived/TASK_135_cortex_v2_phase3_git_monitor.yaml +0 -63
  373. package/core/dev/pipeline/archived/TASK_136_cortex_v2_phase3_change_analyzer.yaml +0 -69
  374. package/core/dev/pipeline/archived/TASK_137_cortex_v2_phase3_cache_invalidator.yaml +0 -67
  375. package/core/dev/pipeline/archived/TASK_137_team_orchestrator_integration.yaml +0 -93
  376. package/core/dev/pipeline/archived/TASK_138_cortex_v2_phase3_distributed_cache.yaml +0 -68
  377. package/core/dev/pipeline/archived/TASK_138_matrix_folder_structure.yaml +0 -61
  378. package/core/dev/pipeline/archived/TASK_139_cortex_v2_phase3_cache_prewarming.yaml +0 -65
  379. package/core/dev/pipeline/archived/TASK_146_unified_documentation.yaml +0 -141
  380. package/core/dev/pipeline/archived/TASK_147_pipeline_execution_rules.yaml +0 -76
  381. package/core/dev/pipeline/archived/TASK_148_update_claude_md.yaml +0 -77
  382. package/core/dev/pipeline/archived/TASK_149_fix_nextjs_mdx_serialization.yaml +0 -63
  383. package/core/dev/pipeline/archived/TASK_149_update_team_docs.yaml +0 -77
  384. package/core/dev/pipeline/archived/TASK_150_pipeline_workflow_guide.yaml +0 -82
  385. package/core/dev/pipeline/archived/TASK_164_fix_smart_context_switch.yaml +0 -49
  386. package/core/dev/pipeline/archived/TASK_165_ctags_symbol_index.yaml +0 -53
  387. package/core/dev/pipeline/archived/TASK_166_symbol_search_mcp_tool.yaml +0 -48
  388. package/core/dev/pipeline/archived/TASK_167_llm_module_summary.yaml +0 -55
  389. package/core/dev/pipeline/archived/TASK_168_map_reduce_context.yaml +0 -51
  390. package/core/dev/pipeline/archived/TASK_169_v2_integration_testing.yaml +0 -52
  391. package/core/dev/pipeline/backups/archive_2026-02-04T22-07-22/TASK_QUEUE_backup.json +0 -95
  392. package/core/dev/pipeline/docs/multi-agent-coordination.md +0 -446
  393. package/core/dev/pipeline/docs/overview.md +0 -406
  394. package/core/dev/pipeline/docs/task-management.md +0 -412
  395. package/core/dev/pipeline/docs/workflows.md +0 -32
  396. package/core/dev/pipeline/orchestrator/schemas/task_queue_schema.json +0 -58
  397. package/core/dev/pipeline/orchestrator/schemas/task_schema.json +0 -139
  398. package/core/dev/pipeline/plans/PLAN_task_cli_refactor.md +0 -281
  399. package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +0 -27
  400. package/core/dev/plans/ANSUZ_SLIM_PLAN.md +0 -68
  401. package/core/dev/plans/CLI_FIRST_INSTALL_FLOW.md +0 -120
  402. package/core/dev/plans/FORMATION_RETIREMENT_PLAN.md +0 -313
  403. package/core/dev/plans/KUZU_REPLACEMENT_PLAN.md +0 -126
  404. package/core/dev/scripts/CRASH_DIAGNOSIS.md +0 -47
  405. package/core/dev/scripts/README.md +0 -142
  406. package/core/dev/scripts/RUN_ONCE.bat +0 -40
  407. package/core/dev/scripts/START_DEV_AGENT.bat +0 -63
  408. package/core/dev/scripts/START_MULTI_AGENT.bat +0 -80
  409. package/core/dev/scripts/dev_agent_scheduler.ps1 +0 -536
  410. package/core/dev/scripts/init_git.ps1 +0 -396
  411. package/core/dev/scripts/init_git.sh +0 -337
  412. package/core/dev/scripts/init_project.ps1 +0 -851
  413. package/core/dev/scripts/init_project.sh +0 -477
  414. package/core/dev/scripts/multi_agent_scheduler.ps1 +0 -2021
  415. package/core/dev/scripts/multi_agent_scheduler.sh +0 -1344
  416. package/core/dev/scripts/run_once.sh +0 -47
  417. package/core/dev/scripts/setup_rag.ps1 +0 -304
  418. package/core/dev/scripts/setup_rag.sh +0 -230
  419. package/core/dev/scripts/start_dev_agent.sh +0 -137
  420. package/core/dev/scripts/start_multi_agent.sh +0 -41
  421. package/core/dev/scripts/sync_task_queue.ps1 +0 -505
  422. package/core/dev/scripts/sync_task_queue.sh +0 -392
  423. package/core/dev/specs/agent-connect/PROTOCOL.md +0 -177
  424. package/core/dev/specs/agent-connect/SDK_GUIDE.md +0 -915
  425. package/core/dev/specs/agent-connect/examples/minimal-site/README.md +0 -137
  426. package/core/dev/specs/agent-connect/examples/minimal-site/package.json +0 -12
  427. package/core/dev/specs/agent-connect/examples/minimal-site/public/index.html +0 -116
  428. package/core/dev/specs/agent-connect/examples/minimal-site/public/install-redirect.js +0 -73
  429. package/core/dev/specs/agent-connect/examples/minimal-site/server.js +0 -516
  430. package/core/dev/specs/agent-connect/examples/minimal-site/test/smoke.test.mjs +0 -263
  431. package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-empty-prompt-no-first-turn.md +0 -77
  432. package/core/dev/specs/agent-connect/history/DEFECT_REPORT_kenaz-agent-hub_2026-09-09_v0.4-prompt-mojibake.md +0 -90
  433. package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md +0 -61
  434. package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-08_relay-v1-conformance.md +0 -76
  435. package/core/dev/specs/agent-connect/history/FEATURE_REQUEST_kenaz-agent-hub_2026-09-09_v0.4-session-channel.md +0 -87
  436. package/core/dev/specs/agent-connect/history/FLOWPIX_REPLY_agent-hub_2026-09-08_relay-v1-answers.md +0 -68
  437. package/core/dev/specs/agent-connect/history/FLOWPIX_bridge_CONTRACT.md +0 -642
  438. package/core/dev/specs/agent-connect/history/FLOWPIX_spikes_relay_spike_relay.mjs +0 -244
  439. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-07.md +0 -77
  440. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_direction-change-v0.3.md +0 -44
  441. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-answers-ack.md +0 -37
  442. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-08_relay-v1-conformance.md +0 -56
  443. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_annotations-install-coldstart.md +0 -44
  444. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_empty-prompt-first-turn.md +0 -56
  445. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_prompt-mojibake-fixed.md +0 -48
  446. package/core/dev/specs/agent-connect/history/KENAZ_RESPONSE_agent-hub_2026-09-09_session-channel.md +0 -57
  447. package/core/dev/specs/agent-connect/history/PROTOCOL_v0.3_snapshot.md +0 -379
  448. package/core/dev/specs/agent-connect/history/README.md +0 -47
  449. package/core/dev/specs/peer/CODEX_INTERACTIVE_PUSH.md +0 -65
  450. package/core/dev/specs/peer/CODEX_MANAGED_DAEMON.md +0 -54
  451. package/core/dev/specs/peer/CODEX_PEER_PULL_SPIKE.md +0 -54
  452. package/core/dev/specs/peer/MODS_SPIKE.md +0 -133
  453. package/core/dev/specs/peer/PER_PROJECT_ADDRESSING.md +0 -143
  454. package/core/dev/specs/peer/SWARM_PROTOCOLS.md +0 -256
  455. package/core/dev/specs/peer/codex-hook-shim-peer.test.js +0 -113
  456. package/core/dev/specs/peer/codex-push-launcher.test.js +0 -142
  457. package/core/dev/specs/peer/setup-codex-hooks.test.js +0 -60
  458. package/core/dev/specs/peer-ansuz/DELIVERY_SPIKE.md +0 -397
  459. package/core/dev/specs/peer-ansuz/DESIGN.md +0 -109
  460. package/core/dev/specs/peer-ansuz/spike/claude_poke.js +0 -129
  461. package/core/dev/specs/peer-ansuz/spike/claude_session_start_hook.js +0 -37
  462. package/core/dev/specs/peer-ansuz/spike/claude_settings_hook.json +0 -14
  463. package/core/dev/specs/peer-ansuz/spike/codex_appserver_client.js +0 -105
  464. package/core/dev/specs/peer-ansuz/spike/codex_appserver_query.js +0 -29
  465. package/core/dev/specs/peer-ansuz/spike/extract_timeline.js +0 -26
  466. package/core/dev/specs/synapse/SYMBOL_IDENTITY.md +0 -305
  467. package/core/dev/spikes/A4-cypher-varlen.md +0 -176
  468. package/core/dev/spikes/bloat-rounds.sh +0 -25
  469. package/core/dev/spikes/mods/clean-claude.js +0 -9
  470. package/core/dev/spikes/mods/drive-probe.js +0 -29
  471. package/core/dev/spikes/mods/e2e-peer.js +0 -71
  472. package/core/dev/spikes/mods/evidence/e2e-peer-control.json +0 -17
  473. package/core/dev/spikes/mods/evidence/e2e-peer-mod.json +0 -17
  474. package/core/dev/spikes/mods/evidence/probe-006a6e65-d807-4bc1-b648-fd7d1edfe0b4.jsonl +0 -4
  475. package/core/dev/spikes/mods/evidence/probe-cebdf1f7-f9c4-47a8-83cd-7c0786177404.jsonl +0 -12
  476. package/core/dev/spikes/mods/evidence/probe-eb21147d-10ce-4c32-93ed-37ca37d88d5a.jsonl +0 -11
  477. package/core/dev/spikes/mods/evidence/stream-cebdf1f7.jsonl +0 -18
  478. package/core/dev/spikes/mods/kenaz-mod-probe/.claude-plugin/plugin.json +0 -1
  479. package/core/dev/spikes/mods/kenaz-mod-probe/hooks/hooks.json +0 -1
  480. package/core/dev/spikes/mods/kenaz-mod-probe/hooks/register.ts +0 -65
  481. package/core/dev/spikes/mods/kenaz-mod-probe/tsconfig.json +0 -3
@@ -1,642 +0,0 @@
1
- # bridge HTTP contract v1 (TASK_96)
2
-
3
- Field names here are the wire contract -- backend/image_generation.py and
4
- backend/text_generation.py (the bridge's only clients, over stdlib
5
- `urllib.request`) and this document must never drift apart. Base URL
6
- defaults to `http://127.0.0.1:8790`, overridable via `GAMEASSET_BRIDGE_URL`
7
- on the backend side and `GAMEASSET_BRIDGE_HOST` / `GAMEASSET_BRIDGE_PORT` on
8
- the bridge side.
9
-
10
- ## `GET /health`
11
-
12
- ```json
13
- {
14
- "ok": true,
15
- "bridge_version": "1.0.0",
16
- "default_provider": "codex",
17
- "providers": [
18
- {"id": "codex", "available": true, "detail": "codex 0.153.4, Logged in using ChatGPT; transport=appserver; usage 34% of 10080min window, resets 2026-09-14T08:33:13+00:00"},
19
- {"id": "openai", "available": false, "detail": "OPENAI_API_KEY environment variable is not set"}
20
- ]
21
- }
22
- ```
23
-
24
- - `codex`'s `available` = `codex --version` exits 0 AND `codex login status`
25
- reports `Logged in` -- independent of which transport is configured (both
26
- need the same logged-in CLI).
27
- - `openai`'s `available` = `OPENAI_API_KEY` has a non-empty value.
28
- - `codex`'s `detail` (TASK_98 R5) always appends `; transport=<appserver|exec>`
29
- (`GAMEASSET_BRIDGE_CODEX_TRANSPORT`, default `appserver`); once at least
30
- one `appserver`-transport call has completed and cached an
31
- `account/rateLimits/updated` notification, it further appends `; usage
32
- <usedPercent>% of <windowDurationMins>min window, resets <ISO time>`. The
33
- usage suffix is absent before any such call, and never appears for the
34
- `exec` transport (which has no persistent connection to receive the
35
- notification on).
36
-
37
- ## `POST /v1/image`
38
-
39
- Request:
40
-
41
- ```json
42
- {
43
- "provider": "codex",
44
- "prompt": "a three-quarter view of the attached garment",
45
- "size": "1024x1024",
46
- "quality": "medium",
47
- "reference_images": ["<base64 PNG>", "..."]
48
- }
49
- ```
50
-
51
- `provider` is optional -- omit it (or send `null`) to let the bridge decide
52
- (see "Provider selection" below).
53
-
54
- Response (200):
55
-
56
- ```json
57
- {
58
- "image_png_b64": "<base64 PNG>",
59
- "width": 1024,
60
- "height": 1024,
61
- "provider": "codex",
62
- "elapsed_ms": 48213,
63
- "meta": {"thread_id": "01a07574-...", "transport": "appserver", "rate_limits": {"...": "..."}}
64
- }
65
- ```
66
-
67
- `meta` is provider-specific and best-effort -- callers must not depend on
68
- any particular key being present. For the `codex` provider (TASK_98 R1/R5):
69
-
70
- - `thread_id` -- the (ephemeral) codex thread this call ran in, both
71
- transports.
72
- - `transport` -- `"appserver"` or `"exec"`, whichever transport actually
73
- ran this call. When `GAMEASSET_BRIDGE_CODEX_TRANSPORT=appserver` (the
74
- default) but the app-server subprocess could not be spawned or never
75
- became healthy within 10s, THIS SINGLE CALL falls back to `exec`
76
- automatically (R6) -- `transport` reads `"exec"` and an additional
77
- `fallback_reason` key explains why. This is a same-provider transport
78
- fallback, not the silent `codex`-to-`openai` provider substitution R3
79
- forbids elsewhere in this document.
80
- - `rate_limits` -- present only for the `appserver` transport, only once at
81
- least one `account/rateLimits/updated` notification has been received
82
- (the same object surfaced in `GET /health`'s usage summary, see above).
83
-
84
- ## `POST /v1/text`
85
-
86
- Request:
87
-
88
- ```json
89
- {
90
- "provider": null,
91
- "prompt": "describe this garment in under 60 words",
92
- "system": "",
93
- "model": "gpt-5.6-sol",
94
- "max_output_tokens": 4096,
95
- "reasoning_effort": "auto",
96
- "reference_images": ["<base64 PNG>"]
97
- }
98
- ```
99
-
100
- Response (200):
101
-
102
- ```json
103
- {
104
- "text": "...",
105
- "provider": "openai",
106
- "elapsed_ms": 3120,
107
- "meta": {"model": "gpt-5.6-sol"}
108
- }
109
- ```
110
-
111
- ## Provider selection (R3)
112
-
113
- 1. `request.provider`, if given explicitly.
114
- 2. `GAMEASSET_BRIDGE_DEFAULT_PROVIDER` environment variable, if set.
115
- 3. `'codex'`.
116
-
117
- If the selected provider is not registered, or registered but its `probe()`
118
- reports `available: false`, the bridge answers `422 provider_unavailable`.
119
- **It never silently substitutes a different provider** -- a user who asked
120
- for (or defaulted to) their ChatGPT subscription and got a silent fallback
121
- to the API-key provider would be burning paid API credits without knowing
122
- it.
123
-
124
- ## Errors
125
-
126
- Every non-2xx response is:
127
-
128
- ```json
129
- {"error": {"code": "provider_unavailable" | "provider_failed" | "provider_timeout" | "invalid_request", "message": "..."}}
130
- ```
131
-
132
- | HTTP status | `code` | Meaning |
133
- |---|---|---|
134
- | 422 | `provider_unavailable` | Unknown provider id, or the selected provider's `probe()` failed. |
135
- | 422 | `invalid_request` | Malformed request body (e.g. a `reference_images` entry that isn't valid base64). |
136
- | 502 | `provider_failed` | The provider ran but the generation itself failed (process error, empty response, moderation refusal, ...). |
137
- | 504 | `provider_timeout` | The provider exceeded its own timeout ceiling (image: 300s, text: 180s for the codex provider; the openai provider's SDK client is configured with a 180s timeout for both). |
138
-
139
- `message` never contains `OPENAI_API_KEY` or any other secret/token value.
140
-
141
- ## CORS (R10)
142
-
143
- Allowed origins: `GAMEASSET_BRIDGE_ALLOWED_ORIGINS` (comma-separated),
144
- default `http://localhost:5173,http://127.0.0.1:5173`. Every preflight
145
- (`OPTIONS`) response additionally carries
146
- `Access-Control-Allow-Private-Network: true` (Chrome's Private Network
147
- Access check) -- header only, no relay/queueing logic; a future
148
- cloud-hosted page proxying through this bridge is a separate card.
149
-
150
- ---
151
-
152
- # Agent hub v1 (TASK_99)
153
-
154
- Turns the bridge into a local relay between a CLI agent (Codex / Claude
155
- Code) and the FlowPix canvas tab(s) the user has open in their browser. The
156
- bridge never touches the backend's saved-workflow API for any of this --
157
- every tool call below acts on a tab's LIVE, possibly-unsaved, in-page graph
158
- (the page-side executor is a separate card; this document is its contract).
159
-
160
- Implementation: `bridge/agent_hub/hub.py` (session registry + addressing +
161
- request/response relay), `bridge/agent_hub/auth.py` (token + `/mcp` guard),
162
- `bridge/agent_hub/tools.py` (the MCP tool set below), wired into
163
- `bridge/main.py`.
164
-
165
- ## `/mcp` -- CLI agent entry point
166
-
167
- A streamable-HTTP MCP server (python `mcp>=2.1`, `MCPServer`), mounted into
168
- this same FastAPI app on the same port (8790 by default). Every request
169
- must carry `Authorization: Bearer <token>`, or the guard middleware answers
170
- before the request reaches MCP:
171
-
172
- | Condition | Response |
173
- |---|---|
174
- | `Origin` header present at all | `403 {"error":{"code":"forbidden","message":"..."}}` -- this path is for local non-browser programs only; a real browser page always sends `Origin` cross-origin. |
175
- | Missing/invalid `Authorization: Bearer <token>` | `401 {"error":{"code":"unauthorized","message":"..."}}` |
176
-
177
- **Token** resolution (`bridge/agent_hub/auth.get_agent_token`): env var
178
- `GAMEASSET_BRIDGE_AGENT_TOKEN`, else `storage/bridge/agent_token.txt`
179
- (created with a fresh 32-hex-char token on first read if neither exists).
180
- Never logged, never included in any error message.
181
-
182
- At real ASGI startup the bridge prints three ready-to-paste setup steps
183
- (TASK_102 -- a two-line banner that never told the user to set
184
- `FLOWPIX_MCP_TOKEN` produced codex's own "Environment variable
185
- FLOWPIX_MCP_TOKEN ... is not set" error the moment the user tried step 2):
186
-
187
- ```
188
- 1) 設定 token 環境變數
189
- PowerShell: setx FLOWPIX_MCP_TOKEN "<token>"
190
- bash: export FLOWPIX_MCP_TOKEN="<token>"
191
- 2) 接上 Codex CLI
192
- PowerShell: codex mcp add flowpix --url http://127.0.0.1:<port>/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN
193
- bash: codex mcp add flowpix --url http://127.0.0.1:<port>/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN
194
- 3) 接上 Claude Code
195
- PowerShell: claude mcp add --transport http flowpix http://127.0.0.1:<port>/mcp --header "Authorization: Bearer <token>"
196
- bash: claude mcp add --transport http flowpix http://127.0.0.1:<port>/mcp --header 'Authorization: Bearer <token>'
197
- ```
198
-
199
- Shell correctness (TASK_102 R4): single quotes are NOT shell quoting in
200
- cmd.exe or PowerShell -- pasting the old single-quoted `claude mcp add`
201
- line there sent claude a literal `Bearer` argument with the quotes and
202
- token stripped off, and claude answered `Invalid header format: "Bearer".
203
- Expected format: "Header-Name: value"`. Double quotes ARE valid quoting in
204
- cmd.exe, PowerShell **and** bash/zsh/sh, so every `powershell` variant
205
- above uses double quotes (safe to paste into cmd.exe too); only the `bash`
206
- variant still uses single quotes.
207
-
208
- **Do not use `--dangerously-bypass-approvals-and-sandbox` for normal use.**
209
- It exists only so this card's own automated test (AC5) can drive `codex
210
- exec` non-interactively against a throwaway fake canvas and an empty
211
- directory; a real CLI agent session should let its OWN approval mechanism
212
- gate `run_workflow` (see below) -- the bridge does not gate it a second
213
- time.
214
-
215
- **Client timeout trap (TASK_106)**: a python `mcp` client built by wrapping
216
- its own `httpx2.AsyncClient(headers={"Authorization": ...})` for the Bearer
217
- header -- instead of `mcp.shared._httpx_utils.create_mcp_http_client()`,
218
- which sets an SSE-friendly `read=300s` -- silently inherits `httpx2`'s bare
219
- default `Timeout(5.0)`. Any tool call whose SSE response takes longer than
220
- 5s to arrive (e.g. `get_output`, whose own server-side timeout is 60s --
221
- see the `canvas_timeout` row in the Errors table below) then gets its
222
- connection torn down by the CLIENT itself, surfacing as `mcp`'s own
223
- "SSE stream ended without a response" -- indistinguishable, from the
224
- agent's side, from the bridge actually dropping the response. Any client
225
- constructed here (or in a script driving this bridge) that adds its own
226
- `headers=` MUST also pass an explicit `timeout=httpx2.Timeout(30.0,
227
- read=900.0)` (or otherwise route through `create_mcp_http_client`) so a
228
- long-running tool's own timeout error (`canvas_timeout`) has a chance to
229
- reach the client before the client's own read timeout does. (TASK_107:
230
- `run_workflow` itself no longer runs long enough to hit this trap -- it now
231
- answers as soon as the job is accepted, same shape as a quick edit -- but
232
- the trap still applies to any tool whose SSE response can legitimately take
233
- more than 5s, `get_output` included.)
234
-
235
- ## `GET /agent/setup`
236
-
237
- CORS-scoped like every other non-`/mcp` route (`GAMEASSET_BRIDGE_ALLOWED_ORIGINS`).
238
- Feeds the editor's connection panel:
239
-
240
- ```json
241
- {
242
- "mcp_url": "http://127.0.0.1:8790/mcp",
243
- "token": "<32 hex chars>",
244
- "steps": [
245
- {
246
- "id": "set_token",
247
- "title": "設定 token 環境變數",
248
- "powershell": "setx FLOWPIX_MCP_TOKEN \"<token>\"",
249
- "bash": "export FLOWPIX_MCP_TOKEN=\"<token>\"",
250
- "note": "PowerShell(setx):設定後只對之後開啟的新終端機生效,本視窗要重開;Bash(export):只在目前這個 shell session 有效,要寫進 ~/.bashrc(或 ~/.zshrc)才能持久。"
251
- },
252
- {
253
- "id": "codex_add",
254
- "title": "接上 Codex CLI",
255
- "powershell": "codex mcp add flowpix --url http://127.0.0.1:8790/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN",
256
- "bash": "codex mcp add flowpix --url http://127.0.0.1:8790/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN"
257
- },
258
- {
259
- "id": "claude_add",
260
- "title": "接上 Claude Code",
261
- "powershell": "claude mcp add --transport http flowpix http://127.0.0.1:8790/mcp --header \"Authorization: Bearer <token>\"",
262
- "bash": "claude mcp add --transport http flowpix http://127.0.0.1:8790/mcp --header 'Authorization: Bearer <token>'"
263
- }
264
- ],
265
- "commands": {
266
- "codex": "codex mcp add flowpix --url http://127.0.0.1:8790/mcp --bearer-token-env-var FLOWPIX_MCP_TOKEN",
267
- "claude_code": "claude mcp add --transport http flowpix http://127.0.0.1:8790/mcp --header \"Authorization: Bearer <token>\""
268
- },
269
- "connected_canvases": [
270
- {"session_id": "...", "tab_id": "...", "workflow_name": "...", "workflow_id": null, "dirty": false, "running": false}
271
- ]
272
- }
273
- ```
274
-
275
- `steps` (TASK_102) is the panel's actual data source -- an ordered array,
276
- `set_token` first, with the token already substituted into every command
277
- (nothing left for the user to fill in themselves). `commands` is a legacy
278
- field kept for backward compatibility (TASK_100); `claude_code` there was
279
- switched to the same double-quoted form as `steps.claude_add.powershell`
280
- (TASK_102 R4) since double quotes work in every shell this field might be
281
- pasted into.
282
-
283
- ## `/ws/canvas` -- FlowPix tab entry point
284
-
285
- A WebSocket endpoint. One connection per browser tab; the page connects,
286
- not the bridge. Origin is checked BEFORE `accept()`:
287
-
288
- - Origin missing, or not in `GAMEASSET_BRIDGE_ALLOWED_ORIGINS` -> the
289
- connection is accepted then immediately closed with code `1008` (policy
290
- violation) -- no `welcome` is ever sent. (An equivalent pre-accept HTTP
291
- 403 denial is also acceptable to a client; the bridge currently always
292
- uses accept-then-close because it does not depend on the ASGI server
293
- advertising the websocket-denial-response extension.)
294
- - Origin allowed -> accepted, and the tab must send `hello` as its first
295
- message.
296
-
297
- **Handshake:**
298
-
299
- ```
300
- tab -> bridge: {"type": "hello", "tab_id": "<string>", "workflow_name": "<string>", "workflow_id": "<string>|null", "client_version": "<string>", "page_id": "<string>|null"}
301
- bridge -> tab: {"type": "welcome", "session_id": "<string>"}
302
- ```
303
-
304
- `page_id` (TASK_103, optional) identifies which BROWSER PAGE this tab
305
- belongs to -- every tab a single page opens (see `create_canvas` below)
306
- sends the SAME `page_id` in its own hello (AgentBridgeClient.ts computes it
307
- once, module-level, and every AgentBridgeClient instance on that page reads
308
- it). Omitted/`null` is accepted (an older client, or a test fixture) and
309
- simply never groups with anything.
310
-
311
- Anything other than `{"type": "hello", ...}` as the first message closes
312
- the connection (code `1008`) without a `welcome`.
313
-
314
- **Re-addressing** (the tab changed which workflow it shows, without
315
- reconnecting):
316
-
317
- ```
318
- tab -> bridge: {"type": "state", "workflow_name": "<string>", "workflow_id": "<string>|null", "dirty": <bool>, "running": <bool>}
319
- ```
320
-
321
- Each field is optional and merged into the session (omitted fields keep
322
- their previous value).
323
-
324
- One session per connection; a session is removed the instant its
325
- connection closes (any tool call still in flight for it fails immediately
326
- with `canvas_disconnected` instead of waiting out its timeout).
327
-
328
- ## Tool-call relay protocol (R4)
329
-
330
- ```
331
- bridge -> tab: {"type": "call", "request_id": "<string>", "tool": "<string>", "args": {...}}
332
- tab -> bridge: {"type": "result", "request_id": "<string>", "ok": true, "result": <any>}
333
- | {"type": "result", "request_id": "<string>", "ok": false, "error": {"code": "<string>", "message": "<string>"}}
334
- ```
335
-
336
- - `request_id` is a fresh random id per call (never reused), so multiple
337
- calls to the same tab may be in flight concurrently; the bridge matches
338
- each `result` back to its own caller by `request_id` alone (never "the
339
- most recent call").
340
- - Timeout: 30s for every tool except `get_output` (60s). On timeout the
341
- bridge answers the MCP caller with `canvas_timeout` (see Errors below);
342
- it does NOT resend the call, and a result that arrives after the timeout
343
- is silently dropped.
344
- - `args` never includes `workflow` -- that field only selects WHICH tab
345
- the call is delivered to (see Addressing below); the tab already knows
346
- its own identity.
347
-
348
- ## MCP tool set v1
349
-
350
- Every tool's first argument is `workflow: str` (a `workflow_name` or a
351
- `session_id` -- see Addressing) EXCEPT `list_canvases` (takes none) and
352
- `create_canvas` (takes `name: str` instead -- there is no canvas yet to
353
- address).
354
- `args` sent to the tab is exactly the tool's OTHER arguments, as shown per
355
- tool below.
356
-
357
- | Tool | Args to tab | Result (from tab, via MCP) |
358
- |---|---|---|
359
- | `list_canvases()` | -- (not forwarded; answered by the bridge itself) | `[{"session_id", "tab_id", "workflow_name", "workflow_id", "dirty", "running", "page_id"}, ...]` |
360
- | `create_canvas(name)` | `{"name"}` -- forwarded to the MOST RECENTLY CONNECTED session (see below), not to an addressed `workflow` | `{"session_id", "tab_id", "workflow_name"}` for the BRAND-NEW tab |
361
- | `focus_canvas(workflow)` | `{}` | `{"tab_id", "workflow_name"}` |
362
- | `get_canvas(workflow)` | `{}` | `{"nodes": [{"id","type","params","position","status","error"}, ...], "edges": [...]}` |
363
- | `list_node_types(workflow)` | `{}` | `[{"type_id","display_name","inputs","outputs","params": [{"name","type","default","options"?,"min"?,"max"?}]}]` |
364
- | `add_node(workflow, type_id, params=None, position=None)` | `{"type_id","params","position"}` | `{"node_id": "<string>"}` |
365
- | `connect_nodes(workflow, source_node, source_port, target_node, target_port)` | `{"source_node","source_port","target_node","target_port"}` | `{}` (or any tab-defined ack) |
366
- | `set_params(workflow, node_id, params)` | `{"node_id","params"}` | `{}` |
367
- | `delete_node(workflow, node_id)` | `{"node_id"}` | `{}` |
368
- | `save_workflow(workflow)` | `{}` | `{"workflow_id": "<string>"}` |
369
- | `run_workflow(workflow, ignore_cache=False)` (TASK_107: returns as soon as the job is ACCEPTED, not when it finishes -- poll `get_job` for the rest) | `{"ignore_cache"}` | `{"job_id": "<string>"}` |
370
- | `get_job(workflow, job_id)` | `{"job_id"}` | `{"status": "<string>", "nodes": {"<node_id>": {"status","error"}}}` |
371
- | `get_output(workflow, node_id, port=None)` | `{"node_id","port"}` | see below |
372
-
373
- **`get_output`'s result shape from the tab** (TN5 -- the ONLY tool whose
374
- tab-side result is itself typed, because the bridge must convert it into
375
- real MCP content, not just relay JSON):
376
-
377
- ```json
378
- {"kind": "image", "mime_type": "image/png", "data_b64": "<base64 PNG>"}
379
- ```
380
- or
381
- ```json
382
- {"kind": "text", "text": "<string>"}
383
- ```
384
-
385
- The bridge turns `kind:"image"` into MCP `ImageContent(type="image",
386
- mimeType, data=<the same base64>)` -- the agent sees a real image, never a
387
- base64 string dressed up as text. `kind:"text"` becomes the tool's plain
388
- text result.
389
-
390
- ## `create_canvas` protocol (TASK_103 R1/TN2)
391
-
392
- `create_canvas` has no `workflow` to address by -- there is no canvas yet.
393
- Instead:
394
-
395
- 1. The bridge picks the single MOST RECENTLY CONNECTED `/ws/canvas` session
396
- (regardless of `workflow_name`/`page_id`) and forwards `{"tool":
397
- "create_canvas", "args": {"name": name}}` to it, exactly like any other
398
- tool call. Zero sessions connected at all -> `no_canvas` (the bridge
399
- cannot open a browser tab on its own).
400
- 2. That tab opens a brand-new, empty tab named `name` and switches its own
401
- UI to it, then answers the call with `{"tab_id": "<the new tab's id>"}`.
402
- A tab named `name` already open -> the tab answers `{"ok": false,
403
- "error": {"code": "canvas_exists", "message": "..."}}` instead (passed
404
- through to the agent like any other tab-reported error -- see Errors).
405
- 3. The NEW tab's own `AgentBridgeClient` connects and sends its own `hello`
406
- (`tab_id` = the id from step 2, `page_id` = the SAME page_id as every
407
- other tab on that page) like any ordinary tab open.
408
- 4. The bridge waits (`GAMEASSET_BRIDGE_CREATE_CANVAS_HELLO_TIMEOUT_S`,
409
- default 5s) for that exact `tab_id` to register a session, then answers
410
- the MCP call with `{"session_id", "tab_id", "workflow_name"}` for the
411
- NEW session. No hello within the window -> `canvas_timeout`.
412
-
413
- ## Addressing (R6)
414
-
415
- Applies to every tool that takes a `workflow` argument -- i.e. every tool
416
- except `list_canvases` and `create_canvas` (see above, its own protocol
417
- section). `focus_canvas` uses this SAME resolution, unlike `create_canvas`.
418
-
419
- `workflow` is resolved against every currently-connected `/ws/canvas`
420
- session, in this order:
421
-
422
- 1. **Zero canvases connected at all** -> `no_canvas`, regardless of what
423
- `workflow` was. The agent must ask the human to open FlowPix and this
424
- workflow in their browser -- it must NEVER fall back to editing the
425
- backend's saved workflow file.
426
- 2. `workflow` equals a connected session's `session_id` exactly -> that
427
- session (no name lookup needed).
428
- 3. Otherwise, exact match against every connected session's
429
- `workflow_name`:
430
- - 0 matches -> `canvas_not_found`, message lists the `workflow_name`s
431
- that ARE currently connected.
432
- - 1 match -> that session.
433
- - >1 matches (two tabs share a workflow name) -> `ambiguous_canvas`,
434
- message lists the matching sessions' `session_id`s -- retry with one
435
- of those as `workflow` (case 2).
436
-
437
- ## Errors
438
-
439
- Every failure raised by a tool is an MCP tool error (`is_error: true`)
440
- whose text content IS `json.dumps({"code": "<code>", "message": "<string>"})`
441
- -- but **what the calling agent actually receives is not that raw JSON
442
- string**. The `mcp` python SDK (and, empirically, every client built on it)
443
- prefixes a tool error's text with `Error executing tool <name>: ` before the
444
- JSON object, e.g.:
445
-
446
- ```
447
- Error executing tool set_params: {"code": "invalid_params", "message": "unknown param 'sizee' for text_prompt"}
448
- ```
449
-
450
- **A reader (TASK_100's frontend executor included, and any agent-side code
451
- parsing this) must locate and parse the `{...}` object embedded in the
452
- text, never `json.loads()` the whole string** -- the exact wording of the
453
- `Error executing tool <name>: ` prefix is the MCP SDK's own, not this
454
- bridge's, and is not part of this contract (do not depend on its exact
455
- text, only on there being a JSON object with `code`/`message` keys
456
- somewhere in the string). `bridge/agent_hub/tools.py`'s tests locate it
457
- with a substring check (`'"code": "<code>"' in text`), not a full parse.
458
-
459
- | `code` | Meaning |
460
- |---|---|
461
- | `no_canvas` | No `/ws/canvas` session is connected at all. |
462
- | `canvas_not_found` | `workflow` matched no connected `session_id` or `workflow_name`. |
463
- | `ambiguous_canvas` | `workflow` matched more than one connected `workflow_name`. |
464
- | `canvas_timeout` | The addressed tab did not send a `result` within the call's timeout (30s; 60s for `get_output`; 30s for `run_workflow` too, TASK_107 -- its page-side handler now answers as soon as the job is ACCEPTED, the same shape/duration as a quick edit, so it shares the plain default value even though it keeps its own override knob; overridable in tests via `GAMEASSET_BRIDGE_CALL_TIMEOUT_S` / `GAMEASSET_BRIDGE_GET_OUTPUT_TIMEOUT_S` / `GAMEASSET_BRIDGE_RUN_WORKFLOW_TIMEOUT_S`). |
465
- | `canvas_disconnected` | The tab's connection closed (or a send to it failed) while a call was in flight. |
466
- | `no_output` | (tab-reported) the node has not produced output yet. |
467
- | `tool_failed` | Generic fallback ONLY if a tab's `{"ok": false, "error": {...}}` result is missing `code`/`message` entirely. |
468
- | *(tab-defined)* | Any other `code`/`message` a tab's `{"ok": false, "error": {...}}` result reports (e.g. `invalid_params`, `invalid_connection`) is passed through UNCHANGED -- this is how the agent learns WHY an edit was rejected, not just that it was. Covered by `test_tab_reported_error_passes_through` and mutation arm M7 (cutting this passthrough is caught). |
469
-
470
- Never falls back to the backend's saved-workflow API for any of these --
471
- that would silently act on stale data instead of surfacing the error to
472
- the agent (R6).
473
-
474
- ---
475
-
476
- # Relay v1 (TASK_105)
477
-
478
- **This section is the wire contract Kenaz's Rust implementation targets** --
479
- see `FEATURE_REQUEST_kenaz-agent-hub_2026-09-07.md` (K1-K8) in the kenaz-core
480
- repo for the product-level feature list this protocol serves. Field names
481
- below MUST NOT drift between the three spike implementations
482
- (`spikes/relay_spike/relay.mjs`, `bridge/agent_relay_client.py`,
483
- `backend/jobs.py`'s `RelaySiteClient`) without updating this document first
484
- -- `test_relay_contract.py` asserts all three agree with the JSON examples
485
- here (AC6).
486
-
487
- ## Why this exists (R4/K2)
488
-
489
- The cloud website/backend never holds the user's AI credentials. Instead a
490
- website's "連接 Kenaz" button opens a `kenaz://connect?...` deep link that
491
- wakes the user's own local Kenaz; Kenaz then dials OUT to a relay server
492
- (firewall-friendly -- the user's machine never needs an inbound port), and
493
- every AI generation the website asks for is forwarded through that relay to
494
- Kenaz, which runs it against the user's own ChatGPT/Codex subscription and
495
- asks the user to approve it. Web3 "connect wallet" UX: connect once, approve
496
- per action (or "always allow this site").
497
-
498
- ## Transport
499
-
500
- One WS/WSS endpoint per relay process (this spike: `ws://127.0.0.1:<port>/ws`;
501
- a real deployment would put this behind TLS). Every frame is UTF-8 JSON, one
502
- JSON object per frame, with at least a `"type"` string field. Most also carry
503
- `"request_id"` (string) that pairs a request with its response(s); a handful
504
- of unsolicited pushes carry `"request_id": null`.
505
-
506
- **Size cap (R2)**: any single frame whose UTF-8 byte length exceeds
507
- **262144 bytes (256 KiB)** is rejected by the relay without being forwarded
508
- -- this is why images and other large payloads travel as object-storage URLs
509
- (`reference_images` entries, a `result.payload.url`), never inline base64. If
510
- the oversized frame carried a `request_id`, the relay answers the SENDER
511
- (not the intended recipient) with `{"type":"error","request_id":<id>,
512
- "error":{"code":"payload_too_large","message":"<n> bytes exceeds the 256KB
513
- relay limit"}}`; a `request_id`-less oversized frame is simply dropped and
514
- logged. The relay logs every frame's direction/type/byte length (JSONL) so a
515
- run can prove after the fact that nothing crossed the cap (AC1).
516
-
517
- ## Roles
518
-
519
- - **site** -- the cloud backend acting on behalf of one website/session
520
- (`backend/jobs.py`'s `RelaySiteClient` in this spike; a real deployment
521
- would run this inside FlowPix's own backend process).
522
- - **agent** -- Kenaz (or, in this spike, `bridge/agent_relay_client.py`
523
- standing in as a "fake Kenaz").
524
-
525
- A connection's role is fixed by its FIRST message: `site.hello` makes it a
526
- site connection; `pair.begin` makes it an agent connection (an agent has no
527
- separate hello step -- `pair.begin` serves both purposes).
528
-
529
- ## 1. Site handshake
530
-
531
- ```json
532
- site -> relay: {"type": "site.hello", "request_id": "<id>", "origin": "<site origin, e.g. https://flowpix.app>"}
533
- relay -> site: {"type": "site.ready", "request_id": "<id>", "site_session_id": "<string>"}
534
- ```
535
-
536
- ## 2. Pairing token (one-time, 60s TTL, origin-bound)
537
-
538
- ```json
539
- site -> relay: {"type": "token.mint", "request_id": "<id>", "agent": "claude" | "codex" | null}
540
- relay -> site: {"type": "token.minted", "request_id": "<id>", "token": "<32 hex chars>", "ttl_s": 60}
541
- ```
542
-
543
- The token is bound to `(site_session_id, origin, agent)` at mint time and is
544
- **consumed the instant a `pair.begin` referencing it is processed** --
545
- regardless of whether that attempt succeeds -- so a token can only ever be
546
- tried once, full stop (AC3: a stolen token cannot be retried against a
547
- different origin after a first failed guess). The site backend builds the
548
- deep link from this response:
549
-
550
- ```
551
- kenaz://connect?site=<url-encoded origin>&token=<token>&relay=<url-encoded relay ws url>&agent=<claude|codex>
552
- ```
553
-
554
- ## 3. Agent pairing
555
-
556
- ```json
557
- agent -> relay: {"type": "pair.begin", "request_id": "<id>", "token": "<token>", "site_origin": "<origin>"}
558
- relay -> agent: {"type": "pair.ok", "request_id": "<id>", "session_credential": "<string>", "site_origin": "<origin>"}
559
- | {"type": "pair.denied", "request_id": "<id>", "error": {"code": "token_invalid" | "token_expired" | "token_already_used" | "origin_mismatch" | "relay_unavailable", "message": "<string>"}}
560
- relay -> site (pair.ok only): {"type": "agent.connected", "request_id": null, "agent_session_id": "<string>"}
561
- ```
562
-
563
- `origin_mismatch`: `site_origin` in `pair.begin` does not equal the origin the
564
- token was minted against. `relay_unavailable`: the token's site session
565
- already disconnected.
566
-
567
- ## 4. Status push (agent -> site, unsolicited, forwarded verbatim)
568
-
569
- ```json
570
- {"type": "agent.status", "request_id": null, "codex_logged_in": true, "rate_limits": null, "approval_mode": "allow_all" | "ask_once" | "deny"}
571
- ```
572
-
573
- ## 5. Generation requests (site -> agent, forwarded)
574
-
575
- ```json
576
- {"type": "generate_image", "request_id": "<id>", "prompt": "<string>", "size": "<string>", "quality": "<string>", "reference_images": ["<url>", "..."]}
577
- {"type": "generate_text", "request_id": "<id>", "prompt": "<string>", "system": "<string>", "model": "<string>", "max_output_tokens": <int>, "reasoning_effort": "<string>", "reference_images": ["<url>", "..."]}
578
- ```
579
-
580
- `reference_images` are object-storage URLs (this spike: `blobstore.mjs`'s
581
- fake presigned URLs), never inline base64 -- exactly why the 256KB cap above
582
- is workable at all. FlowPix's canvas tool set (`list_canvases`...
583
- `focus_canvas`, "Agent hub v1" above) is a SEPARATE path for a local CLI
584
- agent and never travels over the relay.
585
-
586
- ## 6. Approval (agent -> site, forwarded, same `request_id` as the generate_* call)
587
-
588
- ```json
589
- {"type": "approval.pending", "request_id": "<id>", "summary": "<string>"}
590
- {"type": "approval.resolved", "request_id": "<id>", "decision": "allow" | "deny"}
591
- ```
592
-
593
- The site shows "等待你在 Kenaz 允許" for `request_id`s between `.pending` and
594
- `.resolved`/`result` (AC2).
595
-
596
- ## 7. Result (agent -> site, forwarded, same `request_id`)
597
-
598
- ```json
599
- {"type": "result", "request_id": "<id>", "ok": true, "payload": {...}}
600
- {"type": "result", "request_id": "<id>", "ok": false, "error": {"code": "<code>", "message": "<string>"}}
601
- ```
602
-
603
- `payload` for `generate_image`: `{"url": "<blobstore url>", "width": <int>,
604
- "height": <int>, "provider": "codex", "elapsed_ms": <int>, "meta": {...}}`.
605
- `payload` for `generate_text`: `{"text": "<string>", "provider": "codex",
606
- "elapsed_ms": <int>, "meta": {...}}`.
607
-
608
- Error codes (`error.code`): `not_logged_in`, `usage_limit_exceeded` (carries
609
- an additional `resetsAt` field), `denied`, `timeout`, `relay_unavailable`,
610
- `payload_too_large`, `token_invalid`, `token_expired`, `token_already_used`,
611
- `origin_mismatch`.
612
-
613
- ## 8. Agent launch (agent -> site, forwarded -- R7/K8)
614
-
615
- Announces that Kenaz, having just paired via a deep link carrying
616
- `agent=claude|codex`, is starting that CLI headless with FlowPix's `/mcp`
617
- endpoint (this same bridge's Agent hub v1, above) pre-configured so the CLI
618
- can `list_canvases` / `add_node` on the canvas the deep link named, without
619
- the relay itself being involved in that traffic at all.
620
-
621
- ```json
622
- {"type": "agent.launch", "request_id": null, "agent": "claude" | "codex", "mode": "headless" | "interactive", "prompt": "<string>" | null}
623
- {"type": "agent.launched", "request_id": null, "agent": "claude" | "codex", "pid": <int> | null}
624
- {"type": "agent_unavailable", "request_id": null, "agent": "claude" | "codex", "reason": "<string>"}
625
- ```
626
-
627
- ## 9. Disconnect
628
-
629
- ```json
630
- relay -> site: {"type": "agent.disconnected", "request_id": null}
631
- ```
632
- Sent when the paired agent's connection closes. The site's `GET`-style status
633
- read (`backend/jobs.py`'s `get_kenaz_status()`) then reports `connected: false`
634
- again.
635
-
636
- ## Security notes (R1/K2)
637
-
638
- Kenaz only ever makes an OUTBOUND connection to the relay -- no inbound port
639
- on the user's machine. Credentials (Codex/ChatGPT login) never leave the
640
- user's machine; only the generated image/text and metadata cross the relay.
641
- Each website origin gets its own pairing; nothing here lets one origin's
642
- pairing be reused by another.