@magnusekdahl/parallix 1.3.4 → 1.5.126

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 (227) hide show
  1. package/NOTICES +1423 -0
  2. package/README.md +76 -103
  3. package/build/asset-manifest.json +129 -0
  4. package/{config → build/config}/agents.json +4 -8
  5. package/build/manifest.sha256 +40 -0
  6. package/build/migrations/0001-initial-schema.sql +91 -0
  7. package/build/migrations/0002-import-history.sql +16 -0
  8. package/build/migrations/0003-board-lane-events.sql +72 -0
  9. package/build/migrations/0004-mission-aggregate.sql +151 -0
  10. package/build/migrations/0005-mission-external-task-ref.sql +18 -0
  11. package/build/migrations/0005-repository-scoped-session-markers.sql +47 -0
  12. package/build/migrations/0006-session-markers.sql +35 -0
  13. package/build/migrations/0007-usage-statistics-identity.sql +60 -0
  14. package/build/migrations/0008-review-workflow-state.sql +61 -0
  15. package/build/migrations/0009-review-gate-retries.sql +16 -0
  16. package/build/migrations/0010-review-events-and-implementer-response.sql +64 -0
  17. package/build/migrations/0011-board-lane-events-repository-id.sql +89 -0
  18. package/build/migrations/0012-review-hook-retries.sql +11 -0
  19. package/build/migrations/0013-usage-statistics-thoughts-tokens.sql +11 -0
  20. package/build/migrations/0014-remove-usage-closed.sql +33 -0
  21. package/build/migrations/0015-current-work-latest-per-mission.sql +5 -0
  22. package/build/migrations/0016-review-drop-retry-counters.sql +21 -0
  23. package/build/migrations/0017-retire-mission-import-provenance.sql +5 -0
  24. package/build/migrations/0018-adhoc-mission-counter.sql +19 -0
  25. package/build/migrations/0019-custom-agent-leases.sql +12 -0
  26. package/build/package.json +5 -0
  27. package/{prompts/act-on-review.md → build/prompts/act-on-review-core.md} +6 -4
  28. package/build/prompts/act-on-review.md +1 -0
  29. package/{prompts/draft.md → build/prompts/draft-core.md} +8 -1
  30. package/build/prompts/execute-core.md +37 -0
  31. package/build/prompts/execute.md +0 -0
  32. package/build/prompts/review-core.md +71 -0
  33. package/build/prompts/review.md +0 -0
  34. package/build/px.mjs +1226 -0
  35. package/build/px.mjs.map +7 -0
  36. package/build/sbom.json +2155 -0
  37. package/build/templates/mission-scaffold.md +61 -0
  38. package/build/web/assets/index-B8Hv3ORh.js +9 -0
  39. package/build/web/assets/index-DYY4ROtr.css +1 -0
  40. package/build/web/index.html +13 -0
  41. package/build/web/manifest.json +20 -0
  42. package/package.json +56 -30
  43. package/CHANGELOG.md +0 -140
  44. package/config/agents.local.json.template +0 -8
  45. package/config/integration-pipelines.json +0 -14
  46. package/config/state-map.json.template +0 -31
  47. package/config/workflow.config.schema.json +0 -110
  48. package/docs/adr/0031-ai-agent-instruction-boundary-and-command-floor.md +0 -114
  49. package/docs/adr/0032-mission-refinement-state-and-usage-budget-signals.md +0 -137
  50. package/docs/adr/0034-module-and-skill-invocation-model.md +0 -202
  51. package/docs/adr/0036-mission-sizing-and-dependency-wave-heuristics.md +0 -81
  52. package/docs/adr/0037-ai-workflow-coordination-architecture.md +0 -162
  53. package/docs/adr/0041-integration-pipeline-gates.md +0 -165
  54. package/docs/adr/0042-workflow-cli-color-rendering-approach.md +0 -106
  55. package/docs/adr/0043-git-target-resolution-strategy.md +0 -185
  56. package/docs/adr/0044-workflow-distribution-model.md +0 -277
  57. package/docs/adr/0045-parallax-branch-model.md +0 -182
  58. package/docs/adr/0046-npm-publish-process-and-security.md +0 -138
  59. package/docs/adr/0047-per-mission-change-size-budget.md +0 -161
  60. package/docs/adr/0048-fail-closed-harness-defense-against-agent-hallucinations.md +0 -161
  61. package/docs/adr/index.md +0 -23
  62. package/docs/agents.md +0 -212
  63. package/docs/authority-reference.md +0 -328
  64. package/docs/doc-standards.md +0 -89
  65. package/docs/forgejo-setup.md +0 -55
  66. package/docs/migration/extraction.md +0 -61
  67. package/docs/migration/task-classification.md +0 -36
  68. package/docs/operator-setup.md +0 -76
  69. package/docs/readme-rewrite-benchmark.md +0 -188
  70. package/docs/use-cases.md +0 -149
  71. package/examples/README.md +0 -62
  72. package/examples/run-enterprise-tarball-workflow-smoke.sh +0 -257
  73. package/examples/run-verify-env-smoke.sh +0 -40
  74. package/index.js +0 -262
  75. package/lib/README.md +0 -13
  76. package/lib/agents/agents.js +0 -880
  77. package/lib/agents/agents.ts +0 -978
  78. package/lib/agents/claude-telemetry.js +0 -232
  79. package/lib/agents/claude-telemetry.ts +0 -233
  80. package/lib/agents/claude.js +0 -152
  81. package/lib/agents/claude.ts +0 -158
  82. package/lib/agents/codex-telemetry.js +0 -227
  83. package/lib/agents/codex-telemetry.ts +0 -205
  84. package/lib/agents/codex.js +0 -213
  85. package/lib/agents/codex.ts +0 -238
  86. package/lib/agents/limit-hit.js +0 -259
  87. package/lib/agents/limit-hit.ts +0 -262
  88. package/lib/agents/mistral-telemetry.js +0 -140
  89. package/lib/agents/mistral-telemetry.ts +0 -159
  90. package/lib/agents/mistral.js +0 -174
  91. package/lib/agents/mistral.ts +0 -224
  92. package/lib/agents/opencode-export.js +0 -158
  93. package/lib/agents/opencode-export.ts +0 -160
  94. package/lib/agents/opencode-telemetry.js +0 -372
  95. package/lib/agents/opencode-telemetry.ts +0 -350
  96. package/lib/agents/opencode.js +0 -355
  97. package/lib/agents/opencode.ts +0 -372
  98. package/lib/agents/stage-telemetry.js +0 -41
  99. package/lib/agents/stage-telemetry.ts +0 -47
  100. package/lib/commands/active.js +0 -642
  101. package/lib/commands/active.ts +0 -707
  102. package/lib/commands/checkpoint.js +0 -102
  103. package/lib/commands/checkpoint.ts +0 -79
  104. package/lib/commands/config.js +0 -76
  105. package/lib/commands/config.ts +0 -52
  106. package/lib/commands/coverage-gate.js +0 -408
  107. package/lib/commands/coverage-gate.ts +0 -367
  108. package/lib/commands/diff.js +0 -151
  109. package/lib/commands/diff.ts +0 -130
  110. package/lib/commands/draft.js +0 -920
  111. package/lib/commands/draft.ts +0 -1026
  112. package/lib/commands/handoff.js +0 -685
  113. package/lib/commands/handoff.ts +0 -705
  114. package/lib/commands/integrate.js +0 -1612
  115. package/lib/commands/integrate.ts +0 -1724
  116. package/lib/commands/mission-start.js +0 -313
  117. package/lib/commands/mission-start.ts +0 -268
  118. package/lib/commands/rebase.js +0 -667
  119. package/lib/commands/rebase.ts +0 -639
  120. package/lib/commands/repair-handoff.js +0 -363
  121. package/lib/commands/repair-handoff.ts +0 -373
  122. package/lib/commands/resolve-conflict.js +0 -137
  123. package/lib/commands/resolve-conflict.ts +0 -117
  124. package/lib/commands/review.js +0 -18
  125. package/lib/commands/review.ts +0 -19
  126. package/lib/commands/setup-review.js +0 -18
  127. package/lib/commands/setup-review.ts +0 -19
  128. package/lib/commands/setup.js +0 -9
  129. package/lib/commands/setup.ts +0 -7
  130. package/lib/commands/stats-backfill.js +0 -448
  131. package/lib/commands/stats-backfill.ts +0 -423
  132. package/lib/commands/stats.js +0 -2016
  133. package/lib/commands/stats.ts +0 -2135
  134. package/lib/commands/status.js +0 -246
  135. package/lib/commands/status.ts +0 -224
  136. package/lib/commands/verify.js +0 -12
  137. package/lib/commands/verify.ts +0 -7
  138. package/lib/core/fmt.js +0 -178
  139. package/lib/core/fmt.ts +0 -189
  140. package/lib/core/git.js +0 -140
  141. package/lib/core/git.ts +0 -146
  142. package/lib/core/gitignore.js +0 -73
  143. package/lib/core/gitignore.ts +0 -108
  144. package/lib/core/mission-utils.js +0 -1058
  145. package/lib/core/mission-utils.ts +0 -998
  146. package/lib/core/nels.js +0 -184
  147. package/lib/core/nels.ts +0 -189
  148. package/lib/core/persistent-data-migration.js +0 -285
  149. package/lib/core/persistent-data-migration.ts +0 -257
  150. package/lib/core/product-config.js +0 -460
  151. package/lib/core/product-config.ts +0 -518
  152. package/lib/core/runtime-matrix.js +0 -49
  153. package/lib/core/runtime-matrix.ts +0 -84
  154. package/lib/core/spawn-tee.js +0 -160
  155. package/lib/core/spawn-tee.ts +0 -202
  156. package/lib/core/state-map.js +0 -108
  157. package/lib/core/state-map.ts +0 -115
  158. package/lib/core/storage.js +0 -151
  159. package/lib/core/storage.ts +0 -182
  160. package/lib/core/subagent-limit.js +0 -27
  161. package/lib/core/subagent-limit.ts +0 -25
  162. package/lib/core/verification.js +0 -176
  163. package/lib/core/verification.ts +0 -200
  164. package/lib/index.js +0 -160
  165. package/lib/index.ts +0 -134
  166. package/lib/review/rebase.js +0 -168
  167. package/lib/review/rebase.ts +0 -188
  168. package/lib/review/review-adapter.js +0 -234
  169. package/lib/review/review-adapter.ts +0 -198
  170. package/lib/review/review-artifacts.js +0 -542
  171. package/lib/review/review-artifacts.ts +0 -622
  172. package/lib/review/review-commands.js +0 -1318
  173. package/lib/review/review-commands.ts +0 -1579
  174. package/lib/review/review-events.js +0 -716
  175. package/lib/review/review-events.ts +0 -954
  176. package/lib/review/review-loop.js +0 -1271
  177. package/lib/review/review-loop.ts +0 -1493
  178. package/lib/review/review-polling.js +0 -132
  179. package/lib/review/review-polling.ts +0 -194
  180. package/lib/review/review-prompts.js +0 -212
  181. package/lib/review/review-prompts.ts +0 -186
  182. package/lib/review/review-state.js +0 -325
  183. package/lib/review/review-state.ts +0 -353
  184. package/lib/review/review.js +0 -126
  185. package/lib/review/review.ts +0 -143
  186. package/lib/tools/backlog.js +0 -848
  187. package/lib/tools/backlog.ts +0 -835
  188. package/lib/tools/forgejo.js +0 -1659
  189. package/lib/tools/forgejo.ts +0 -1793
  190. package/lib/tools/gatekeeper.js +0 -134
  191. package/lib/tools/gatekeeper.ts +0 -124
  192. package/lib/tools/redgreen.js +0 -239
  193. package/lib/tools/redgreen.ts +0 -221
  194. package/lib/tools/sessions.js +0 -87
  195. package/lib/tools/sessions.ts +0 -81
  196. package/lib/tools/setup-review.js +0 -1083
  197. package/lib/tools/setup-review.ts +0 -1152
  198. package/prompts/act-on-review-verbose.md +0 -20
  199. package/prompts/execute.md +0 -24
  200. package/prompts/portfolio.md +0 -30
  201. package/prompts/review-verbose.md +0 -36
  202. package/prompts/review.md +0 -50
  203. package/px.js +0 -268
  204. package/templates/AGENTS-snippet.md +0 -14
  205. package/templates/AGENTS.md.template +0 -34
  206. package/templates/CLAUDE.md.template +0 -27
  207. package/templates/CODEX.md.template +0 -38
  208. package/templates/MISTRAL.md.template +0 -24
  209. package/templates/claude-commands/act-on-review.md +0 -3
  210. package/templates/claude-commands/area-review.md +0 -3
  211. package/templates/claude-commands/draft.md +0 -6
  212. package/templates/claude-commands/execute.md +0 -6
  213. package/templates/claude-commands/integrate.md +0 -4
  214. package/templates/claude-commands/portfolio.md +0 -5
  215. package/templates/claude-commands/review.md +0 -4
  216. package/templates/codex/config.toml +0 -6
  217. package/templates/mission-scaffold.md +0 -39
  218. package/templates/vibe/skills/act-on-review/SKILL.md +0 -16
  219. package/templates/vibe/skills/area-review/SKILL.md +0 -16
  220. package/templates/vibe/skills/draft/SKILL.md +0 -16
  221. package/templates/vibe/skills/execute/SKILL.md +0 -16
  222. package/templates/vibe/skills/integrate/SKILL.md +0 -16
  223. package/templates/vibe/skills/portfolio/SKILL.md +0 -21
  224. package/templates/vibe/skills/review/SKILL.md +0 -16
  225. package/tools/setup-forgejo-docker.sh +0 -87
  226. /package/{config → build/config}/state-map.json +0 -0
  227. /package/{data/.gitkeep → build/prompts/draft.md} +0 -0
