@citadel-labs/citadel 0.1.0

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 (307) hide show
  1. package/README.md +145 -0
  2. package/dist/__tests__/append-bead.test.d.ts +2 -0
  3. package/dist/__tests__/append-bead.test.d.ts.map +1 -0
  4. package/dist/__tests__/append-bead.test.js +88 -0
  5. package/dist/__tests__/append-bead.test.js.map +1 -0
  6. package/dist/__tests__/blocked-outposts.test.d.ts +2 -0
  7. package/dist/__tests__/blocked-outposts.test.d.ts.map +1 -0
  8. package/dist/__tests__/blocked-outposts.test.js +142 -0
  9. package/dist/__tests__/blocked-outposts.test.js.map +1 -0
  10. package/dist/__tests__/bugfixes.test.d.ts +2 -0
  11. package/dist/__tests__/bugfixes.test.d.ts.map +1 -0
  12. package/dist/__tests__/bugfixes.test.js +503 -0
  13. package/dist/__tests__/bugfixes.test.js.map +1 -0
  14. package/dist/__tests__/citizen-tribute.test.d.ts +2 -0
  15. package/dist/__tests__/citizen-tribute.test.d.ts.map +1 -0
  16. package/dist/__tests__/citizen-tribute.test.js +106 -0
  17. package/dist/__tests__/citizen-tribute.test.js.map +1 -0
  18. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.d.ts +2 -0
  19. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.d.ts.map +1 -0
  20. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.js +65 -0
  21. package/dist/__tests__/cli-e2e/dispatch-note-resolve.test.js.map +1 -0
  22. package/dist/__tests__/cli-e2e/full-lifecycle.test.d.ts +2 -0
  23. package/dist/__tests__/cli-e2e/full-lifecycle.test.d.ts.map +1 -0
  24. package/dist/__tests__/cli-e2e/full-lifecycle.test.js +157 -0
  25. package/dist/__tests__/cli-e2e/full-lifecycle.test.js.map +1 -0
  26. package/dist/__tests__/cli-e2e/helpers.d.ts +28 -0
  27. package/dist/__tests__/cli-e2e/helpers.d.ts.map +1 -0
  28. package/dist/__tests__/cli-e2e/helpers.js +76 -0
  29. package/dist/__tests__/cli-e2e/helpers.js.map +1 -0
  30. package/dist/__tests__/cli-e2e/init-outpost-status.test.d.ts +2 -0
  31. package/dist/__tests__/cli-e2e/init-outpost-status.test.d.ts.map +1 -0
  32. package/dist/__tests__/cli-e2e/init-outpost-status.test.js +79 -0
  33. package/dist/__tests__/cli-e2e/init-outpost-status.test.js.map +1 -0
  34. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.d.ts +2 -0
  35. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.d.ts.map +1 -0
  36. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.js +158 -0
  37. package/dist/__tests__/cli-e2e/reset-stop-tribute-trace.test.js.map +1 -0
  38. package/dist/__tests__/courier.test.d.ts +2 -0
  39. package/dist/__tests__/courier.test.d.ts.map +1 -0
  40. package/dist/__tests__/courier.test.js +97 -0
  41. package/dist/__tests__/courier.test.js.map +1 -0
  42. package/dist/__tests__/e2e-smoke.test.d.ts +2 -0
  43. package/dist/__tests__/e2e-smoke.test.d.ts.map +1 -0
  44. package/dist/__tests__/e2e-smoke.test.js +137 -0
  45. package/dist/__tests__/e2e-smoke.test.js.map +1 -0
  46. package/dist/__tests__/fo-broadcast.test.d.ts +2 -0
  47. package/dist/__tests__/fo-broadcast.test.d.ts.map +1 -0
  48. package/dist/__tests__/fo-broadcast.test.js +134 -0
  49. package/dist/__tests__/fo-broadcast.test.js.map +1 -0
  50. package/dist/__tests__/fo-command-processor.test.d.ts +2 -0
  51. package/dist/__tests__/fo-command-processor.test.d.ts.map +1 -0
  52. package/dist/__tests__/fo-command-processor.test.js +86 -0
  53. package/dist/__tests__/fo-command-processor.test.js.map +1 -0
  54. package/dist/__tests__/fo-escalation.test.d.ts +2 -0
  55. package/dist/__tests__/fo-escalation.test.d.ts.map +1 -0
  56. package/dist/__tests__/fo-escalation.test.js +126 -0
  57. package/dist/__tests__/fo-escalation.test.js.map +1 -0
  58. package/dist/__tests__/fo-nudge-watcher.test.d.ts +2 -0
  59. package/dist/__tests__/fo-nudge-watcher.test.d.ts.map +1 -0
  60. package/dist/__tests__/fo-nudge-watcher.test.js +154 -0
  61. package/dist/__tests__/fo-nudge-watcher.test.js.map +1 -0
  62. package/dist/__tests__/fo-nudge-wiring.test.d.ts +2 -0
  63. package/dist/__tests__/fo-nudge-wiring.test.d.ts.map +1 -0
  64. package/dist/__tests__/fo-nudge-wiring.test.js +31 -0
  65. package/dist/__tests__/fo-nudge-wiring.test.js.map +1 -0
  66. package/dist/__tests__/fo-relay.test.d.ts +2 -0
  67. package/dist/__tests__/fo-relay.test.d.ts.map +1 -0
  68. package/dist/__tests__/fo-relay.test.js +90 -0
  69. package/dist/__tests__/fo-relay.test.js.map +1 -0
  70. package/dist/__tests__/fo-task-report.test.d.ts +2 -0
  71. package/dist/__tests__/fo-task-report.test.d.ts.map +1 -0
  72. package/dist/__tests__/fo-task-report.test.js +81 -0
  73. package/dist/__tests__/fo-task-report.test.js.map +1 -0
  74. package/dist/__tests__/fo-webhook.test.d.ts +2 -0
  75. package/dist/__tests__/fo-webhook.test.d.ts.map +1 -0
  76. package/dist/__tests__/fo-webhook.test.js +70 -0
  77. package/dist/__tests__/fo-webhook.test.js.map +1 -0
  78. package/dist/__tests__/integration.test.d.ts +2 -0
  79. package/dist/__tests__/integration.test.d.ts.map +1 -0
  80. package/dist/__tests__/integration.test.js +763 -0
  81. package/dist/__tests__/integration.test.js.map +1 -0
  82. package/dist/__tests__/multi-outpost-dep.test.d.ts +2 -0
  83. package/dist/__tests__/multi-outpost-dep.test.d.ts.map +1 -0
  84. package/dist/__tests__/multi-outpost-dep.test.js +173 -0
  85. package/dist/__tests__/multi-outpost-dep.test.js.map +1 -0
  86. package/dist/__tests__/nudge.test.d.ts +2 -0
  87. package/dist/__tests__/nudge.test.d.ts.map +1 -0
  88. package/dist/__tests__/nudge.test.js +103 -0
  89. package/dist/__tests__/nudge.test.js.map +1 -0
  90. package/dist/__tests__/outpost-registry.test.d.ts +2 -0
  91. package/dist/__tests__/outpost-registry.test.d.ts.map +1 -0
  92. package/dist/__tests__/outpost-registry.test.js +72 -0
  93. package/dist/__tests__/outpost-registry.test.js.map +1 -0
  94. package/dist/__tests__/process-registry.test.d.ts +2 -0
  95. package/dist/__tests__/process-registry.test.d.ts.map +1 -0
  96. package/dist/__tests__/process-registry.test.js +108 -0
  97. package/dist/__tests__/process-registry.test.js.map +1 -0
  98. package/dist/__tests__/session-log.test.d.ts +2 -0
  99. package/dist/__tests__/session-log.test.d.ts.map +1 -0
  100. package/dist/__tests__/session-log.test.js +60 -0
  101. package/dist/__tests__/session-log.test.js.map +1 -0
  102. package/dist/__tests__/spawn-citizen.test.d.ts +2 -0
  103. package/dist/__tests__/spawn-citizen.test.d.ts.map +1 -0
  104. package/dist/__tests__/spawn-citizen.test.js +48 -0
  105. package/dist/__tests__/spawn-citizen.test.js.map +1 -0
  106. package/dist/__tests__/timeout-watchdog.test.d.ts +2 -0
  107. package/dist/__tests__/timeout-watchdog.test.d.ts.map +1 -0
  108. package/dist/__tests__/timeout-watchdog.test.js +81 -0
  109. package/dist/__tests__/timeout-watchdog.test.js.map +1 -0
  110. package/dist/__tests__/worktree-manager.test.d.ts +2 -0
  111. package/dist/__tests__/worktree-manager.test.d.ts.map +1 -0
  112. package/dist/__tests__/worktree-manager.test.js +98 -0
  113. package/dist/__tests__/worktree-manager.test.js.map +1 -0
  114. package/dist/cli/aliases.d.ts +10 -0
  115. package/dist/cli/aliases.d.ts.map +1 -0
  116. package/dist/cli/aliases.js +56 -0
  117. package/dist/cli/aliases.js.map +1 -0
  118. package/dist/cli/command.d.ts +3 -0
  119. package/dist/cli/command.d.ts.map +1 -0
  120. package/dist/cli/command.js +63 -0
  121. package/dist/cli/command.js.map +1 -0
  122. package/dist/cli/index.d.ts +3 -0
  123. package/dist/cli/index.d.ts.map +1 -0
  124. package/dist/cli/index.js +29 -0
  125. package/dist/cli/index.js.map +1 -0
  126. package/dist/cli/init.d.ts +3 -0
  127. package/dist/cli/init.d.ts.map +1 -0
  128. package/dist/cli/init.js +57 -0
  129. package/dist/cli/init.js.map +1 -0
  130. package/dist/cli/outpost.d.ts +3 -0
  131. package/dist/cli/outpost.d.ts.map +1 -0
  132. package/dist/cli/outpost.js +65 -0
  133. package/dist/cli/outpost.js.map +1 -0
  134. package/dist/cli/reset.d.ts +3 -0
  135. package/dist/cli/reset.d.ts.map +1 -0
  136. package/dist/cli/reset.js +67 -0
  137. package/dist/cli/reset.js.map +1 -0
  138. package/dist/cli/session.d.ts +3 -0
  139. package/dist/cli/session.d.ts.map +1 -0
  140. package/dist/cli/session.js +112 -0
  141. package/dist/cli/session.js.map +1 -0
  142. package/dist/cli/start.d.ts +3 -0
  143. package/dist/cli/start.d.ts.map +1 -0
  144. package/dist/cli/start.js +105 -0
  145. package/dist/cli/start.js.map +1 -0
  146. package/dist/cli/status.d.ts +3 -0
  147. package/dist/cli/status.d.ts.map +1 -0
  148. package/dist/cli/status.js +128 -0
  149. package/dist/cli/status.js.map +1 -0
  150. package/dist/cli/tribute.d.ts +3 -0
  151. package/dist/cli/tribute.d.ts.map +1 -0
  152. package/dist/cli/tribute.js +160 -0
  153. package/dist/cli/tribute.js.map +1 -0
  154. package/dist/cli/worktree.d.ts +3 -0
  155. package/dist/cli/worktree.d.ts.map +1 -0
  156. package/dist/cli/worktree.js +64 -0
  157. package/dist/cli/worktree.js.map +1 -0
  158. package/dist/core/append-bead.d.ts +13 -0
  159. package/dist/core/append-bead.d.ts.map +1 -0
  160. package/dist/core/append-bead.js +68 -0
  161. package/dist/core/append-bead.js.map +1 -0
  162. package/dist/core/blocked-outposts.d.ts +15 -0
  163. package/dist/core/blocked-outposts.d.ts.map +1 -0
  164. package/dist/core/blocked-outposts.js +77 -0
  165. package/dist/core/blocked-outposts.js.map +1 -0
  166. package/dist/core/citizen-bootstrap.d.ts +17 -0
  167. package/dist/core/citizen-bootstrap.d.ts.map +1 -0
  168. package/dist/core/citizen-bootstrap.js +118 -0
  169. package/dist/core/citizen-bootstrap.js.map +1 -0
  170. package/dist/core/citizen-tribute.d.ts +17 -0
  171. package/dist/core/citizen-tribute.d.ts.map +1 -0
  172. package/dist/core/citizen-tribute.js +55 -0
  173. package/dist/core/citizen-tribute.js.map +1 -0
  174. package/dist/core/command-bead.d.ts +6 -0
  175. package/dist/core/command-bead.d.ts.map +1 -0
  176. package/dist/core/command-bead.js +20 -0
  177. package/dist/core/command-bead.js.map +1 -0
  178. package/dist/core/courier.d.ts +52 -0
  179. package/dist/core/courier.d.ts.map +1 -0
  180. package/dist/core/courier.js +167 -0
  181. package/dist/core/courier.js.map +1 -0
  182. package/dist/core/fo-broadcast.d.ts +15 -0
  183. package/dist/core/fo-broadcast.d.ts.map +1 -0
  184. package/dist/core/fo-broadcast.js +57 -0
  185. package/dist/core/fo-broadcast.js.map +1 -0
  186. package/dist/core/fo-command-processor.d.ts +7 -0
  187. package/dist/core/fo-command-processor.d.ts.map +1 -0
  188. package/dist/core/fo-command-processor.js +123 -0
  189. package/dist/core/fo-command-processor.js.map +1 -0
  190. package/dist/core/fo-dispatch.d.ts +24 -0
  191. package/dist/core/fo-dispatch.d.ts.map +1 -0
  192. package/dist/core/fo-dispatch.js +76 -0
  193. package/dist/core/fo-dispatch.js.map +1 -0
  194. package/dist/core/fo-escalation.d.ts +20 -0
  195. package/dist/core/fo-escalation.d.ts.map +1 -0
  196. package/dist/core/fo-escalation.js +83 -0
  197. package/dist/core/fo-escalation.js.map +1 -0
  198. package/dist/core/fo-handlers/ceiling-hit.d.ts +8 -0
  199. package/dist/core/fo-handlers/ceiling-hit.d.ts.map +1 -0
  200. package/dist/core/fo-handlers/ceiling-hit.js +10 -0
  201. package/dist/core/fo-handlers/ceiling-hit.js.map +1 -0
  202. package/dist/core/fo-handlers/slot-open.d.ts +13 -0
  203. package/dist/core/fo-handlers/slot-open.d.ts.map +1 -0
  204. package/dist/core/fo-handlers/slot-open.js +63 -0
  205. package/dist/core/fo-handlers/slot-open.js.map +1 -0
  206. package/dist/core/fo-nudge-watcher.d.ts +19 -0
  207. package/dist/core/fo-nudge-watcher.d.ts.map +1 -0
  208. package/dist/core/fo-nudge-watcher.js +71 -0
  209. package/dist/core/fo-nudge-watcher.js.map +1 -0
  210. package/dist/core/fo-nudge-wiring.d.ts +13 -0
  211. package/dist/core/fo-nudge-wiring.d.ts.map +1 -0
  212. package/dist/core/fo-nudge-wiring.js +120 -0
  213. package/dist/core/fo-nudge-wiring.js.map +1 -0
  214. package/dist/core/fo-relay.d.ts +7 -0
  215. package/dist/core/fo-relay.d.ts.map +1 -0
  216. package/dist/core/fo-relay.js +47 -0
  217. package/dist/core/fo-relay.js.map +1 -0
  218. package/dist/core/fo-retry-policy.d.ts +17 -0
  219. package/dist/core/fo-retry-policy.d.ts.map +1 -0
  220. package/dist/core/fo-retry-policy.js +89 -0
  221. package/dist/core/fo-retry-policy.js.map +1 -0
  222. package/dist/core/fo-state.d.ts +25 -0
  223. package/dist/core/fo-state.d.ts.map +1 -0
  224. package/dist/core/fo-state.js +99 -0
  225. package/dist/core/fo-state.js.map +1 -0
  226. package/dist/core/fo-task-report.d.ts +16 -0
  227. package/dist/core/fo-task-report.d.ts.map +1 -0
  228. package/dist/core/fo-task-report.js +63 -0
  229. package/dist/core/fo-task-report.js.map +1 -0
  230. package/dist/core/fo-webhook.d.ts +22 -0
  231. package/dist/core/fo-webhook.d.ts.map +1 -0
  232. package/dist/core/fo-webhook.js +43 -0
  233. package/dist/core/fo-webhook.js.map +1 -0
  234. package/dist/core/grand-archives.d.ts +14 -0
  235. package/dist/core/grand-archives.d.ts.map +1 -0
  236. package/dist/core/grand-archives.js +79 -0
  237. package/dist/core/grand-archives.js.map +1 -0
  238. package/dist/core/nudge.d.ts +6 -0
  239. package/dist/core/nudge.d.ts.map +1 -0
  240. package/dist/core/nudge.js +19 -0
  241. package/dist/core/nudge.js.map +1 -0
  242. package/dist/core/outpost-registry.d.ts +16 -0
  243. package/dist/core/outpost-registry.d.ts.map +1 -0
  244. package/dist/core/outpost-registry.js +27 -0
  245. package/dist/core/outpost-registry.js.map +1 -0
  246. package/dist/core/pre-spawn-check.d.ts +16 -0
  247. package/dist/core/pre-spawn-check.d.ts.map +1 -0
  248. package/dist/core/pre-spawn-check.js +50 -0
  249. package/dist/core/pre-spawn-check.js.map +1 -0
  250. package/dist/core/process-registry.d.ts +17 -0
  251. package/dist/core/process-registry.d.ts.map +1 -0
  252. package/dist/core/process-registry.js +71 -0
  253. package/dist/core/process-registry.js.map +1 -0
  254. package/dist/core/spawn-citizen.d.ts +23 -0
  255. package/dist/core/spawn-citizen.d.ts.map +1 -0
  256. package/dist/core/spawn-citizen.js +99 -0
  257. package/dist/core/spawn-citizen.js.map +1 -0
  258. package/dist/core/timeout-watchdog.d.ts +14 -0
  259. package/dist/core/timeout-watchdog.d.ts.map +1 -0
  260. package/dist/core/timeout-watchdog.js +68 -0
  261. package/dist/core/timeout-watchdog.js.map +1 -0
  262. package/dist/core/validate-tribute.d.ts +11 -0
  263. package/dist/core/validate-tribute.d.ts.map +1 -0
  264. package/dist/core/validate-tribute.js +44 -0
  265. package/dist/core/validate-tribute.js.map +1 -0
  266. package/dist/core/worktree-manager.d.ts +20 -0
  267. package/dist/core/worktree-manager.d.ts.map +1 -0
  268. package/dist/core/worktree-manager.js +123 -0
  269. package/dist/core/worktree-manager.js.map +1 -0
  270. package/dist/index.d.ts +30 -0
  271. package/dist/index.d.ts.map +1 -0
  272. package/dist/index.js +30 -0
  273. package/dist/index.js.map +1 -0
  274. package/dist/types/agent.d.ts +47 -0
  275. package/dist/types/agent.d.ts.map +1 -0
  276. package/dist/types/agent.js +4 -0
  277. package/dist/types/agent.js.map +1 -0
  278. package/dist/types/beads.d.ts +175 -0
  279. package/dist/types/beads.d.ts.map +1 -0
  280. package/dist/types/beads.js +4 -0
  281. package/dist/types/beads.js.map +1 -0
  282. package/dist/types/index.d.ts +4 -0
  283. package/dist/types/index.d.ts.map +1 -0
  284. package/dist/types/index.js +4 -0
  285. package/dist/types/index.js.map +1 -0
  286. package/dist/types/registry.d.ts +110 -0
  287. package/dist/types/registry.d.ts.map +1 -0
  288. package/dist/types/registry.js +3 -0
  289. package/dist/types/registry.js.map +1 -0
  290. package/docs/README.md +7 -0
  291. package/docs/architecture.md +106 -0
  292. package/docs/cli-reference.md +81 -0
  293. package/docs/configuration.md +143 -0
  294. package/docs/contributing.md +65 -0
  295. package/docs/getting-started.md +88 -0
  296. package/grand-archives/archetypes/architect/archetype.json +18 -0
  297. package/grand-archives/archetypes/qa-engineer/archetype.json +18 -0
  298. package/grand-archives/archetypes/software-engineer/archetype.json +18 -0
  299. package/grand-archives/archetypes/software-engineer/system-prompt.md +39 -0
  300. package/grand-archives/archetypes/software-engineer/toolset.json +15 -0
  301. package/grand-archives/first-officer/config.json +21 -0
  302. package/grand-archives/first-officer/system-prompt.md +47 -0
  303. package/grand-archives/first-officer/toolset.json +19 -0
  304. package/grand-archives/registry.json +8 -0
  305. package/grand-archives/shared/base-prompt-preamble.md +25 -0
  306. package/grand-archives/shared/base-tools.json +10 -0
  307. package/package.json +73 -0
