mad-edge 0.6.0__tar.gz

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 (134) hide show
  1. mad_edge-0.6.0/.gitignore +21 -0
  2. mad_edge-0.6.0/CHANGELOG.md +360 -0
  3. mad_edge-0.6.0/LICENSE +21 -0
  4. mad_edge-0.6.0/PKG-INFO +204 -0
  5. mad_edge-0.6.0/README.md +146 -0
  6. mad_edge-0.6.0/docs/05-operations/runbooks/README.md +85 -0
  7. mad_edge-0.6.0/docs/06-flow-participation/README.md +127 -0
  8. mad_edge-0.6.0/docs/07-decisions/README.md +36 -0
  9. mad_edge-0.6.0/docs/08-rfcs/README.md +50 -0
  10. mad_edge-0.6.0/docs/10-user-manuals/README.md +37 -0
  11. mad_edge-0.6.0/docs/README.md +171 -0
  12. mad_edge-0.6.0/docs/adr/README.md +51 -0
  13. mad_edge-0.6.0/pyproject.toml +291 -0
  14. mad_edge-0.6.0/src/mad/__init__.py +1 -0
  15. mad_edge-0.6.0/src/mad/adapters/__init__.py +0 -0
  16. mad_edge-0.6.0/src/mad/adapters/inbound/__init__.py +0 -0
  17. mad_edge-0.6.0/src/mad/adapters/inbound/http/__init__.py +3 -0
  18. mad_edge-0.6.0/src/mad/adapters/inbound/http/app.py +368 -0
  19. mad_edge-0.6.0/src/mad/adapters/inbound/http/asgi.py +21 -0
  20. mad_edge-0.6.0/src/mad/adapters/inbound/http/dependencies.py +109 -0
  21. mad_edge-0.6.0/src/mad/adapters/inbound/http/routes/__init__.py +0 -0
  22. mad_edge-0.6.0/src/mad/adapters/inbound/http/routes/events.py +220 -0
  23. mad_edge-0.6.0/src/mad/adapters/inbound/http/routes/orchestration.py +651 -0
  24. mad_edge-0.6.0/src/mad/adapters/inbound/http/routes/providers.py +197 -0
  25. mad_edge-0.6.0/src/mad/adapters/inbound/http/routes/sessions.py +366 -0
  26. mad_edge-0.6.0/src/mad/adapters/inbound/http/routes/workflows.py +190 -0
  27. mad_edge-0.6.0/src/mad/adapters/inbound/internal/__init__.py +0 -0
  28. mad_edge-0.6.0/src/mad/adapters/inbound/internal/app.py +35 -0
  29. mad_edge-0.6.0/src/mad/adapters/inbound/internal/hooks_router.py +62 -0
  30. mad_edge-0.6.0/src/mad/adapters/inbound/mcp/__init__.py +12 -0
  31. mad_edge-0.6.0/src/mad/adapters/inbound/mcp/server.py +759 -0
  32. mad_edge-0.6.0/src/mad/adapters/outbound/__init__.py +0 -0
  33. mad_edge-0.6.0/src/mad/adapters/outbound/agents/__init__.py +0 -0
  34. mad_edge-0.6.0/src/mad/adapters/outbound/agents/_subprocess.py +63 -0
  35. mad_edge-0.6.0/src/mad/adapters/outbound/agents/claude_cli.py +322 -0
  36. mad_edge-0.6.0/src/mad/adapters/outbound/agents/factory.py +13 -0
  37. mad_edge-0.6.0/src/mad/adapters/outbound/agents/hook_socket.py +14 -0
  38. mad_edge-0.6.0/src/mad/adapters/outbound/agents/hooks/__init__.py +0 -0
  39. mad_edge-0.6.0/src/mad/adapters/outbound/agents/hooks/forward.sh +25 -0
  40. mad_edge-0.6.0/src/mad/adapters/outbound/agents/hooks/settings.local.json +137 -0
  41. mad_edge-0.6.0/src/mad/adapters/outbound/agents/model_catalog.py +62 -0
  42. mad_edge-0.6.0/src/mad/adapters/outbound/agents/opencode.py +153 -0
  43. mad_edge-0.6.0/src/mad/adapters/outbound/events/__init__.py +0 -0
  44. mad_edge-0.6.0/src/mad/adapters/outbound/events/in_memory_event_bus.py +86 -0
  45. mad_edge-0.6.0/src/mad/adapters/outbound/events/jsonl_event_log_query.py +83 -0
  46. mad_edge-0.6.0/src/mad/adapters/outbound/orchestration/__init__.py +0 -0
  47. mad_edge-0.6.0/src/mad/adapters/outbound/orchestration/git_inspector.py +156 -0
  48. mad_edge-0.6.0/src/mad/adapters/outbound/orchestration/projection.py +155 -0
  49. mad_edge-0.6.0/src/mad/adapters/outbound/orchestration/system_clock.py +17 -0
  50. mad_edge-0.6.0/src/mad/adapters/outbound/orchestration/workflow_projection.py +131 -0
  51. mad_edge-0.6.0/src/mad/adapters/outbound/persistence/__init__.py +0 -0
  52. mad_edge-0.6.0/src/mad/adapters/outbound/persistence/jsonl_session_repository.py +208 -0
  53. mad_edge-0.6.0/src/mad/adapters/outbound/persistence/local_workspace_provisioner.py +231 -0
  54. mad_edge-0.6.0/src/mad/core/__init__.py +0 -0
  55. mad_edge-0.6.0/src/mad/core/events/__init__.py +0 -0
  56. mad_edge-0.6.0/src/mad/core/events/domain/__init__.py +0 -0
  57. mad_edge-0.6.0/src/mad/core/events/domain/event.py +58 -0
  58. mad_edge-0.6.0/src/mad/core/events/domain/event_id.py +37 -0
  59. mad_edge-0.6.0/src/mad/core/events/emitter.py +47 -0
  60. mad_edge-0.6.0/src/mad/core/events/ports/__init__.py +5 -0
  61. mad_edge-0.6.0/src/mad/core/events/ports/event_bus.py +48 -0
  62. mad_edge-0.6.0/src/mad/core/events/ports/event_log_query.py +50 -0
  63. mad_edge-0.6.0/src/mad/core/events/ports/event_store.py +23 -0
  64. mad_edge-0.6.0/src/mad/core/events/use_cases/__init__.py +0 -0
  65. mad_edge-0.6.0/src/mad/core/events/use_cases/query_events.py +77 -0
  66. mad_edge-0.6.0/src/mad/core/events/use_cases/stream_events.py +105 -0
  67. mad_edge-0.6.0/src/mad/core/orchestration/__init__.py +0 -0
  68. mad_edge-0.6.0/src/mad/core/orchestration/domain/__init__.py +0 -0
  69. mad_edge-0.6.0/src/mad/core/orchestration/domain/deployment_policy.py +67 -0
  70. mad_edge-0.6.0/src/mad/core/orchestration/domain/dispatch_policy.py +261 -0
  71. mad_edge-0.6.0/src/mad/core/orchestration/domain/effort_config.py +52 -0
  72. mad_edge-0.6.0/src/mad/core/orchestration/domain/exceptions/__init__.py +0 -0
  73. mad_edge-0.6.0/src/mad/core/orchestration/domain/exceptions/base.py +48 -0
  74. mad_edge-0.6.0/src/mad/core/orchestration/domain/exceptions/rate_limit.py +55 -0
  75. mad_edge-0.6.0/src/mad/core/orchestration/domain/exceptions/workflow.py +29 -0
  76. mad_edge-0.6.0/src/mad/core/orchestration/domain/git_result.py +73 -0
  77. mad_edge-0.6.0/src/mad/core/orchestration/domain/model_config.py +44 -0
  78. mad_edge-0.6.0/src/mad/core/orchestration/domain/ordering.py +98 -0
  79. mad_edge-0.6.0/src/mad/core/orchestration/domain/retry_schedule.py +50 -0
  80. mad_edge-0.6.0/src/mad/core/orchestration/domain/task.py +41 -0
  81. mad_edge-0.6.0/src/mad/core/orchestration/domain/timeout_config.py +66 -0
  82. mad_edge-0.6.0/src/mad/core/orchestration/domain/workflow.py +309 -0
  83. mad_edge-0.6.0/src/mad/core/orchestration/ports/__init__.py +0 -0
  84. mad_edge-0.6.0/src/mad/core/orchestration/ports/clock.py +26 -0
  85. mad_edge-0.6.0/src/mad/core/orchestration/ports/git_inspector.py +45 -0
  86. mad_edge-0.6.0/src/mad/core/orchestration/ports/model_catalog.py +18 -0
  87. mad_edge-0.6.0/src/mad/core/orchestration/ports/task_projection.py +26 -0
  88. mad_edge-0.6.0/src/mad/core/orchestration/ports/task_queue.py +64 -0
  89. mad_edge-0.6.0/src/mad/core/orchestration/ports/workflow_read_model.py +47 -0
  90. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/__init__.py +0 -0
  91. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/cancel_task.py +65 -0
  92. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/clear_dispatch_policy.py +70 -0
  93. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/create_workflow.py +56 -0
  94. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/deployment_dispatch_policy.py +101 -0
  95. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/deployment_effort_config.py +106 -0
  96. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/deployment_model_config.py +103 -0
  97. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/dispatcher.py +552 -0
  98. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/enqueue_task.py +83 -0
  99. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/get_global_queue.py +177 -0
  100. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/get_workflow.py +27 -0
  101. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/list_provider_models.py +43 -0
  102. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/list_tasks.py +42 -0
  103. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/rehydrate_pending_sessions.py +49 -0
  104. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/trigger_manual_dispatch.py +88 -0
  105. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/update_dispatch_policy.py +79 -0
  106. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/update_dispatch_priority.py +63 -0
  107. mad_edge-0.6.0/src/mad/core/orchestration/use_cases/workflow_coordinator.py +456 -0
  108. mad_edge-0.6.0/src/mad/core/sessions/__init__.py +7 -0
  109. mad_edge-0.6.0/src/mad/core/sessions/credentials.py +51 -0
  110. mad_edge-0.6.0/src/mad/core/sessions/domain/__init__.py +3 -0
  111. mad_edge-0.6.0/src/mad/core/sessions/domain/entities/__init__.py +7 -0
  112. mad_edge-0.6.0/src/mad/core/sessions/domain/entities/session.py +151 -0
  113. mad_edge-0.6.0/src/mad/core/sessions/domain/exceptions/__init__.py +11 -0
  114. mad_edge-0.6.0/src/mad/core/sessions/domain/exceptions/base.py +27 -0
  115. mad_edge-0.6.0/src/mad/core/sessions/domain/rehydrate.py +137 -0
  116. mad_edge-0.6.0/src/mad/core/sessions/domain/value_objects/__init__.py +7 -0
  117. mad_edge-0.6.0/src/mad/core/sessions/domain/value_objects/mount_path.py +51 -0
  118. mad_edge-0.6.0/src/mad/core/sessions/ports/__init__.py +9 -0
  119. mad_edge-0.6.0/src/mad/core/sessions/ports/outbound/__init__.py +9 -0
  120. mad_edge-0.6.0/src/mad/core/sessions/ports/outbound/agent_launcher.py +60 -0
  121. mad_edge-0.6.0/src/mad/core/sessions/ports/outbound/session_repository.py +31 -0
  122. mad_edge-0.6.0/src/mad/core/sessions/ports/outbound/workspace_provisioner.py +54 -0
  123. mad_edge-0.6.0/src/mad/core/sessions/store.py +24 -0
  124. mad_edge-0.6.0/src/mad/core/sessions/use_cases/__init__.py +3 -0
  125. mad_edge-0.6.0/src/mad/core/sessions/use_cases/auto_sync_prompt.py +51 -0
  126. mad_edge-0.6.0/src/mad/core/sessions/use_cases/cleanup_sessions.py +105 -0
  127. mad_edge-0.6.0/src/mad/core/sessions/use_cases/create_session.py +223 -0
  128. mad_edge-0.6.0/src/mad/core/sessions/use_cases/delete_session.py +92 -0
  129. mad_edge-0.6.0/src/mad/core/sessions/use_cases/get_session.py +60 -0
  130. mad_edge-0.6.0/src/mad/core/sessions/use_cases/list_sessions.py +117 -0
  131. mad_edge-0.6.0/src/mad/core/sessions/use_cases/send_user_message.py +316 -0
  132. mad_edge-0.6.0/src/mad/entry_points/__init__.py +0 -0
  133. mad_edge-0.6.0/src/mad/entry_points/cli.py +105 -0
  134. mad_edge-0.6.0/tests/e2e/README.md +43 -0