@@ -0,0 +1,72 @@
1
+ -- Migration: 0003-board-lane-events
2
+ -- Description: Dedicated relational table for board lane-transition events.
3
+ -- Replaces the JSON-blob pattern (operational_history + event_type filter)
4
+ -- with a typed table following the usage_statistics analytical pattern.
5
+ --
6
+ -- Authority: operator-local telemetry only (ADR 0051). Lane-transition events
7
+ -- are the source of truth for the event log itself, never a competing mission
8
+ -- lifecycle authority — repository Git/Markdown state still wins.
9
+ --
10
+ -- Domain alignment:
11
+ -- - mission_id maps to MissionId (src/domain/mission.ts)
12
+ -- - from_status / to_status map to MissionStatus enum values
13
+ -- - trigger maps to MissionCommand['type'] (src/domain/mission-workflow.ts)
14
+ -- - agent maps to AgentFamily (src/domain/agents.ts)
15
+ -- - occurred_at is the authoritative transition timestamp
16
+ -- The row maps 1:1 to LaneTransitionEvent (src/domain/board-event.ts) and
17
+ -- converts losslessly to MissionTransition via the domain mapping function.
18
+ --
19
+ -- Relationship to usage_statistics:
20
+ -- board_lane_events records every lifecycle transition (the "when" and
21
+ -- "how" of mission movement). usage_statistics records outcome measurements
22
+ -- for completed missions (cycle time, tokens, cost, review rounds).
23
+ -- Together they feed buildMetrics():
24
+ -- - board_lane_events → MissionTransition[] → cumulativeFlow, wipSeries
25
+ -- - usage_statistics → MissionOutcome[] → throughput, reviewLoopRate
26
+ -- Both tables share mission_id as the join key and use the same
27
+ -- operator-local authority model.
28
+ --
29
+ -- Forward-only: this migration has no `down` SQL. The TASK-2295 migration runner
30
+ -- takes a pre-migration backup before applying an irreversible migration.
31
+
32
+ CREATE TABLE IF NOT EXISTS board_lane_events (
33
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
34
+
35
+ -- Domain identity: which mission transitioned
36
+ mission_id TEXT NOT NULL,
37
+
38
+ -- Lifecycle states (MissionStatus vocabulary:
39
+ -- backlog, refined, active, review, integration, done)
40
+ from_status TEXT,
41
+ to_status TEXT NOT NULL,
42
+
43
+ -- Which MissionCommand caused the transition
44
+ -- (activate, submit-for-review, request-changes, approve, integrate)
45
+ trigger TEXT NOT NULL,
46
+
47
+ -- Agent family that performed the transition
48
+ agent TEXT NOT NULL DEFAULT 'unknown',
49
+
50
+ -- ISO-8601 timestamp of the authoritative transition
51
+ occurred_at TEXT NOT NULL,
52
+
53
+ -- Idempotency key: application-generated, unique per emission attempt.
54
+ -- Prevents duplicate rows if the same transition is recorded twice.
55
+ idempotency_key TEXT NOT NULL
56
+ );
57
+
58
+ -- Idempotency backstop: a duplicate emission of the same idempotency key
59
+ -- cannot produce a second row. The application recorder also dedups by
60
+ -- idempotency key before writing; this UNIQUE index makes the guarantee
61
+ -- durable at the storage layer.
62
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_board_lane_events_idempotency
63
+ ON board_lane_events (idempotency_key);
64
+
65
+ -- Query-support index for reading lane transitions by mission id
66
+ -- (used by buildMetrics → cumulativeFlow, wipSeries).
67
+ CREATE INDEX IF NOT EXISTS idx_board_lane_events_mission
68
+ ON board_lane_events (mission_id, occurred_at);
69
+
70
+ -- Query-support index for throughput / flow analytics by time window.
71
+ CREATE INDEX IF NOT EXISTS idx_board_lane_events_time
72
+ ON board_lane_events (occurred_at);
@@ -0,0 +1,151 @@
1
+ -- Migration: 0004-mission-aggregate
2
+ -- Persist the checked Mission aggregate as relational domain data. Child
3
+ -- tables are aggregate-owned value collections, not independently writable
4
+ -- entities. Repository observations remain in known_repositories; missions
5
+ -- retain only the stable RepositoryId reference.
6
+
7
+ ALTER TABLE known_repositories ADD COLUMN display_name TEXT;
8
+
9
+ CREATE TABLE missions (
10
+ id TEXT PRIMARY KEY NOT NULL,
11
+ repository_id TEXT NOT NULL,
12
+ title TEXT NOT NULL,
13
+ status TEXT NOT NULL CHECK (
14
+ status IN ('backlog', 'refined', 'active', 'review', 'integration', 'done')
15
+ ),
16
+ raw_status TEXT,
17
+ assignee TEXT,
18
+ net_engineering_lines INTEGER CHECK (
19
+ net_engineering_lines IS NULL OR net_engineering_lines >= 0
20
+ ),
21
+ closed_at TEXT,
22
+ version INTEGER NOT NULL DEFAULT 1 CHECK (version >= 1),
23
+ CHECK (
24
+ closed_at IS NULL OR status = 'done'
25
+ )
26
+ );
27
+
28
+ CREATE INDEX idx_missions_repository ON missions (repository_id);
29
+ CREATE INDEX idx_missions_status ON missions (status);
30
+
31
+ CREATE TABLE mission_labels (
32
+ mission_id TEXT NOT NULL REFERENCES missions(id) ON DELETE CASCADE,
33
+ position INTEGER NOT NULL CHECK (position >= 0),
34
+ label TEXT NOT NULL CHECK (length(label) > 0),
35
+ PRIMARY KEY (mission_id, position),
36
+ UNIQUE (mission_id, label)
37
+ );
38
+
39
+ CREATE TABLE mission_checkpoints (
40
+ mission_id TEXT NOT NULL REFERENCES missions(id) ON DELETE CASCADE,
41
+ position INTEGER NOT NULL CHECK (position >= 0),
42
+ checkpoint_mission_id TEXT NOT NULL,
43
+ name TEXT NOT NULL,
44
+ raw_filename TEXT,
45
+ first_line TEXT,
46
+ next_action_text TEXT NOT NULL,
47
+ PRIMARY KEY (mission_id, position)
48
+ );
49
+
50
+ CREATE TABLE mission_checkpoint_goal_checks (
51
+ mission_id TEXT NOT NULL,
52
+ checkpoint_position INTEGER NOT NULL,
53
+ position INTEGER NOT NULL CHECK (position >= 0),
54
+ criterion TEXT NOT NULL,
55
+ evidence TEXT NOT NULL,
56
+ PRIMARY KEY (mission_id, checkpoint_position, position),
57
+ FOREIGN KEY (mission_id, checkpoint_position)
58
+ REFERENCES mission_checkpoints(mission_id, position) ON DELETE CASCADE
59
+ );
60
+
61
+ CREATE TABLE mission_reviews (
62
+ mission_id TEXT PRIMARY KEY REFERENCES missions(id) ON DELETE CASCADE,
63
+ intervention_requested_at TEXT,
64
+ intervention_requested_by TEXT CHECK (
65
+ intervention_requested_by IS NULL
66
+ OR intervention_requested_by IN ('reviewer', 'implementer', 'workflow')
67
+ ),
68
+ intervention_reason TEXT,
69
+ CHECK (
70
+ (intervention_requested_at IS NULL
71
+ AND intervention_requested_by IS NULL
72
+ AND intervention_reason IS NULL)
73
+ OR
74
+ (intervention_requested_at IS NOT NULL
75
+ AND intervention_requested_by IS NOT NULL
76
+ AND intervention_reason IS NOT NULL)
77
+ )
78
+ );
79
+
80
+ CREATE TABLE mission_review_rounds (
81
+ mission_id TEXT NOT NULL REFERENCES mission_reviews(mission_id) ON DELETE CASCADE,
82
+ position INTEGER NOT NULL CHECK (position >= 0),
83
+ round_number INTEGER NOT NULL CHECK (round_number >= 1),
84
+ change_kind TEXT NOT NULL CHECK (change_kind IN ('pull-request', 'local-branch')),
85
+ provider TEXT,
86
+ provider_change_id TEXT,
87
+ provider_url TEXT,
88
+ source_branch TEXT NOT NULL,
89
+ target_branch TEXT NOT NULL,
90
+ revision TEXT NOT NULL,
91
+ reviewer TEXT NOT NULL,
92
+ implementer TEXT NOT NULL,
93
+ started_at TEXT NOT NULL,
94
+ decision_kind TEXT CHECK (decision_kind IS NULL OR decision_kind IN ('approved', 'changes-requested')),
95
+ decided_at TEXT,
96
+ decision_comment TEXT,
97
+ approval_source_kind TEXT CHECK (
98
+ approval_source_kind IS NULL OR approval_source_kind IN ('provider', 'local')
99
+ ),
100
+ approval_source_provider TEXT,
101
+ responded_at TEXT,
102
+ resulting_revision TEXT,
103
+ PRIMARY KEY (mission_id, position),
104
+ UNIQUE (mission_id, round_number),
105
+ CHECK (
106
+ (change_kind = 'pull-request' AND provider IS NOT NULL AND provider_change_id IS NOT NULL)
107
+ OR
108
+ (change_kind = 'local-branch' AND provider IS NULL
109
+ AND provider_change_id IS NULL AND provider_url IS NULL)
110
+ ),
111
+ CHECK (
112
+ (decision_kind IS NULL AND decided_at IS NULL AND approval_source_kind IS NULL)
113
+ OR
114
+ (decision_kind = 'approved' AND decided_at IS NOT NULL AND approval_source_kind IS NOT NULL)
115
+ OR
116
+ (decision_kind = 'changes-requested' AND decided_at IS NOT NULL
117
+ AND approval_source_kind IS NULL AND approval_source_provider IS NULL)
118
+ ),
119
+ CHECK (
120
+ (responded_at IS NULL AND resulting_revision IS NULL)
121
+ OR (responded_at IS NOT NULL AND resulting_revision IS NOT NULL)
122
+ )
123
+ );
124
+
125
+ CREATE TABLE mission_review_findings (
126
+ mission_id TEXT NOT NULL,
127
+ round_position INTEGER NOT NULL,
128
+ position INTEGER NOT NULL CHECK (position >= 0),
129
+ finding_id TEXT NOT NULL,
130
+ summary TEXT NOT NULL,
131
+ location TEXT,
132
+ PRIMARY KEY (mission_id, round_position, position),
133
+ UNIQUE (mission_id, round_position, finding_id),
134
+ FOREIGN KEY (mission_id, round_position)
135
+ REFERENCES mission_review_rounds(mission_id, position) ON DELETE CASCADE
136
+ );
137
+
138
+ CREATE TABLE mission_review_resolutions (
139
+ mission_id TEXT NOT NULL,
140
+ round_position INTEGER NOT NULL,
141
+ position INTEGER NOT NULL CHECK (position >= 0),
142
+ finding_id TEXT NOT NULL,
143
+ kind TEXT NOT NULL CHECK (kind IN ('fixed', 'disputed')),
144
+ explanation TEXT NOT NULL,
145
+ PRIMARY KEY (mission_id, round_position, position),
146
+ UNIQUE (mission_id, round_position, finding_id),
147
+ FOREIGN KEY (mission_id, round_position)
148
+ REFERENCES mission_review_rounds(mission_id, position) ON DELETE CASCADE,
149
+ FOREIGN KEY (mission_id, round_position, finding_id)
150
+ REFERENCES mission_review_findings(mission_id, round_position, finding_id)
151
+ );
@@ -0,0 +1,18 @@
1
+ -- Migration: 0005-mission-external-task-ref
2
+ -- Intake traceability for accepted external material (ADR 0053: external task
3
+ -- catalogs are excluded as aggregates; only the reference is stored).
4
+ --
5
+ -- Modelled as an aggregate-owned value collection with at most one row per
6
+ -- mission, exactly like the other nested Mission values. It deliberately has no
7
+ -- status, assignee, or lifecycle column: a second lifecycle authority must not
8
+ -- be reachable by adding columns to this table.
9
+
10
+ CREATE TABLE mission_external_task_refs (
11
+ mission_id TEXT PRIMARY KEY REFERENCES missions(id) ON DELETE CASCADE,
12
+ source TEXT NOT NULL CHECK (length(source) > 0 AND length(source) <= 512),
13
+ external_id TEXT NOT NULL CHECK (length(external_id) > 0 AND length(external_id) <= 512),
14
+ url TEXT CHECK (url IS NULL OR (length(url) > 0 AND length(url) <= 512))
15
+ );
16
+
17
+ CREATE INDEX idx_mission_external_task_refs_source
18
+ ON mission_external_task_refs (source, external_id);
@@ -0,0 +1,47 @@
1
+ -- Migration: 0005-repository-scoped-session-markers
2
+ -- Description: Scope SessionMarker identity to its owning repository and make
3
+ -- the table strict so SQLite enforces the declared storage classes.
4
+ --
5
+ -- Migration 0004 may already be present in an operator database. Its rows do
6
+ -- not contain enough information to infer their repository safely, so they are
7
+ -- preserved under an explicit legacy scope. An explicit legacy import can
8
+ -- associate source worktree markers with a checked RepositoryId.
9
+
10
+ DROP INDEX IF EXISTS idx_session_markers_mission;
11
+
12
+ ALTER TABLE session_markers RENAME TO session_markers_unscoped;
13
+
14
+ CREATE TABLE session_markers (
15
+ repository_id TEXT NOT NULL CHECK(length(trim(repository_id)) > 0),
16
+ mission_id TEXT NOT NULL,
17
+ role TEXT NOT NULL CHECK(role IN ('execute', 'draft', 'review')),
18
+ agent TEXT NOT NULL,
19
+ last_launched TEXT NOT NULL,
20
+ session_id TEXT,
21
+ updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
22
+ UNIQUE(repository_id, mission_id, role)
23
+ ) STRICT;
24
+
25
+ INSERT INTO session_markers (
26
+ repository_id,
27
+ mission_id,
28
+ role,
29
+ agent,
30
+ last_launched,
31
+ session_id,
32
+ updated_at
33
+ )
34
+ SELECT
35
+ 'legacy-unscoped',
36
+ mission_id,
37
+ role,
38
+ agent,
39
+ last_launched,
40
+ session_id,
41
+ updated_at
42
+ FROM session_markers_unscoped;
43
+
44
+ DROP TABLE session_markers_unscoped;
45
+
46
+ CREATE INDEX idx_session_markers_repository_mission
47
+ ON session_markers (repository_id, mission_id);
@@ -0,0 +1,35 @@
1
+ -- Migration: 0006-session-markers
2
+ -- Description: Dedicated relational table for SessionMarker domain concept.
3
+ -- Replaces the file-backed `.workflow/sessions/<slug>-<role>.json` path as
4
+ -- the sole live authority for resumable agent-session markers (TASK-2322.09).
5
+ --
6
+ -- Authority: operator-local domain state (ADR 0053 classification:
7
+ -- `database-owned-domain-state`). Session identity must survive worktree
8
+ -- cleanup and must not be confused with an inferred Attempt aggregate.
9
+ --
10
+ -- Domain alignment:
11
+ -- - mission_id maps to MissionId (src/domain/mission.ts)
12
+ -- - role maps to SessionRole enum ('execute' | 'draft' | 'review')
13
+ -- - agent maps to AgentFamily (src/domain/agents.ts)
14
+ -- - last_launched is the ISO-8601 timestamp of the last agent launch
15
+ -- - session_id is the optional provider session identifier
16
+ -- - updated_at is the authoritative modification timestamp
17
+ -- The row maps 1:1 to SessionMarker (src/domain/session.ts).
18
+ --
19
+ -- Forward-only: this migration has no `down` SQL. The TASK-2295 migration runner
20
+ -- takes a pre-migration backup before applying an irreversible migration.
21
+
22
+ CREATE TABLE IF NOT EXISTS session_markers (
23
+ mission_id TEXT NOT NULL,
24
+ role TEXT NOT NULL CHECK(role IN ('execute', 'draft', 'review')),
25
+ agent TEXT NOT NULL,
26
+ last_launched TEXT NOT NULL,
27
+ session_id TEXT,
28
+ updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
29
+ UNIQUE(mission_id, role)
30
+ );
31
+
32
+ -- Query-support index for reading markers by mission (e.g. import dedup,
33
+ -- bulk clear by mission, or operator-local status queries).
34
+ CREATE INDEX IF NOT EXISTS idx_session_markers_mission
35
+ ON session_markers (mission_id);
@@ -0,0 +1,60 @@
1
+ -- 0007-usage-statistics-identity
2
+ --
3
+ -- TASK-2322.08: make `usage_statistics` the sole authority for
4
+ -- `AgentRunMeasurement` / `MissionOutcome` data (ADR 0053), replacing the
5
+ -- former `<PARALLIX_HOME>/stats.csv` file authority.
6
+ --
7
+ -- Identity: TASK-2322.02 excluded `Attempt`, so a measurement has NO per-run
8
+ -- identity. The valid identity is the grouping the domain already models —
9
+ -- (repo, mission, stage, actor) — where `actor_key` is the normalized agent
10
+ -- family the row is attributed to. `actor_key` is supplied by the caller that
11
+ -- owns the attribution rule; the adapter never infers it, and no per-launch
12
+ -- row is created.
13
+ --
14
+ -- Irreversible (no `down`): the unique index collapses pre-existing duplicate
15
+ -- rows that the file authority allowed. The migration runner takes a
16
+ -- pre-migration backup for irreversible migrations.
17
+
18
+ ALTER TABLE usage_statistics ADD COLUMN actor_key TEXT NOT NULL DEFAULT '';
19
+
20
+ -- Backfill `actor_key` with the same rule the statistics command applies:
21
+ -- review rows are attributed to the reviewer, every other stage to the
22
+ -- implementer; the value is trimmed, stripped of one leading '@', lowercased.
23
+ UPDATE usage_statistics
24
+ SET actor_key = lower(
25
+ CASE
26
+ WHEN substr(
27
+ CASE
28
+ WHEN lower(trim(COALESCE(NULLIF(trim(stage), ''), 'default'))) = 'review'
29
+ THEN COALESCE(NULLIF(trim(reviewer_agent), ''), NULLIF(trim(implementer_agent), ''), NULLIF(trim(implementer), ''), '')
30
+ ELSE COALESCE(NULLIF(trim(implementer_agent), ''), NULLIF(trim(implementer), ''), '')
31
+ END, 1, 1) = '@'
32
+ THEN substr(
33
+ CASE
34
+ WHEN lower(trim(COALESCE(NULLIF(trim(stage), ''), 'default'))) = 'review'
35
+ THEN COALESCE(NULLIF(trim(reviewer_agent), ''), NULLIF(trim(implementer_agent), ''), NULLIF(trim(implementer), ''), '')
36
+ ELSE COALESCE(NULLIF(trim(implementer_agent), ''), NULLIF(trim(implementer), ''), '')
37
+ END, 2)
38
+ ELSE
39
+ CASE
40
+ WHEN lower(trim(COALESCE(NULLIF(trim(stage), ''), 'default'))) = 'review'
41
+ THEN COALESCE(NULLIF(trim(reviewer_agent), ''), NULLIF(trim(implementer_agent), ''), NULLIF(trim(implementer), ''), '')
42
+ ELSE COALESCE(NULLIF(trim(implementer_agent), ''), NULLIF(trim(implementer), ''), '')
43
+ END
44
+ END
45
+ );
46
+
47
+ -- Normalize `stage` so the identity key cannot split on '' vs 'default'.
48
+ UPDATE usage_statistics
49
+ SET stage = lower(trim(COALESCE(NULLIF(trim(stage), ''), 'default')));
50
+
51
+ -- Collapse duplicates the file authority permitted, keeping the newest row
52
+ -- (highest rowid) for each identity.
53
+ DELETE FROM usage_statistics
54
+ WHERE id NOT IN (
55
+ SELECT MAX(id) FROM usage_statistics
56
+ GROUP BY repo, mission, stage, actor_key
57
+ );
58
+
59
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_usage_statistics_identity
60
+ ON usage_statistics(repo, mission, stage, actor_key);
@@ -0,0 +1,61 @@
1
+ -- TASK-2322.12: model review-loop workflow state on the Review aggregate.
2
+ --
3
+ -- Before this migration the workflow phase, per-round retry counters and the
4
+ -- stage-launch de-duplication windows lived only in review-state.json, which
5
+ -- made review-state.json the durable authority for a concept ADR 0053 assigns
6
+ -- to the operator database. These columns close that gap so the JSON path can
7
+ -- be retired.
8
+ --
9
+ -- Additive only: existing rows take the defaults, which reproduce the values a
10
+ -- pre-migration review would have had (a round with no recorded retries, in the
11
+ -- phase implied by its decision history).
12
+
13
+ ALTER TABLE mission_review_rounds
14
+ ADD COLUMN phase TEXT NOT NULL DEFAULT 'reviewing'
15
+ CHECK (phase IN ('reviewing', 'fixing', 'pending-approval', 'approved'));
16
+
17
+ ALTER TABLE mission_review_rounds
18
+ ADD COLUMN disposition TEXT
19
+ CHECK (
20
+ disposition IS NULL
21
+ OR disposition IN (
22
+ 'APPROVED', 'REQUEST_CHANGES', 'COMMENT',
23
+ 'PUSHBACK_ALL', 'BLOCKED', 'PARKED', 'CHANGES_MADE'
24
+ )
25
+ );
26
+
27
+ ALTER TABLE mission_review_rounds
28
+ ADD COLUMN reviewer_retry_count INTEGER NOT NULL DEFAULT 0
29
+ CHECK (reviewer_retry_count >= 0);
30
+
31
+ ALTER TABLE mission_review_rounds
32
+ ADD COLUMN implementer_retry_count INTEGER NOT NULL DEFAULT 0
33
+ CHECK (implementer_retry_count >= 0);
34
+
35
+ -- Backfill phase and disposition from the decision history already stored, so
36
+ -- an upgraded database presents the same loop state a fresh one would.
37
+ UPDATE mission_review_rounds
38
+ SET phase = 'approved', disposition = 'APPROVED'
39
+ WHERE decision_kind = 'approved';
40
+
41
+ UPDATE mission_review_rounds
42
+ SET phase = 'pending-approval', disposition = 'CHANGES_MADE'
43
+ WHERE decision_kind = 'changes-requested' AND responded_at IS NOT NULL;
44
+
45
+ UPDATE mission_review_rounds
46
+ SET phase = 'fixing', disposition = 'REQUEST_CHANGES'
47
+ WHERE decision_kind = 'changes-requested' AND responded_at IS NULL;
48
+
49
+ -- Stage-launch windows are cumulative across rounds, so they hang off the
50
+ -- review rather than a round. `position` preserves insertion order within a
51
+ -- window; the application caps retained fingerprints per window.
52
+ CREATE TABLE mission_review_stage_launches (
53
+ mission_id TEXT NOT NULL REFERENCES mission_reviews(mission_id) ON DELETE CASCADE,
54
+ stage_key TEXT NOT NULL,
55
+ position INTEGER NOT NULL CHECK (position >= 0),
56
+ fingerprint TEXT NOT NULL,
57
+ PRIMARY KEY (mission_id, stage_key, position)
58
+ );
59
+
60
+ CREATE INDEX idx_review_stage_launches_window
61
+ ON mission_review_stage_launches (mission_id, stage_key);
@@ -0,0 +1,16 @@
1
+ -- TASK-2322.12: carry the pre-review gate retry budget on the Review aggregate.
2
+ --
3
+ -- Migration 0008 modelled the workflow phase, the per-round retry counters and
4
+ -- the stage-launch windows. It did not cover `gateFailureRetryCount`, the
5
+ -- counter `handleGateFailureAutoBounce` uses to cap auto-bounces at
6
+ -- MAX_GATE_RETRY. That counter is the last review-loop value that would have
7
+ -- kept review-state.json alive as a durable authority, so it lands here rather
8
+ -- than by rewriting 0008, which is already applied.
9
+ --
10
+ -- Cumulative across rounds like the stage-launch windows: an auto-bounce hands
11
+ -- the mission back to the implementer without starting a new round, so a
12
+ -- per-round column would reset the budget on every bounce.
13
+
14
+ ALTER TABLE mission_reviews
15
+ ADD COLUMN gate_failure_retry_count INTEGER NOT NULL DEFAULT 0
16
+ CHECK (gate_failure_retry_count >= 0);
@@ -0,0 +1,64 @@
1
+ -- TASK-2322.12: store review events and implementer response details in SQLite.
2
+ --
3
+ -- The review-events .md files (missions/<slug>/review-events/*.md) are workflow
4
+ -- audit records that supplement the Review aggregate. After this migration they
5
+ -- are stored in the operator database so the file-backed paths can be retired.
6
+ --
7
+ -- Two concerns land here:
8
+ --
9
+ -- 1. mission_review_events — full audit trail for all event types
10
+ -- (reviewer findings/outcomes, implementer summaries/dispositions,
11
+ -- human notes, blocked/parked publication records). This replaces the
12
+ -- .md files under missions/<slug>/review-events/.
13
+ --
14
+ -- 2. Implementer response columns on mission_review_rounds — the implementer's
15
+ -- round summary includes workflow metadata (fixed_items, pushed_back_items,
16
+ -- parked_items, blocked_reason) that is not captured by the structured
17
+ -- FindingResolution collection. These columns store that metadata directly
18
+ -- on the round so stats.ts and the review loop can access it without
19
+ -- scanning event files.
20
+ --
21
+ -- Additive only: existing rows take NULL defaults. The application backfills
22
+ -- from .md files on first read (compatibility path).
23
+
24
+ -- Full audit trail for review events (replaces missions/<slug>/review-events/*.md)
25
+ CREATE TABLE mission_review_events (
26
+ mission_id TEXT NOT NULL REFERENCES mission_reviews(mission_id) ON DELETE CASCADE,
27
+ position INTEGER NOT NULL CHECK (position >= 0),
28
+ event_type TEXT NOT NULL CHECK (
29
+ event_type IN (
30
+ 'reviewer_findings', 'reviewer_outcome',
31
+ 'implementer_round_summary', 'implementer_disposition',
32
+ 'neutral_discussion', 'human_note',
33
+ 'blocked_publication', 'parked_followup'
34
+ )
35
+ ),
36
+ round_number INTEGER CHECK (round_number IS NULL OR round_number >= 1),
37
+ phase TEXT,
38
+ actor TEXT,
39
+ content TEXT NOT NULL DEFAULT '',
40
+ disposition TEXT,
41
+ verdict TEXT,
42
+ /** JSON array of {kind: 'fixed'|'pushed_back'|'parked', findingId: string} */
43
+ item_dispositions TEXT,
44
+ blocked_reason TEXT,
45
+ followup_reference TEXT,
46
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%S', 'now')),
47
+ PRIMARY KEY (mission_id, position)
48
+ );
49
+
50
+ CREATE INDEX idx_review_events_mission_type
51
+ ON mission_review_events (mission_id, event_type);
52
+
53
+ CREATE INDEX idx_review_events_round
54
+ ON mission_review_events (mission_id, round_number);
55
+
56
+ -- Implementer response metadata on the round (supplements FindingResolution)
57
+ ALTER TABLE mission_review_rounds
58
+ ADD COLUMN implementer_response_content TEXT;
59
+
60
+ ALTER TABLE mission_review_rounds
61
+ ADD COLUMN item_dispositions TEXT;
62
+
63
+ ALTER TABLE mission_review_rounds
64
+ ADD COLUMN blocked_reason TEXT;
@@ -0,0 +1,89 @@
1
+ -- Migration: 0011-board-lane-events-repository-id
2
+ -- Description: Add repository_id to board_lane_events and scope the
3
+ -- idempotency UNIQUE index and mission lookup index by repository.
4
+ -- Existing rows are backfilled with the explicit 'legacy-unscoped'
5
+ -- sentinel following the precedent in 0005-repository-scoped-session-markers.
6
+ --
7
+ -- Authority: operator-local telemetry only (ADR 0051).
8
+ -- Domain alignment: repository_id maps to RepositoryId (src/domain/repository.ts).
9
+ --
10
+ -- Forward-only: uses rename-copy-drop pattern. The TASK-2295 migration runner
11
+ -- takes a pre-migration backup before applying an irreversible migration.
12
+
13
+ -- Drop indexes that will be recreated with repository_id prefix
14
+ DROP INDEX IF EXISTS idx_board_lane_events_idempotency;
15
+ DROP INDEX IF EXISTS idx_board_lane_events_mission;
16
+ DROP INDEX IF EXISTS idx_board_lane_events_time;
17
+
18
+ -- Rename existing table
19
+ ALTER TABLE board_lane_events RENAME TO board_lane_events_unscoped;
20
+
21
+ -- Create new table with repository_id and CHECK constraint
22
+ CREATE TABLE board_lane_events (
23
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
24
+
25
+ -- Stable repository identifier (scoped, non-empty)
26
+ repository_id TEXT NOT NULL CHECK(length(trim(repository_id)) > 0),
27
+
28
+ -- Domain identity: which mission transitioned
29
+ mission_id TEXT NOT NULL,
30
+
31
+ -- Lifecycle states (MissionStatus vocabulary:
32
+ -- backlog, refined, active, review, integration, done)
33
+ from_status TEXT,
34
+ to_status TEXT NOT NULL,
35
+
36
+ -- Which MissionCommand caused the transition
37
+ -- (activate, submit-for-review, request-changes, approve, integrate)
38
+ trigger TEXT NOT NULL,
39
+
40
+ -- Agent family that performed the transition
41
+ agent TEXT NOT NULL DEFAULT 'unknown',
42
+
43
+ -- ISO-8601 timestamp of the authoritative transition
44
+ occurred_at TEXT NOT NULL,
45
+
46
+ -- Idempotency key: application-generated, unique per emission attempt.
47
+ -- Scoped by repository_id so the same key can exist in different repos.
48
+ idempotency_key TEXT NOT NULL
49
+ );
50
+
51
+ -- Backfill: existing rows get explicit legacy sentinel
52
+ INSERT INTO board_lane_events (
53
+ id,
54
+ repository_id,
55
+ mission_id,
56
+ from_status,
57
+ to_status,
58
+ trigger,
59
+ agent,
60
+ occurred_at,
61
+ idempotency_key
62
+ )
63
+ SELECT
64
+ id,
65
+ 'legacy-unscoped',
66
+ mission_id,
67
+ from_status,
68
+ to_status,
69
+ trigger,
70
+ agent,
71
+ occurred_at,
72
+ idempotency_key
73
+ FROM board_lane_events_unscoped;
74
+
75
+ -- Drop the old table
76
+ DROP TABLE board_lane_events_unscoped;
77
+
78
+ -- Idempotency: scoped by (repository_id, idempotency_key) so the same key
79
+ -- can exist in different repositories without collision.
80
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_board_lane_events_repo_idempotency
81
+ ON board_lane_events (repository_id, idempotency_key);
82
+
83
+ -- Query-support index for reading lane transitions by repository + mission
84
+ CREATE INDEX IF NOT EXISTS idx_board_lane_events_repo_mission
85
+ ON board_lane_events (repository_id, mission_id, occurred_at);
86
+
87
+ -- Query-support index for throughput / flow analytics by time window
88
+ CREATE INDEX IF NOT EXISTS idx_board_lane_events_time
89
+ ON board_lane_events (occurred_at);
@@ -0,0 +1,11 @@
1
+ -- TASK-2340: carry the hook-failure retry budget on the Review aggregate.
2
+ --
3
+ -- Mirrors migration 0009 (gate_failure_retry_count). Hook auto-bounces happen
4
+ -- during rebase/integrate operations, not during the pre-review gate, so the
5
+ -- counter is separate. Cumulative across rounds like gate retries: a hook
6
+ -- bounce hands the mission back to the implementer without starting a new
7
+ -- round, so a per-round column would reset the budget on every bounce.
8
+
9
+ ALTER TABLE mission_reviews
10
+ ADD COLUMN hook_failure_retry_count INTEGER NOT NULL DEFAULT 0
11
+ CHECK (hook_failure_retry_count >= 0);
@@ -0,0 +1,11 @@
1
+ -- TASK-2362: record thinking/reasoning tokens as their own measurement column.
2
+ --
3
+ -- The qwen usage artifacts (`usage/token-usage-YYYY-MM.jsonl`) report
4
+ -- `thoughtsTokens` separately from input/output/cached. Folding them into
5
+ -- output_tokens would make the reasoning spend invisible, so they land in
6
+ -- their own column alongside the other token categories. Families that do not
7
+ -- report thinking tokens write 0, which is the same honest-zero the other
8
+ -- token columns already use.
9
+
10
+ ALTER TABLE usage_statistics
11
+ ADD COLUMN thoughts_tokens INTEGER;