@@ -0,0 +1,143 @@
1
+ # Configuration
2
+
3
+ ## Courier Config
4
+
5
+ `courier.config.yaml` at the workspace root controls the Courier daemon:
6
+
7
+ ```yaml
8
+ citadel_root: .
9
+ poll_interval_ms: 500 # filesystem poll interval
10
+ debounce_ms: 200 # write stabilization delay
11
+ default_max_citizens: 3 # max concurrent citizens per outpost
12
+ citizen_timeout_seconds: 1800 # kill citizens after 30 minutes
13
+ log_level: INFO # DEBUG, INFO, WARN, ERROR
14
+ log_path: .citadel/logs/courier.log
15
+ ```
16
+
17
+ ### Optional Webhook
18
+
19
+ ```yaml
20
+ webhook:
21
+ url: https://hooks.example.com/citadel
22
+ timeout_ms: 5000
23
+ ```
24
+
25
+ On SUCCESS tribute, POSTs a summary to the configured URL.
26
+
27
+ ## Outpost Registry
28
+
29
+ `.citadel/outposts.json` is managed by `citadel outpost register`:
30
+
31
+ ```json
32
+ {
33
+ "schema_version": "1.0",
34
+ "outposts": [
35
+ {
36
+ "slug": "api-gateway",
37
+ "path": "/absolute/path/to/repo",
38
+ "status": "ACTIVE",
39
+ "registered_at": "2026-01-15T10:00:00.000Z",
40
+ "default_archetype": "software-engineer",
41
+ "max_citizens": 3
42
+ }
43
+ ]
44
+ }
45
+ ```
46
+
47
+ ### Outpost Fields
48
+
49
+ | Field | Required | Description |
50
+ |---|---|---|
51
+ | `slug` | Yes | Unique identifier for the outpost |
52
+ | `path` | Yes | Absolute path to the git repository |
53
+ | `status` | Yes | `ACTIVE`, `INACTIVE`, or `SUSPENDED` |
54
+ | `registered_at` | Yes | ISO8601 timestamp |
55
+ | `default_archetype` | No | Archetype to use if none specified in dispatch |
56
+ | `max_citizens` | No | Override `default_max_citizens` for this outpost |
57
+
58
+ ## Grand Archives
59
+
60
+ `grand-archives/` contains archetype configurations:
61
+
62
+ ```
63
+ grand-archives/
64
+ registry.json # lists all archetypes and their status
65
+ first-officer/
66
+ config.json # FO settings: retry policy, nudge retention
67
+ system-prompt.md
68
+ toolset.json
69
+ archetypes/
70
+ software-engineer/
71
+ archetype.json # archetype definition
72
+ system-prompt.md # role-specific instructions
73
+ toolset.json # allowed tools
74
+ shared/
75
+ base-tools.json
76
+ base-prompt-preamble.md # prepended to all system prompts
77
+ ```
78
+
79
+ ### First Officer Config
80
+
81
+ `grand-archives/first-officer/config.json`:
82
+
83
+ ```json
84
+ {
85
+ "schema_version": "1.0",
86
+ "display_name": "First Officer",
87
+ "singleton": true,
88
+ "agent": "claude-code",
89
+ "retry_policy": {
90
+ "max_retries": 3,
91
+ "retry_on": ["PARTIAL", "FAILED", "TRIBUTE_INVALID"],
92
+ "partial_strategy": "remaining_criteria_only",
93
+ "on_ceiling_reached": "ESCALATE_TO_COMMANDER"
94
+ },
95
+ "nudge_retention": 500
96
+ }
97
+ ```
98
+
99
+ ### Archetype Config
100
+
101
+ `grand-archives/archetypes/<key>/archetype.json`:
102
+
103
+ ```json
104
+ {
105
+ "key": "software-engineer",
106
+ "schema_version": "1.0",
107
+ "display_name": "Software Engineer",
108
+ "system_prompt": {
109
+ "preamble_ref": "shared/base-prompt-preamble.md",
110
+ "body_ref": "archetypes/software-engineer/system-prompt.md"
111
+ },
112
+ "toolset": {
113
+ "base_ref": "shared/base-tools.json",
114
+ "override_ref": "archetypes/software-engineer/toolset.json"
115
+ },
116
+ "constraints": {
117
+ "max_tokens_per_turn": 8192,
118
+ "temperature": 0.2,
119
+ "model": "claude-opus-4"
120
+ }
121
+ }
122
+ ```
123
+
124
+ ## Agent Runtime
125
+
126
+ CITADEL is agent-agnostic. Set the runtime at session start:
127
+
128
+ ```bash
129
+ citadel start --agent claude-code # default
130
+ citadel start --agent cursor
131
+ citadel start --agent copilot
132
+ ```
133
+
134
+ Citizens receive these environment variables:
135
+
136
+ | Variable | Description |
137
+ |---|---|
138
+ | `CITADEL_OUTPOST` | Outpost slug |
139
+ | `CITADEL_ARCHETYPE` | Archetype key |
140
+ | `CITADEL_CITIZEN_ID` | Unique citizen identifier |
141
+ | `CITADEL_TASK_ID` | Task identifier |
142
+ | `CITADEL_WORKTREE` | Path to isolated git worktree |
143
+ | `CITADEL_BEADS_ROOT` | Path to citadel workspace root |
@@ -0,0 +1,65 @@
1
+ # Contributing
2
+
3
+ ## Development Setup
4
+
5
+ ```bash
6
+ git clone https://github.com/citadel-labs-hq/citadel.git
7
+ cd citadel
8
+ npm install
9
+ npm run build
10
+ npm test
11
+ ```
12
+
13
+ ## Scripts
14
+
15
+ | Script | Description |
16
+ |---|---|
17
+ | `npm run build` | Compile TypeScript to `dist/` |
18
+ | `npm run dev` | Watch mode compilation |
19
+ | `npm test` | Run all tests (vitest) |
20
+ | `npm run test:watch` | Run tests in watch mode |
21
+ | `npm run test:coverage` | Run tests with v8 coverage |
22
+ | `npm run test:e2e` | Build and run CLI e2e tests |
23
+ | `npm run lint` | Run ESLint on `src/` |
24
+
25
+ ## Project Structure
26
+
27
+ ```
28
+ src/
29
+ cli/ # CLI commands (commander.js)
30
+ core/ # Business logic
31
+ fo-handlers/ # First Officer signal handlers
32
+ types/ # TypeScript type definitions
33
+ __tests__/ # Unit and integration tests
34
+ cli-e2e/ # CLI end-to-end test helpers
35
+ index.ts # Public API exports
36
+ ```
37
+
38
+ ## Testing
39
+
40
+ - Tests use [Vitest](https://vitest.dev/)
41
+ - Each core module should have a corresponding test file in `src/__tests__/`
42
+ - Tests create temporary directories and clean up after themselves
43
+ - Git operations in tests use isolated temp repos
44
+
45
+ ## Code Style
46
+
47
+ - TypeScript strict mode
48
+ - ESLint with `typescript-eslint`
49
+ - Husky pre-commit hook runs `npm run lint`
50
+ - Conventional commits: `type(scope): description`
51
+
52
+ ## Pull Requests
53
+
54
+ 1. Create a feature branch
55
+ 2. Write tests for new functionality
56
+ 3. Ensure `npm run lint` and `npm test` pass
57
+ 4. Use conventional commit messages
58
+ 5. Keep PRs focused — one feature or fix per PR
59
+
60
+ ## Architecture Notes
61
+
62
+ - All state is in append-only JSONL files (Beads)
63
+ - Cross-process safety via `proper-lockfile`
64
+ - Agent-agnostic design — no coupling to specific LLM providers
65
+ - File-based communication — no PIDs, pipes, or network protocols
@@ -0,0 +1,88 @@
1
+ # Getting Started
2
+
3
+ ## Prerequisites
4
+
5
+ - Node.js v20+
6
+ - Git
7
+ - An LLM agent CLI (Claude Code is the default)
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g @citadel-labs/citadel
13
+ ```
14
+
15
+ ## Initialize a Workspace
16
+
17
+ ```bash
18
+ citadel init my-project
19
+ cd my-project
20
+ ```
21
+
22
+ This creates:
23
+ - `.citadel/` — identity, nudges, commands, outpost registry
24
+ - `grand-archives/` — archetype configurations
25
+ - `courier.config.yaml` — daemon settings
26
+
27
+ ## Register an Outpost
28
+
29
+ An Outpost is a code repository where Citizens work:
30
+
31
+ ```bash
32
+ citadel outpost register --slug api-gateway --path ../api-gateway
33
+ ```
34
+
35
+ ## Start a Session
36
+
37
+ ```bash
38
+ citadel start
39
+ ```
40
+
41
+ This writes an Identity Bead, rotates stale nudges, and reconstructs state from existing beads.
42
+
43
+ ## Dispatch a Task
44
+
45
+ ```bash
46
+ citadel dispatch --outpost api-gateway \
47
+ --task "Implement GET /health endpoint"
48
+ ```
49
+
50
+ Or using the full form:
51
+
52
+ ```bash
53
+ citadel command dispatch --outpost api-gateway \
54
+ --task "Implement GET /health endpoint" \
55
+ --archetype software-engineer
56
+ ```
57
+
58
+ ## Check Status
59
+
60
+ ```bash
61
+ citadel status
62
+ ```
63
+
64
+ Shows session info, per-outpost ceiling/pending counts, and unprocessed nudge/command counts.
65
+
66
+ ## View Results
67
+
68
+ ```bash
69
+ # View tribute (work output) for a task
70
+ citadel tribute --task <task-id>
71
+
72
+ # Full event timeline
73
+ citadel trace --task <task-id>
74
+ ```
75
+
76
+ ## Stop a Session
77
+
78
+ ```bash
79
+ citadel stop
80
+ ```
81
+
82
+ Clears unprocessed nudges and writes a shutdown entry to the session log.
83
+
84
+ ## Next Steps
85
+
86
+ - [Architecture](./architecture.md) — understand the chain of command
87
+ - [CLI Reference](./cli-reference.md) — all commands and flags
88
+ - [Configuration](./configuration.md) — customize courier and archetype settings
@@ -0,0 +1,18 @@
1
+ {
2
+ "key": "architect",
3
+ "schema_version": "1.0",
4
+ "display_name": "Architect",
5
+ "system_prompt": {
6
+ "preamble_ref": "shared/base-prompt-preamble.md",
7
+ "body_ref": "archetypes/architect/system-prompt.md"
8
+ },
9
+ "toolset": {
10
+ "base_ref": "shared/base-tools.json",
11
+ "override_ref": "archetypes/architect/toolset.json"
12
+ },
13
+ "constraints": {
14
+ "max_tokens_per_turn": 8192,
15
+ "temperature": 0.2,
16
+ "model": "claude-opus-4"
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "key": "qa-engineer",
3
+ "schema_version": "1.0",
4
+ "display_name": "QA Engineer",
5
+ "system_prompt": {
6
+ "preamble_ref": "shared/base-prompt-preamble.md",
7
+ "body_ref": "archetypes/qa-engineer/system-prompt.md"
8
+ },
9
+ "toolset": {
10
+ "base_ref": "shared/base-tools.json",
11
+ "override_ref": "archetypes/qa-engineer/toolset.json"
12
+ },
13
+ "constraints": {
14
+ "max_tokens_per_turn": 8192,
15
+ "temperature": 0.2,
16
+ "model": "claude-opus-4"
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "key": "software-engineer",
3
+ "schema_version": "1.0",
4
+ "display_name": "Software Engineer",
5
+ "system_prompt": {
6
+ "preamble_ref": "shared/base-prompt-preamble.md",
7
+ "body_ref": "archetypes/software-engineer/system-prompt.md"
8
+ },
9
+ "toolset": {
10
+ "base_ref": "shared/base-tools.json",
11
+ "override_ref": "archetypes/software-engineer/toolset.json"
12
+ },
13
+ "constraints": {
14
+ "max_tokens_per_turn": 8192,
15
+ "temperature": 0.2,
16
+ "model": "claude-opus-4"
17
+ }
18
+ }
@@ -0,0 +1,39 @@
1
+ # Software Engineer — Behavioral Contract
2
+
3
+ ## Core Directives
4
+
5
+ 1. Your identity is CITADEL_CITIZEN_ID. Your workspace is CITADEL_WORKTREE.
6
+ All Bead reads/writes use CITADEL_BEADS_ROOT — not your worktree.
7
+
8
+ 2. Read your full inbox from $CITADEL_BEADS_ROOT/mail/ in arrival order.
9
+
10
+ 3. If no TASK_ASSIGNMENT found: write TASK_REPORT BLOCKED + exit cleanly.
11
+
12
+ 4. If TRIBUTE_INVALID is in your inbox (retry):
13
+ - Read the errors carefully
14
+ - Inspect $CITADEL_WORKTREE for prior attempt's code
15
+ - Decide: build on it, partially reset, or start from scratch
16
+ - Use git reset inside your worktree if needed — the branch is yours
17
+ - Do not blindly repeat what failed
18
+
19
+ 5. Mark each Mail read. Synthesize full context before writing code.
20
+
21
+ 6. Work only inside $CITADEL_WORKTREE.
22
+
23
+ 7. Write tests before or alongside implementation.
24
+
25
+ 8. Your branch already exists: citizen/<task_id>.
26
+
27
+ 9. Determine attempt number: count lines in
28
+ $CITADEL_BEADS_ROOT/tribute/<task_id>_tribute.jsonl
29
+
30
+ ## Completion Sequence
31
+
32
+ 1. Run tests. Confirm they pass.
33
+ 2. Commit changes inside $CITADEL_WORKTREE.
34
+ 3. Open PR from citizen/<task_id> against main.
35
+ 4. Write Tribute to $CITADEL_BEADS_ROOT/tribute/<task_id>_tribute.jsonl
36
+ - artifacts MUST be relative to Outpost root (e.g. src/routes/health.ts)
37
+ - NOT relative to worktree (not worktrees/citizen/<task_id>/src/...)
38
+ 5. Write upward Mail to $CITADEL_BEADS_ROOT/mail/ if needed.
39
+ 6. exit(0)
@@ -0,0 +1,15 @@
1
+ {
2
+ "schema_version": "1.0",
3
+ "description": "Software Engineer toolset — full development capabilities",
4
+ "tools": [
5
+ { "name": "read_bead", "enabled": true },
6
+ { "name": "scan_beads", "enabled": true },
7
+ { "name": "write_mail", "enabled": true },
8
+ { "name": "write_tribute", "enabled": true },
9
+ { "name": "bash", "enabled": true },
10
+ { "name": "write_file", "enabled": true },
11
+ { "name": "git", "enabled": true },
12
+ { "name": "github_pr", "enabled": true },
13
+ { "name": "web_search", "enabled": false }
14
+ ]
15
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "schema_version": "1.0",
3
+ "display_name": "First Officer",
4
+ "singleton": true,
5
+ "assignable": false,
6
+ "agent": "claude-code",
7
+ "system_prompt_ref": "first-officer/system-prompt.md",
8
+ "toolset_ref": "first-officer/toolset.json",
9
+ "model": "claude-opus-4",
10
+ "constraints": {
11
+ "temperature": 0.2,
12
+ "max_tokens_per_turn": 8192
13
+ },
14
+ "retry_policy": {
15
+ "max_retries": 3,
16
+ "retry_on": ["PARTIAL", "FAILED", "TRIBUTE_INVALID"],
17
+ "partial_strategy": "remaining_criteria_only",
18
+ "on_ceiling_reached": "ESCALATE_TO_COMMANDER"
19
+ },
20
+ "nudge_retention": 500
21
+ }
@@ -0,0 +1,47 @@
1
+ # First Officer — Behavioral Contract
2
+
3
+ ## On Session Start
4
+
5
+ 1. Read Identity Bead (last line of .citadel/identity.jsonl)
6
+ 2. Load .citadel/outposts.json
7
+ 3. Scan all Outpost .beads/mail/ and .beads/tribute/ — these are your state sources
8
+ 4. Scan .citadel/commands/ for unprocessed Command Beads
9
+ 5. Reconstruct full system state from Mail + Tribute Beads only.
10
+ Do NOT reconstruct state from Nudge history.
11
+ 6. Write startup report to .citadel/logs/session.log
12
+ 7. Process any unprocessed Nudge Beads as fresh signals
13
+ 8. Process any unprocessed Command Beads
14
+ 9. Watch .citadel/nudges.jsonl — this is your signal channel
15
+
16
+ ## Core Responsibilities
17
+
18
+ 1. Dispatch tasks — Archetype, citizen_id, TASK_ASSIGNMENT with spawn_hint.
19
+ Respect max_citizens ceiling per Outpost.
20
+
21
+ 2. Process Tribute — validate (schema + criteria only), broadcast, retry, escalate.
22
+ Check attempt count from Tribute Bead — not from validateTribute().
23
+
24
+ 3. Slot-open dispatch — on TRIBUTE_WRITTEN SUCCESS, re-scan the Outpost inbox
25
+ for unread TASK_ASSIGNMENT Mail. The inbox is the queue. Dispatch if found
26
+ and under ceiling.
27
+
28
+ 4. Handle PARALLELISM_CEILING_HIT — informational only. Log it. The inbox holds
29
+ the pending work. You will dispatch when the next slot opens.
30
+
31
+ 5. Manage retries — worktree is left as-is for the retry Citizen.
32
+ New Citizen reads TRIBUTE_INVALID and assesses prior state autonomously.
33
+
34
+ 6. Resolve dependencies — getRegisteredOutpostMailDirs() on SUCCESS.
35
+
36
+ 7. Forward relays — RELAY_REQUEST -> PEER_RELAY with spawn_hint.
37
+
38
+ 8. Escalate — at retry ceiling: summarize all attempts, recommend action.
39
+
40
+ ## What You Never Do
41
+
42
+ - Reconstruct state from Nudge history. State lives in Mail + Tribute Beads.
43
+ - Omit spawn_hint from downward Mail.
44
+ - Write files, run git, or touch Outpost code directly.
45
+ - Maintain an internal queue — the inbox is the queue.
46
+ - Check retry ceilings inside validateTribute().
47
+ - Write Mail addressed to `citadel`.
@@ -0,0 +1,19 @@
1
+ {
2
+ "schema_version": "1.0",
3
+ "description": "First Officer toolset — orchestration only",
4
+ "tools": [
5
+ { "name": "read_bead", "enabled": true },
6
+ { "name": "scan_beads", "enabled": true },
7
+ { "name": "write_mail", "enabled": true },
8
+ {
9
+ "name": "citadel_cli",
10
+ "enabled": true,
11
+ "allowed_commands": ["status", "dispatch", "note", "retry", "resolve", "trace", "worktree"]
12
+ },
13
+ { "name": "bash", "enabled": false },
14
+ { "name": "write_file", "enabled": false },
15
+ { "name": "git", "enabled": false },
16
+ { "name": "github_pr", "enabled": false },
17
+ { "name": "web_search", "enabled": false }
18
+ ]
19
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "schema_version": "1.0",
3
+ "archetypes": [
4
+ { "key": "software-engineer", "description": "Features, bugs, tests, PRs.", "status": "active" },
5
+ { "key": "qa-engineer", "description": "Integration/E2E tests, regressions.", "status": "planned" },
6
+ { "key": "architect", "description": "ADRs, design review, scalability.", "status": "planned" }
7
+ ]
8
+ }
@@ -0,0 +1,25 @@
1
+ # CITADEL Citizen — Base Preamble
2
+
3
+ You are a CITADEL Citizen — an autonomous LLM agent operating within the CITADEL orchestration system.
4
+
5
+ ## Environment
6
+
7
+ - `CITADEL_OUTPOST` — the Outpost you are assigned to
8
+ - `CITADEL_ARCHETYPE` — your role archetype
9
+ - `CITADEL_CITIZEN_ID` — your unique identity for this task
10
+ - `CITADEL_TASK_ID` — the task you are executing
11
+ - `CITADEL_WORKTREE` — your isolated workspace (git worktree)
12
+ - `CITADEL_BEADS_ROOT` — path to shared .beads/ directory for all Bead I/O
13
+
14
+ ## Bead I/O Rules
15
+
16
+ - ALL Bead reads and writes go through `CITADEL_BEADS_ROOT` — never worktree-local paths.
17
+ - Mail: `$CITADEL_BEADS_ROOT/mail/`
18
+ - Tribute: `$CITADEL_BEADS_ROOT/tribute/`
19
+ - Artifact paths in Tribute must be relative to the Outpost root, not the worktree.
20
+
21
+ ## Communication
22
+
23
+ - You write upward Mail (to: citadel) for reports, relay requests, and status.
24
+ - You never address other Outposts directly — use RELAY_REQUEST via the First Officer.
25
+ - You never write downward Mail.
@@ -0,0 +1,10 @@
1
+ {
2
+ "schema_version": "1.0",
3
+ "description": "Base toolset shared across all Archetypes",
4
+ "tools": [
5
+ { "name": "read_bead", "enabled": true },
6
+ { "name": "scan_beads", "enabled": true },
7
+ { "name": "write_mail", "enabled": true },
8
+ { "name": "write_tribute", "enabled": true }
9
+ ]
10
+ }
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@citadel-labs/citadel",
3
+ "version": "0.1.0",
4
+ "description": "Multi-agent orchestration system — cold-start, hub-and-spoke coordination for autonomous LLM Citizens",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "citadel": "dist/cli/index.js"
10
+ },
11
+ "engines": {
12
+ "node": ">=20.0.0"
13
+ },
14
+ "os": [
15
+ "darwin",
16
+ "linux",
17
+ "win32"
18
+ ],
19
+ "files": [
20
+ "dist",
21
+ "grand-archives",
22
+ "docs"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "dev": "tsc --watch",
27
+ "lint": "eslint src/",
28
+ "test": "vitest run",
29
+ "test:watch": "vitest",
30
+ "test:coverage": "vitest run --coverage",
31
+ "test:e2e": "npm run build && vitest run src/__tests__/cli-e2e/",
32
+ "prepublishOnly": "npm run build",
33
+ "version:patch": "npm version patch -m 'chore(release): v%s'",
34
+ "version:minor": "npm version minor -m 'chore(release): v%s'",
35
+ "version:major": "npm version major -m 'chore(release): v%s'",
36
+ "changelog": "git log --pretty=format:'* %s (%h)' $(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~20)..HEAD",
37
+ "release:patch": "npm run lint && npm test && npm run version:patch && git push && git push --tags",
38
+ "release:minor": "npm run lint && npm test && npm run version:minor && git push && git push --tags",
39
+ "prepare": "husky"
40
+ },
41
+ "keywords": [
42
+ "citadel",
43
+ "agent",
44
+ "orchestration",
45
+ "llm",
46
+ "multi-agent"
47
+ ],
48
+ "license": "MIT",
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "https://github.com/citadel-labs/citadel.git"
52
+ },
53
+ "publishConfig": {
54
+ "access": "public"
55
+ },
56
+ "dependencies": {
57
+ "chokidar": "^5.0.0",
58
+ "commander": "^14.0.3",
59
+ "nanoid": "^5.1.6",
60
+ "proper-lockfile": "^4.1.2",
61
+ "yaml": "^2.8.2"
62
+ },
63
+ "devDependencies": {
64
+ "@types/node": "^25.3.5",
65
+ "@types/proper-lockfile": "^4.1.4",
66
+ "@vitest/coverage-v8": "^4.0.18",
67
+ "eslint": "^10.0.2",
68
+ "husky": "^9.1.7",
69
+ "typescript": "^5.9.3",
70
+ "typescript-eslint": "^8.56.1",
71
+ "vitest": "^4.0.18"
72
+ }
73
+ }