@@ -0,0 +1,21 @@
1
+ .venv/
2
+ venv/
3
+ __pycache__/
4
+ *.pyc
5
+ *.pyo
6
+ /sessions/
7
+ /tmp/mad_*
8
+ .pytest_cache/
9
+ .coverage
10
+ dist/
11
+ build/
12
+ *.egg-info/
13
+ .DS_Store
14
+ hook-events/*
15
+
16
+ # Docker / per-instance operator config (#66) — secrets and per-instance host
17
+ # state never get committed; only the tracked templates do.
18
+ .env
19
+ .env.*
20
+ !.env.example
21
+ /instances/
@@ -0,0 +1,360 @@
1
+ # CHANGELOG
2
+
3
+
4
+ ## v0.6.0 (2026-07-04)
5
+
6
+ ### Features
7
+
8
+ - **cli**: Rename distribution to mad-edge and console script to mad-edge
9
+ ([`8c05c58`](https://github.com/mad-core/mad-edge/commit/8c05c587b28b2de4ca545fcae78e861f7bf1fcfa))
10
+
11
+
12
+ ## v0.5.26 (2026-07-04)
13
+
14
+ ### Bug Fixes
15
+
16
+ - Deprecate mad-bros distribution in favor of mad-edge
17
+ ([`c5b334d`](https://github.com/mad-core/mad-edge/commit/c5b334d721cd5724a1bf7312fc4df3b0ab6411b3))
18
+
19
+
20
+ ## v0.5.25 (2026-06-27)
21
+
22
+
23
+ ## v0.5.24 (2026-06-27)
24
+
25
+ ### Features
26
+
27
+ - **http**: Add POST/GET /v1/workflows for session chaining
28
+ ([`54a3485`](https://github.com/mad-core/mad-edge/commit/54a34851e2366de4f563152a03be6fafb9da0c09))
29
+
30
+
31
+ ## v0.5.23 (2026-06-27)
32
+
33
+ ### Features
34
+
35
+ - **http**: Add per-task effort with task > session > deployment precedence
36
+ ([`aef916b`](https://github.com/mad-core/mad-edge/commit/aef916b42bcaeda257f7b636d1fba25773bc622f))
37
+
38
+
39
+ ## v0.5.22 (2026-06-27)
40
+
41
+ ### Features
42
+
43
+ - **sse**: Emit task.git_result event after a task completes
44
+ ([`357e2cf`](https://github.com/mad-core/mad-edge/commit/357e2cf22c702d17dc7abe7fba0f4cf2827e699f))
45
+
46
+
47
+ ## v0.5.21 (2026-06-27)
48
+
49
+ ### Features
50
+
51
+ - **config**: Source GitHub clone PAT from host env; deprecate inline PAT
52
+ ([`72bd84f`](https://github.com/mad-core/mad-edge/commit/72bd84f107d228b458a2231668f5878089adf0e8))
53
+
54
+
55
+ ## v0.5.20 (2026-06-27)
56
+
57
+ ### Bug Fixes
58
+
59
+ - **agents**: Don't re-run primary when auto-sync hits a rate limit
60
+ ([`099e099`](https://github.com/mad-core/mad-edge/commit/099e099eaa96a8adbecf5a086b43f5031ca773c6))
61
+
62
+ ### Features
63
+
64
+ - **http**: Expose importable ASGI application instance
65
+ ([`9e0518e`](https://github.com/mad-core/mad-edge/commit/9e0518ebe1017e3d33a407a85ca3486c420c26b5))
66
+
67
+
68
+ ## v0.5.19 (2026-06-25)
69
+
70
+ ### Bug Fixes
71
+
72
+ - **agents**: Defer rate-limit retry when work window closes
73
+ ([`7c7b3a0`](https://github.com/mad-core/mad-edge/commit/7c7b3a05edd4da63a91b1ebab967400d6f3dc799))
74
+
75
+
76
+ ## v0.5.18 (2026-06-22)
77
+
78
+ ### Bug Fixes
79
+
80
+ - **agents**: Retry transient 401 authentication_failed instead of draining queue
81
+ ([`0d9c956`](https://github.com/mad-core/mad-edge/commit/0d9c956fedb3fe7c7cb5f0986f5795a2c5bc27e6))
82
+
83
+ ### Features
84
+
85
+ - **config**: Add MAD_SESSIONS_RETENTION_DAYS JSONL log TTL
86
+ ([`d5d9296`](https://github.com/mad-core/mad-edge/commit/d5d92965a8d84f2fed5de4c814b52085753fbeb8))
87
+
88
+
89
+ ## v0.5.17 (2026-06-22)
90
+
91
+ ### Features
92
+
93
+ - **agents**: Agent-agnostic timeout with per-session override
94
+ ([`b1b2eb5`](https://github.com/mad-core/mad-edge/commit/b1b2eb5aa24def5a727a51f467b969d337bbe522))
95
+ - **config**: Make sessions log directory configurable via MAD_SESSIONS_DIR
96
+ ([`ef7a2a2`](https://github.com/mad-core/mad-edge/commit/ef7a2a2fc4e265bc1a8996e684f4bc0a2b41e69d))
97
+
98
+
99
+ ## v0.5.16 (2026-06-22)
100
+
101
+
102
+ ## v0.5.15 (2026-06-21)
103
+
104
+ ### Bug Fixes
105
+
106
+ - **agents**: Detect real claude-cli 429 rate-limit terminal stdout shape
107
+ ([`bec17ed`](https://github.com/mad-core/mad-edge/commit/bec17ed4c7cec2276d725e0f65b3d49d11da07da))
108
+
109
+
110
+ ## v0.5.14 (2026-06-21)
111
+
112
+ ### Bug Fixes
113
+
114
+ - **agents**: Prevent LimitOverrunError killing tasks on long stdout lines
115
+ ([`4deb5df`](https://github.com/mad-core/mad-edge/commit/4deb5df3e526eb2b6991bd40267c876607bf75b2))
116
+
117
+
118
+ ## v0.5.13 (2026-06-21)
119
+
120
+ ### Bug Fixes
121
+
122
+ - **agents**: Treat billing errors as terminal and require --verbose for stream-json
123
+ ([`d7f3496`](https://github.com/mad-core/mad-edge/commit/d7f34965fe172fa7d7c197b3e42bf9db05e5741b))
124
+
125
+ ### Features
126
+
127
+ - **agents**: Detect rate-limit exits in claude_cli and opencode providers
128
+ ([`59f37a5`](https://github.com/mad-core/mad-edge/commit/59f37a5134696b28f35114922be7453612e948b0))
129
+ - **http**: Expose retry status and retry_info on task list response
130
+ ([`24a0cdd`](https://github.com/mad-core/mad-edge/commit/24a0cdd5272b3656b94861871725ef7219d4c3f4))
131
+
132
+
133
+ ## v0.5.12 (2026-06-21)
134
+
135
+ ### Bug Fixes
136
+
137
+ - **agents**: Correct misleading comment in claude_cli stdout parser
138
+ ([`96ef51a`](https://github.com/mad-core/mad-edge/commit/96ef51a8765f97f3ddd37f320b540f24e6db3205))
139
+ - **http**: Capture conversation ID from SessionStart hook in on_emit
140
+ ([`2022288`](https://github.com/mad-core/mad-edge/commit/2022288d221783f1d26ce3fa848f842314fd735a))
141
+
142
+ ### Features
143
+
144
+ - **agents**: Capture conversation ID from claude_cli and opencode
145
+ ([`8c1b5de`](https://github.com/mad-core/mad-edge/commit/8c1b5de878589fe8646ddac1e10e07b1827f6fcf))
146
+ - **agents**: Forward reasoning effort to claude and opencode CLIs
147
+ ([`302ab9a`](https://github.com/mad-core/mad-edge/commit/302ab9a7dd25b8c07bb33af6cb068ea50a2d7e17))
148
+ - **http**: Expose conversation_mode on tasks and last_conversation_id on sessions
149
+ ([`643ac42`](https://github.com/mad-core/mad-edge/commit/643ac42a5184db6bdfaebab897f030e5b2058421))
150
+ - **http**: Select reasoning effort per session with a deployment default
151
+ ([`c6d5c47`](https://github.com/mad-core/mad-edge/commit/c6d5c47fc46fe7940b00d22f304b90a140d26b2f))
152
+
153
+
154
+ ## v0.5.11 (2026-06-21)
155
+
156
+ ### Features
157
+
158
+ - **config**: Make workspace base dir configurable via MAD_WORKSPACE_DIR
159
+ ([`f137b53`](https://github.com/mad-core/mad-edge/commit/f137b536f9714bedc4fb932b5e4af0af950d7115))
160
+
161
+
162
+ ## v0.5.10 (2026-06-14)
163
+
164
+ ### Features
165
+
166
+ - **agents**: Add opencode launcher provider
167
+ ([`9d70222`](https://github.com/mad-core/mad-edge/commit/9d70222d35d3892d1e2e679e14a93a171662e255))
168
+ - **http**: Discover provider models + per-level model selection
169
+ ([`3c254dc`](https://github.com/mad-core/mad-edge/commit/3c254dc8e519bdb3a497914a8909960b02006d93))
170
+ - **http**: Mirror model discovery + selection as MCP tools
171
+ ([`f51f341`](https://github.com/mad-core/mad-edge/commit/f51f341cacae1a6cad6695040afd7ea51a7ca3e1))
172
+
173
+
174
+ ## v0.5.9 (2026-06-14)
175
+
176
+ ### Bug Fixes
177
+
178
+ - **http**: Drop a deleted session's queued tasks from the queue
179
+ ([`0d4513f`](https://github.com/mad-core/mad-edge/commit/0d4513f51c95ddac622178097a92cdb949d5d40b))
180
+ - **http**: Resolve effective dispatch policy in the global queue view
181
+ ([`1a18f4a`](https://github.com/mad-core/mad-edge/commit/1a18f4a35c8d8380ef76fecb360e8207d3ff746d))
182
+
183
+ ### Features
184
+
185
+ - **http**: Expose session priority and global queue as MCP tools
186
+ ([`edaf49d`](https://github.com/mad-core/mad-edge/commit/edaf49d8ba6872a9e3e40f1c615039fe81fe7c9f))
187
+
188
+
189
+ ## v0.5.8 (2026-06-12)
190
+
191
+ ### Features
192
+
193
+ - **http**: Configure deployment-wide dispatch policy inherited by sessions
194
+ ([`16b1772`](https://github.com/mad-core/mad-edge/commit/16b177226c2fe7653d294e977cf4cfdf2d424920))
195
+ - **http**: Expose every request/response /v1 route as MCP tool
196
+ ([`0902dc2`](https://github.com/mad-core/mad-edge/commit/0902dc29f0325249e02e78b13c293ef578df427f))
197
+
198
+
199
+ ## v0.5.7 (2026-06-12)
200
+
201
+ ### Bug Fixes
202
+
203
+ - **cli**: Ship mad.core.sessions in the published package
204
+ ([`8cfb12f`](https://github.com/mad-core/mad-edge/commit/8cfb12f281efc08464349af4479759c890cb782b))
205
+
206
+ ### Features
207
+
208
+ - **http**: Per-session priority and global GET /v1/queue view
209
+ ([`8d30ab0`](https://github.com/mad-core/mad-edge/commit/8d30ab0e1c44faea410bfa0feaa49bbda339b69c))
210
+
211
+
212
+ ## v0.5.6 (2026-05-19)
213
+
214
+ ### Bug Fixes
215
+
216
+ - **cli**: Unpack 8 deps from build_dependencies and wire into create_app
217
+ ([`1520c87`](https://github.com/mad-core/mad-edge/commit/1520c870f157915694c3275821b743467dcc72b5))
218
+
219
+
220
+ ## v0.5.5 (2026-05-17)
221
+
222
+ ### Features
223
+
224
+ - **http**: Launch agents in the cloned repo, not the workspace root
225
+ ([`5f639e2`](https://github.com/mad-core/mad-edge/commit/5f639e2c0b379b8bdd9bf20bfdcf21e9fdbdb057))
226
+
227
+
228
+ ## v0.5.4 (2026-05-16)
229
+
230
+ ### Features
231
+
232
+ - **deps**: Add mcp runtime dependency (>=1.0,<2)
233
+ ([`62bb08a`](https://github.com/mad-core/mad-edge/commit/62bb08a395ff0a2d3b05a970525bca942a4d0dc9))
234
+ - **http**: Expose Mad as an MCP server mounted at /mcp
235
+ ([`0d1af76`](https://github.com/mad-core/mad-edge/commit/0d1af766d76a7af13e0c9f2483750e377c2d3363))
236
+
237
+
238
+ ## v0.5.3 (2026-05-15)
239
+
240
+ ### Features
241
+
242
+ - **http**: Add dispatch_policy PATCH and manual trigger endpoints
243
+ ([`f5dae87`](https://github.com/mad-core/mad-edge/commit/f5dae87cf9dbc1745371cc26170fdbf277f05fa6))
244
+
245
+
246
+ ## v0.5.2 (2026-05-15)
247
+
248
+ ### Bug Fixes
249
+
250
+ - **sse**: Emit periodic heartbeats and disable proxy buffering on /v1/events/stream (#38)
251
+ ([#38](https://github.com/mad-core/mad-edge/pull/38),
252
+ [`996d4fd`](https://github.com/mad-core/mad-edge/commit/996d4fd9f1862d1c44fc261d099590d242209d45))
253
+
254
+ ### Features
255
+
256
+ - **http**: Add /v1/sessions/{id}/tasks endpoints for the task queue
257
+ ([`3dc8a4b`](https://github.com/mad-core/mad-edge/commit/3dc8a4b29ffaae5598298ba031662aa857a68bf1))
258
+ - **http**: Add session cleanup endpoint and hide deleted by default (#37)
259
+ ([#37](https://github.com/mad-core/mad-edge/pull/37),
260
+ [`e3a27f3`](https://github.com/mad-core/mad-edge/commit/e3a27f3b831cda2db810ba0184e809ab3beb99f1))
261
+
262
+
263
+ ## v0.5.1 (2026-05-09)
264
+
265
+ ### Features
266
+
267
+ - **claude-cli**: Inject MAD_SESSION_ID/MAD_HOOK_SOCKET/MAD_PROVIDER
268
+ ([`0dc11cf`](https://github.com/mad-core/mad-edge/commit/0dc11cf123154d2f93b56275ac316d9adab37c4a))
269
+ - **cli**: Start public TCP and internal UDS uvicorn servers in parallel
270
+ ([`b063c81`](https://github.com/mad-core/mad-edge/commit/b063c819d0e0c5461e9ccc10c12b2ddb4c7cba80))
271
+ - **internal**: Add inbound adapter for claude-cli hook ingestion
272
+ ([`588d745`](https://github.com/mad-core/mad-edge/commit/588d745ba6ebc6f8d2d6b751c5fc6dfae847d1f9))
273
+ - **provisioner**: Install claude hooks + isolate via .git/info/exclude
274
+ ([`ce6d25c`](https://github.com/mad-core/mad-edge/commit/ce6d25cc92425cf6ab7bccbc40fcf9c37d6f5d12))
275
+
276
+
277
+ ## v0.5.0 (2026-05-07)
278
+
279
+ ### Bug Fixes
280
+
281
+ - **sessions**: Coerce naive datetime filters to UTC on /v1/sessions
282
+ ([`a9af871`](https://github.com/mad-core/mad-edge/commit/a9af871690b34d732a00baa13ee002213cbf35b8))
283
+
284
+ ### Features
285
+
286
+ - **sessions**: Expose created_at/updated_at and filter list endpoint
287
+ ([`a9a95bb`](https://github.com/mad-core/mad-edge/commit/a9a95bb535dcdd65a4e297db21903baaf2c78117))
288
+
289
+
290
+ ## v0.4.0 (2026-05-07)
291
+
292
+ ### Bug Fixes
293
+
294
+ - **http**: Type request bodies with Pydantic and tolerate invalid Last-Event-ID
295
+ ([`fe0f8c3`](https://github.com/mad-core/mad-edge/commit/fe0f8c3b8a2628eecb3d32cd40a2015c3f0e25e9))
296
+ - **sessions**: List every persisted session, not just the in-memory ones
297
+ ([`55e0647`](https://github.com/mad-core/mad-edge/commit/55e0647eff37e524ae5700815efb9b1d19011c80))
298
+
299
+ ### Features
300
+
301
+ - **api**: Add /v1/events and /v1/events/stream endpoints
302
+ ([`5b5bdc1`](https://github.com/mad-core/mad-edge/commit/5b5bdc186001e93518b578530e78e9e0e5634918))
303
+ - **core**: Add InMemoryEventBus and JsonlEventLogQuery adapters
304
+ ([`8e5ce11`](https://github.com/mad-core/mad-edge/commit/8e5ce11b337590c153ebdf44eb3e88295f295430))
305
+ - **core**: Add StreamEventsUseCase and QueryEventsUseCase
306
+ ([`0410d05`](https://github.com/mad-core/mad-edge/commit/0410d051efdd66ba61d702e34d668069cff64c21))
307
+ - **core**: Inject UUIDv7 event_id on every persisted event
308
+ ([`cb4cd1d`](https://github.com/mad-core/mad-edge/commit/cb4cd1d822aa19b5c63e25c911d5367bf8d40c89))
309
+ - **core**: Scaffold events module domain and ports
310
+ ([`b846da9`](https://github.com/mad-core/mad-edge/commit/b846da92c4c086669cac087f1dc248c5ce68a949))
311
+ - **core**: Wire EventBus into SendUserMessage and create_app
312
+ ([`2edcb0a`](https://github.com/mad-core/mad-edge/commit/2edcb0a5850b055a2f5bbd977c4b44a9e8a698a6))
313
+ - **sessions**: Emit session.deleted via EventEmitter on delete
314
+ ([`c1d1d52`](https://github.com/mad-core/mad-edge/commit/c1d1d5217bf010e30147f7ab6002739ddd7f70d5))
315
+
316
+
317
+ ## v0.3.0 (2026-05-04)
318
+
319
+ ### Bug Fixes
320
+
321
+ - Include use_cases/sessions/ files missed by gitignore
322
+ ([`c04c318`](https://github.com/mad-core/mad-edge/commit/c04c318c9d15399c5f277918ef683e0c0ea9d631))
323
+ - **makefile**: Point serve target at the new adapters path
324
+ ([`846274c`](https://github.com/mad-core/mad-edge/commit/846274ca2222a0dae2475aac676cd8923784666d))
325
+
326
+ ### Features
327
+
328
+ - **api**: Inject launcher_factory and relocate test doubles
329
+ ([`3c4f322`](https://github.com/mad-core/mad-edge/commit/3c4f322a0f29e3b04da0c4e14997a0c81ad1d449))
330
+ - **core**: Introduce domain entities and use cases (Phase 4)
331
+ ([`6995d5e`](https://github.com/mad-core/mad-edge/commit/6995d5e561ae2821e6e5f50673a21932f4597317))
332
+ - **core**: Introduce outbound ports (Phase 3)
333
+ ([`199bb48`](https://github.com/mad-core/mad-edge/commit/199bb48a769fa3e35cd63d5a93cc82c048d7b8bb))
334
+ - **core**: Pin base_branch and run post-run auto-sync via second claude-cli invocation
335
+ ([`d7f75f5`](https://github.com/mad-core/mad-edge/commit/d7f75f5d2322f0c85fca1c13427dfffeb3a297d4))
336
+
337
+
338
+ ## v0.2.0 (2026-04-30)
339
+
340
+ ### Features
341
+
342
+ - **claude-cli**: Implement ClaudeCLI provider with timeout and cancellation
343
+ ([`96ecfe3`](https://github.com/mad-core/mad-edge/commit/96ecfe31dbe98482cfbfe8730aee6bbe2c687ecf))
344
+ - **infra**: Realign codebase to infrastructure-only architecture
345
+ ([`7471cb1`](https://github.com/mad-core/mad-edge/commit/7471cb13abebc182ad9d279944ad22ca3569a92c))
346
+
347
+
348
+ ## v0.1.0 (2026-04-15)
349
+
350
+ ### Build System
351
+
352
+ - **pypi**: Rename package to mad-bros
353
+ ([`fbb828c`](https://github.com/mad-core/mad-edge/commit/fbb828cc0e8501fa846725bb1d2d430cecc479e4))
354
+
355
+ ### Features
356
+
357
+ - Initialize project infrastructure for Mad v0.1
358
+ ([`1494569`](https://github.com/mad-core/mad-edge/commit/1494569f02344b9b0a923446f765801e37f728ec))
359
+ - **api**: Implement session management and provider interfaces
360
+ ([`b232a75`](https://github.com/mad-core/mad-edge/commit/b232a756af10e05e32bfd8e635380bdb3f6c2aff))
mad_edge-0.6.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jose Salamanca
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,204 @@
1
+ Metadata-Version: 2.4
2
+ Name: mad-edge
3
+ Version: 0.6.0
4
+ Summary: Self-hosted infrastructure that provisions isolated workspaces, clones GitHub repos, and launches external coding agents (Claude Code CLI) — streaming their stdout as agent.output SSE events. Not an orchestrator: no tool-call parsing, no conversation loop.
5
+ Project-URL: Homepage, https://github.com/mad-core/mad-edge
6
+ Project-URL: Issues, https://github.com/mad-core/mad-edge/issues
7
+ Author-email: Jose Salamanca <jose.salamancacoy@gmail.com>, Cristian Moreno <cristianfmoreno95@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 Jose Salamanca
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ License-File: LICENSE
30
+ Keywords: agents,automation,claude,github,infrastructure,sse
31
+ Classifier: Development Status :: 3 - Alpha
32
+ Classifier: Framework :: FastAPI
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: POSIX :: Linux
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Requires-Python: >=3.11
39
+ Requires-Dist: anthropic>=0.39
40
+ Requires-Dist: fastapi>=0.110
41
+ Requires-Dist: httpx>=0.27
42
+ Requires-Dist: mcp<2,>=1.0
43
+ Requires-Dist: uvicorn[standard]>=0.29
44
+ Provides-Extra: dev
45
+ Requires-Dist: build>=1.2; extra == 'dev'
46
+ Requires-Dist: import-linter>=2.0; extra == 'dev'
47
+ Requires-Dist: mypy>=1.10; extra == 'dev'
48
+ Requires-Dist: pip-audit>=2.7; extra == 'dev'
49
+ Requires-Dist: pre-commit>=3.7; extra == 'dev'
50
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
51
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
52
+ Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
53
+ Requires-Dist: pytest>=8.0; extra == 'dev'
54
+ Requires-Dist: python-semantic-release>=10.5.3; extra == 'dev'
55
+ Requires-Dist: ruff>=0.6; extra == 'dev'
56
+ Requires-Dist: twine>=5.1; extra == 'dev'
57
+ Description-Content-Type: text/markdown
58
+
59
+ # Mad
60
+
61
+ > That's mad!
62
+
63
+ **M**ulti **A**gent **D**evelop — self-hosted infrastructure for **delegating coding work to external agents and walking away.** Queue tasks per session, chain sessions into a validated DAG workflow (`depends_on`, including cross-repo handoff where a later step checks out the exact branch/commit an earlier step produced), and confine runs to the hours and days you choose (`WorkWindowPolicy`, timezone-aware). Hit a Claude Pro/Max rate limit and Mad **waits until the window resets and resumes the same conversation** — reusing capacity you have already paid for instead of failing. Every run closes with an auto-sync step that attempts branch → commit → push → open a PR with the result.
64
+
65
+ Under the hood Mad provisions isolated workspaces, clones a GitHub repository, and launches an external coding agent (Claude Code CLI today) against it. Each agent's stdout is streamed as `agent.output` Server-Sent Events on a per-session log, and a final `session.status_idle` (or `session.error`) event signals completion.
66
+
67
+ **The core stays pure infrastructure; orchestration is a real, shipping layer on top of it.** Mad itself does NOT parse tool calls, NOT execute tools, and NOT manage a conversation loop — those concerns belong to the external agent's own harness. It *uses* Claude Code / Codex / opencode; it never runs the agent's reasoning loop. Sessions run in parallel, each with its own agent process and event stream, and the workflow layer coordinates them by git branch/commit handoff — not by richer shared state.
68
+
69
+ The full scope contract lives in [`CLAUDE.md`](CLAUDE.md) ("What this project is" + hard rule 1).
70
+
71
+ ## Status
72
+
73
+ Early days — `0.x`. Single launcher provider (`claude_cli`); HTTP + SSE surface stable enough to build clients against; multi-tenancy deferred ([ADR-0006](docs/adr/0006-multi-tenancy-deferred.md)).
74
+
75
+ ## Requirements
76
+
77
+ - Linux host (see `Operating System :: POSIX :: Linux` classifier)
78
+ - Python ≥ 3.11
79
+ - The `claude` CLI installed and on `PATH` (override the binary with `MAD_CLAUDE_CLI_BIN`)
80
+ - Optionally: the `opencode` CLI for the `opencode` provider (override the binary with `MAD_OPENCODE_BIN`)
81
+ - Launcher timeout is agent-agnostic: set `MAD_AGENT_TIMEOUT_S` (default 600 s) for the operator-wide default, or pass `timeout_s` on `POST /v1/sessions` to override it per session (resolution: per-session `timeout_s` > `MAD_AGENT_TIMEOUT_S` > 600 s)
82
+ - A GitHub token with `repo` scope for cloning private repos (passed per-request, never persisted — see hard rule 2)
83
+ - Session workspaces are created under `~/mad` by default. Override the base directory with `MAD_WORKSPACE_DIR` (used verbatim — no `~`/`$VAR` expansion) when you need a larger or persistent disk; resolution is `MAD_WORKSPACE_DIR` → `~/mad` → the system temp dir (last resort, only if the home directory cannot be resolved). The base is created on first use.
84
+ - Session JSONL logs (the source of truth, hard rule 6) are written under `./sessions` by default. Override the directory with `MAD_SESSIONS_DIR` (used verbatim — no `~`/`$VAR` expansion) when you need a persistent or shared disk; an unset or blank value falls back to `./sessions`. The directory is created on first write.
85
+ - Per-session JSONL event logs (`sessions/`) are kept forever by default. Set `MAD_SESSIONS_RETENTION_DAYS` to a positive integer to enable TTL retention: at startup Mad purges any session log whose **last** event is older than that many days. Unset, `0`, or a negative/non-integer value disables purging (keep forever — the safe default, no behavior change).
86
+
87
+ ## Install
88
+
89
+ The distribution is published as `mad-edge`; the import package is `mad` and the console script is `mad-edge`:
90
+
91
+ ```bash
92
+ pip install mad-edge
93
+ mad-edge serve # uvicorn factory on 0.0.0.0:8000 by default
94
+ ```
95
+
96
+ > Prior to 0.6.0 this distribution was published as `mad-bros`; that name is deprecated and will
97
+ > receive no further releases. The import package remains `mad`; the `mad` console command now
98
+ > belongs to the separate `mad-cli` operator tool.
99
+
100
+ From a checkout (development):
101
+
102
+ ```bash
103
+ make install # create venv + `pip install -e '.[dev]'`
104
+ make test # pytest -q
105
+ make serve # uvicorn mad.adapters.inbound.http.app:create_app --factory
106
+ make help # full target list
107
+ ```
108
+
109
+ With Docker (one or more isolated instances on a single host):
110
+
111
+ ```bash
112
+ cp .env.example .env
113
+ docker compose -f compose.example.yml up -d --build
114
+ ```
115
+
116
+ See [`docs/05-operations/runbooks/docker.md`](docs/05-operations/runbooks/docker.md) for per-instance credential setup, the
117
+ workspace bind-mount model, and running multiple instances.
118
+
119
+ ## Quickstart
120
+
121
+ A session has two parts: an **agent spec** (which launcher to run) and a list of **resources** to mount into the isolated workspace. Resources can be `github_repository` (cloned into `mount_path`) or `file` (literal `content` written at `mount_path`). The prompt is sent as a separate message after creation; that's what kicks the agent off.
122
+
123
+ ```bash
124
+ # 1. Create the session — provisions a workspace and clones the repo.
125
+ curl -sS -X POST http://localhost:8000/v1/sessions \
126
+ -H 'Content-Type: application/json' \
127
+ -d '{
128
+ "agent": {
129
+ "name": "my-agent",
130
+ "provider": "claude_cli"
131
+ },
132
+ "resources": [
133
+ {
134
+ "type": "github_repository",
135
+ "url": "https://github.com/octocat/Hello-World.git",
136
+ "mount_path": "/workspace/repo",
137
+ "checkout": {"type": "branch", "name": "main"}
138
+ }
139
+ ]
140
+ }'
141
+ # → { "session_id": "sesn_…", "status": "created", "workspace": "…", "resources_mounted": […] }
142
+
143
+ # 2. Send the first user message — this launches the external agent.
144
+ curl -sS -X POST http://localhost:8000/v1/sessions/sesn_XXX/messages \
145
+ -H 'Content-Type: application/json' \
146
+ -d '{"content": "Summarize the README in one sentence."}'
147
+
148
+ # 3. Stream the cross-session event log (Last-Event-ID resumable per ADR-0005).
149
+ curl -N http://localhost:8000/v1/events/stream
150
+ # Optional filters: ?session_id=sesn_XXX&kind=agent.output
151
+ ```
152
+
153
+ Each frame on the stream is `id: <uuidv7>\ndata: {…}\n\n` where the JSON object carries `event_id`, `session_id`, `type`, `data`, and `timestamp`. Representative types Mad emits:
154
+
155
+ | Type | Emitted when |
156
+ |---|---|
157
+ | `session.created` | Session row written and workspace provisioned |
158
+ | `agent.output` | One line of stdout from the external agent |
159
+ | `session.status_idle` | Agent exited 0 |
160
+ | `session.error` | Agent exited non-zero or timed out |
161
+
162
+ For private repos, configure the clone credential on the **host** where Mad runs via the standard `GITHUB_TOKEN` (or its `GH_TOKEN` alias) environment variable — not in the request body. Mad reads it at clone time, uses it once for `git clone`, and immediately strips it from the remote URL ([hard rule 2](CLAUDE.md)). The inline `authorization_token` field on the `github_repository` resource is **deprecated** (removal target v0.6.0) and emits a deprecation warning when supplied; prefer the host env var. For historical replay outside SSE, `GET /v1/events?after_event_id=…&limit=…` returns the same shape with a `next_cursor`.
163
+
164
+ ## Project structure
165
+
166
+ The package follows a hexagonal / ports-and-adapters layout — see [ADR-0003](docs/adr/0003-package-layout.md) for the rationale.
167
+
168
+ ```
169
+ mad/
170
+ ├── pyproject.toml # package metadata, deps, `mad-edge` console script
171
+ ├── src/mad/
172
+ │ ├── core/ # framework-free domain (no FastAPI, no subprocess)
173
+ │ │ ├── sessions/ # sessions bounded context (domain, ports, use_cases)
174
+ │ │ └── events/ # cross-session events (domain, ports, use_cases, emitter)
175
+ │ ├── adapters/
176
+ │ │ ├── inbound/http/ # FastAPI app factory + routes (sessions, events stream)
177
+ │ │ └── outbound/ # agents (claude_cli launcher), persistence (JSONL), events
178
+ │ └── entry_points/cli.py # `mad-edge` console script (uvicorn launcher)
179
+ └── tests/
180
+ ├── unit/ # core + adapters in isolation
181
+ ├── integration/ # HTTP + SSE end-to-end
182
+ └── support/ # test-only doubles (e.g. ScriptedLauncher)
183
+ ```
184
+
185
+ The architectural boundary (`mad.core` is framework-free and adapter-free) is enforced by `import-linter` — see hard rule 4 in [`CLAUDE.md`](CLAUDE.md).
186
+
187
+ ## Vision
188
+
189
+ Mad already uses this infrastructure as the substrate for multi-agent workflows: you chain sessions into a validated DAG with `depends_on`, hand off work across repositories by branch and commit, prioritize across a global queue, and confine runs to a scheduling window — all backed by a complete, append-only event log (JSONL) that records both successes and failures and is queryable over HTTP, SSE, and MCP. The "Multi Agent Develop — takes an idea and ships it end-to-end" framing is a current capability, not a promise for later: the workflow layer ships today.
190
+
191
+ The core package stays a pure infrastructure layer; orchestration lives as a real, shipping layer on top of it, never inside the substrate. What is still deferred is worth naming honestly: the handoff between steps is git branch/commit only (not richer shared collaboration), and the closing auto-sync step always *attempts* to open a PR but does not itself guarantee or verify one. Running one isolated Mad instance per stage — plan, dev, review, docs, release — is a pattern you can compose today, not a built-in pipeline.
192
+
193
+ ## Documentation
194
+
195
+ - [`docs/adr/`](docs/adr/) — Architecture Decision Records (start at `README.md`).
196
+ - [`docs/08-rfcs/backlog.md`](docs/08-rfcs/backlog.md) — improvements deferred past v0.1.
197
+ - [`docs/05-operations/runbooks/docker.md`](docs/05-operations/runbooks/docker.md) — operator's guide for running one or more isolated Mad instances with Docker.
198
+ - [`docs/05-operations/runbooks/sandbox-bwrap.md`](docs/05-operations/runbooks/sandbox-bwrap.md) — operator's guide for hardening the sandbox with bubblewrap.
199
+ - [`docs/05-operations/runbooks/ai-develop-on-issue.md`](docs/05-operations/runbooks/ai-develop-on-issue.md) — operator's guide for the label-gated GitHub Action that runs Claude on an issue.
200
+ - [`docs/04-conventions/testing-heuristics.md`](docs/04-conventions/testing-heuristics.md) — the eight heuristics every test must satisfy (hard rule 10).
201
+
202
+ ## License
203
+
204
+ See [`LICENSE`](LICENSE).