opencode-swarm 7.164.11 → 7.164.12

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 (107) hide show
  1. package/.opencode/skills/engineering-conventions/SKILL.md +1 -1
  2. package/dist/background/pending-delegations.d.ts +7 -2
  3. package/dist/background/pr-subscriptions.d.ts +3 -3
  4. package/dist/cli/{coder-settlement-0rfk8y11.js → coder-settlement-yh1q5fr3.js} +15 -16
  5. package/dist/cli/{config-doctor-j17b7qq2.js → config-doctor-bd4yzmh7.js} +3 -3
  6. package/dist/cli/{core-evhjjrtt.js → core-y0s1vmyc.js} +2 -2
  7. package/dist/cli/{curation-policy-vj6z5hvr.js → curation-policy-gs1qakn7.js} +5 -6
  8. package/dist/cli/{curator-vqd5yeck.js → curator-brqack0j.js} +48 -46
  9. package/dist/cli/{curator-drift-ez81vg2t.js → curator-drift-1sg9yk2m.js} +14 -12
  10. package/dist/cli/curator-llm-factory-dtsjc3zf.js +70 -0
  11. package/dist/cli/{dispatch-dqybvj8v.js → dispatch-c7xjt7js.js} +3 -3
  12. package/dist/cli/{evidence-summary-service-937x7rbg.js → evidence-summary-service-nqbcvp30.js} +24 -23
  13. package/dist/cli/{gate-evidence-q1cehr4k.js → gate-evidence-9stdtpej.js} +9 -10
  14. package/dist/cli/guardrail-explain-3ff1z3fm.js +71 -0
  15. package/dist/cli/{guardrail-log-3g93f3g2.js → guardrail-log-sf39x00b.js} +10 -10
  16. package/dist/cli/{guardrail-reset-qe2r5qzq.js → guardrail-reset-9wr6a60s.js} +48 -46
  17. package/dist/cli/hive-promoter-bqtj8261.js +85 -0
  18. package/dist/cli/{index-kv2tdkk5.js → index-03enxdaq.js} +1 -1
  19. package/dist/cli/{index-ggrp3v00.js → index-0byep4pe.js} +15 -17
  20. package/dist/cli/{index-2bgr671r.js → index-2bhz5k91.js} +20 -2
  21. package/dist/cli/{index-mmjamc9b.js → index-3fnym6ac.js} +5 -5
  22. package/dist/cli/{index-d9entpn3.js → index-40twgsyh.js} +4 -4
  23. package/dist/cli/{index-ggtmsm84.js → index-4mjmnysc.js} +1 -1
  24. package/dist/cli/{index-e90em0x4.js → index-4vb56w2k.js} +12 -17
  25. package/dist/cli/{index-r656jh9j.js → index-5wc5pbzc.js} +3700 -2609
  26. package/dist/cli/{index-w3gtqey0.js → index-6chhqq2n.js} +4 -4
  27. package/dist/cli/{index-qbw3yw2d.js → index-888pq4xx.js} +11 -11
  28. package/dist/cli/{index-3146wmgv.js → index-8d90gzaz.js} +1 -1
  29. package/dist/cli/{index-5jx22kwc.js → index-8vw2pjgr.js} +544 -15
  30. package/dist/cli/{index-b2nj04q6.js → index-9ss2m4rs.js} +1 -434
  31. package/dist/cli/{index-x43debgx.js → index-ad9064j9.js} +15 -17
  32. package/dist/cli/{index-5kcvrpkt.js → index-b25t91a3.js} +1 -1
  33. package/dist/cli/index-c45662wc.js +361 -0
  34. package/dist/cli/{index-aqppaaqx.js → index-cgewrpw5.js} +3 -2
  35. package/dist/cli/{index-zfs3zqeq.js → index-d3mpxsmy.js} +771 -21
  36. package/dist/cli/{index-y1yqmkv7.js → index-d7j3n5ra.js} +52 -50
  37. package/dist/cli/{index-4vb6qa73.js → index-ebce775n.js} +36 -2
  38. package/dist/cli/{index-dsg9dw3b.js → index-eed0gkv6.js} +2 -2
  39. package/dist/cli/index-es64amqt.js +675 -0
  40. package/dist/cli/{index-9gxbjkts.js → index-ewv8qa8q.js} +22 -19
  41. package/dist/cli/{index-1ww7wj8d.js → index-hb7bh4r2.js} +15 -15
  42. package/dist/cli/{index-kc2tgcm7.js → index-hg09xemc.js} +4 -4
  43. package/dist/cli/{index-w95vxjde.js → index-hvz4ad2t.js} +39 -8
  44. package/dist/cli/{index-77z98j76.js → index-k0s8n6m5.js} +314 -130
  45. package/dist/cli/{index-7m32fjb4.js → index-kxv193aq.js} +9 -9
  46. package/dist/cli/{index-hp22pzn5.js → index-m8xrbdmn.js} +2 -2
  47. package/dist/cli/{index-4gqxppcx.js → index-mee9maf5.js} +2 -2
  48. package/dist/cli/{index-r3mvsbtq.js → index-p612v1mv.js} +7 -1
  49. package/dist/cli/{index-r5q5gd2a.js → index-qgajv9rd.js} +2 -2
  50. package/dist/cli/{index-zjg4chy2.js → index-qqq04n70.js} +2 -2
  51. package/dist/cli/{index-ww6zm5hr.js → index-r2p0pgst.js} +3 -3
  52. package/dist/cli/{index-47kh2103.js → index-r69gzes2.js} +14 -14
  53. package/dist/cli/{index-vdn32nws.js → index-sphahrmq.js} +3 -3
  54. package/dist/cli/{index-rhqdsc1x.js → index-vw66q1rw.js} +9 -9
  55. package/dist/cli/{index-kch6yenm.js → index-wasdrhev.js} +7 -7
  56. package/dist/cli/{index-c5v1w13g.js → index-wknpkfm8.js} +807 -629
  57. package/dist/cli/{index-pp2nya9v.js → index-x39hjdf1.js} +2 -4
  58. package/dist/cli/{index-n8688d12.js → index-xxfk62zd.js} +2 -2
  59. package/dist/cli/index-yvqg6kn5.js +429 -0
  60. package/dist/cli/{index-nqsj0g5y.js → index-ztm0q26v.js} +8 -8
  61. package/dist/cli/index.js +50 -48
  62. package/dist/cli/{knowledge-escalator-j04g450p.js → knowledge-escalator-01vva51d.js} +17 -18
  63. package/dist/cli/{knowledge-events-53z45rs0.js → knowledge-events-dpfwh1hs.js} +15 -16
  64. package/dist/cli/{knowledge-link-a6kfg3qm.js → knowledge-link-2rvp966j.js} +4 -5
  65. package/dist/cli/{knowledge-store-whm0gagt.js → knowledge-store-aw58ae7b.js} +6 -7
  66. package/dist/cli/{knowledge-validator-h8m7065g.js → knowledge-validator-yhd31ryf.js} +8 -9
  67. package/dist/cli/{pending-delegations-6hkpe5ze.js → pending-delegations-fjetcz8e.js} +17 -8
  68. package/dist/cli/{pr-subscriptions-11zca1mh.js → pr-subscriptions-cwwtfs8w.js} +17 -8
  69. package/dist/cli/{pr-workflow-gate-6g29rkg7.js → pr-workflow-gate-5xwtg1k2.js} +50 -48
  70. package/dist/cli/{runner-5abw3t35.js → runner-mb51twxt.js} +6 -7
  71. package/dist/cli/{scan-cursor-mkfx410t.js → scan-cursor-j11qwf0v.js} +9 -10
  72. package/dist/cli/{schema-jbbam3ev.js → schema-0xp3bde3.js} +1 -1
  73. package/dist/cli/{scope-persistence-q1ct4k42.js → scope-persistence-brrk806y.js} +19 -12
  74. package/dist/cli/{skill-generator-cv8fg96x.js → skill-generator-j8qzmet9.js} +20 -21
  75. package/dist/cli/snapshot-coordination-init-h0xmtftq.js +84 -0
  76. package/dist/cli/{telemetry-mbqqamsj.js → telemetry-m84ap0pp.js} +1 -1
  77. package/dist/cli/{workspace-snapshot-eh18vgkn.js → workspace-snapshot-6z9rk7xw.js} +3 -3
  78. package/dist/cli/{worktree-collision-ownership-xgnn8dsq.js → worktree-collision-ownership-j9zykj18.js} +21 -12
  79. package/dist/cli/{worktree-isolation-k2dgfmeg.js → worktree-isolation-jd39xz6h.js} +48 -46
  80. package/dist/commands/close.d.ts +13 -6
  81. package/dist/commands/reset-session.d.ts +4 -0
  82. package/dist/db/coordination-store.d.ts +85 -0
  83. package/dist/db/durability.d.ts +22 -5
  84. package/dist/db/index.d.ts +1 -0
  85. package/dist/db/project-db.d.ts +12 -0
  86. package/dist/index.js +810 -705
  87. package/dist/memory/schema.d.ts +3 -3
  88. package/dist/pr-review/authorization.d.ts +5 -4
  89. package/dist/pr-review/persistence.d.ts +10 -1
  90. package/dist/scope/scope-binding.d.ts +10 -0
  91. package/dist/scope/scope-persistence.d.ts +10 -0
  92. package/dist/services/handoff-service.d.ts +2 -0
  93. package/dist/services/status-service.d.ts +4 -0
  94. package/dist/session/snapshot-coordination-init.d.ts +49 -0
  95. package/dist/session/snapshot-reader.d.ts +2 -0
  96. package/dist/session/snapshot-store.d.ts +42 -0
  97. package/dist/session/snapshot-writer.d.ts +4 -1
  98. package/dist/state.d.ts +6 -3
  99. package/dist/turbo/epic/state.d.ts +4 -20
  100. package/dist/utils/bun-compat.d.ts +10 -0
  101. package/dist/utils/external-tool-runner.d.ts +2 -0
  102. package/package.json +3 -2
  103. package/dist/cli/curator-llm-factory-sxcpmcqq.js +0 -68
  104. package/dist/cli/guardrail-explain-xv9aw1bf.js +0 -69
  105. package/dist/cli/hive-promoter-09yc9mp5.js +0 -83
  106. package/dist/cli/index-xnb3tk7x.js +0 -24
  107. package/dist/cli/{ast-diff-ekd9v10f.js → ast-diff-b0esr2kf.js} +3 -3
@@ -7,13 +7,11 @@ import {
7
7
  computeTaskSetContentHash,
8
8
  resolveContainedExistingPath
9
9
  } from "./index-txdagbh7.js";
10
- import {
11
- atomicWriteFile
12
- } from "./index-xnb3tk7x.js";
13
10
  import {
14
11
  assertProjectRoot,
12
+ atomicWriteFile,
15
13
  withEvidenceLock
16
- } from "./index-2bgr671r.js";
14
+ } from "./index-2bhz5k91.js";
17
15
  import {
18
16
  exports_external,
19
17
  init_zod
@@ -1,10 +1,10 @@
1
1
  // @bun
2
2
  import {
3
3
  validateSwarmPath
4
- } from "./index-zjg4chy2.js";
4
+ } from "./index-qqq04n70.js";
5
5
  import {
6
6
  atomicWriteSwarmFileSync
7
- } from "./index-9gxbjkts.js";
7
+ } from "./index-ewv8qa8q.js";
8
8
 
9
9
  // src/hooks/delegation-gate/worktree-provisioning-owner.ts
10
10
  import { createHash } from "crypto";
@@ -0,0 +1,429 @@
1
+ // @bun
2
+ import {
3
+ derivePlanId,
4
+ derivePlanIdentityHash
5
+ } from "./index-c45662wc.js";
6
+ import {
7
+ DURABILITY_CLASSES,
8
+ getProjectDb,
9
+ projectDbExists,
10
+ withImmediateTransaction
11
+ } from "./index-es64amqt.js";
12
+ import {
13
+ init_logger,
14
+ warn
15
+ } from "./index-zgwm4ryv.js";
16
+ // src/db/qa-gate-profile.ts
17
+ import { createHash } from "crypto";
18
+
19
+ // src/qa-gate/recovery.ts
20
+ function formatLegacyQaBindingOnlyCall(identity) {
21
+ return `set_qa_gates({ swarm_id: ${JSON.stringify(identity.swarm)}, plan_title: ${JSON.stringify(identity.title)}, adopt_legacy_binding_only: true })`;
22
+ }
23
+ function formatLegacyQaBindingRecovery(identity, retryAction) {
24
+ return `Run ${formatLegacyQaBindingOnlyCall(identity)} from the current persisted plan identity to exact-bind the existing QA profile without changing gates or its lock, then ${retryAction}.`;
25
+ }
26
+
27
+ // src/db/qa-gate-profile.ts
28
+ init_logger();
29
+ var _internals = {
30
+ getProfile,
31
+ getProfileLookupForIdentity,
32
+ getProfileForIdentity,
33
+ getOrCreateProfile,
34
+ getOrCreateProfileForIdentity,
35
+ setGates,
36
+ setGatesForIdentity,
37
+ lockProfileForIdentity,
38
+ getEffectiveGates,
39
+ computeProfileHash,
40
+ hasAnyProfileWithEnabledGate,
41
+ afterSetGatesRead: () => {},
42
+ lastTxnSynchronous: -1
43
+ };
44
+ var DEFAULT_QA_GATES = {
45
+ reviewer: true,
46
+ test_engineer: true,
47
+ council_mode: false,
48
+ sme_enabled: true,
49
+ critic_pre_plan: true,
50
+ hallucination_guard: false,
51
+ sast_enabled: true,
52
+ mutation_test: false,
53
+ phase_council: false,
54
+ drift_check: true,
55
+ final_council: false
56
+ };
57
+
58
+ class QaGateProfileIdentityUnboundError extends Error {
59
+ identity;
60
+ constructor(identity) {
61
+ super(`QA gate profile exists for readable plan_id='${identity.planId}' but is not exact-bound to swarm_id='${identity.swarm}' and plan_title='${identity.title}'. ${formatLegacyQaBindingRecovery(identity, "retry the blocked read-only or enforcement operation")}`);
62
+ this.name = "QaGateProfileIdentityUnboundError";
63
+ this.identity = identity;
64
+ }
65
+ }
66
+ function buildProfileIdentity(identity) {
67
+ return {
68
+ swarm: identity.swarm,
69
+ title: identity.title,
70
+ planId: derivePlanId(identity),
71
+ identityHash: derivePlanIdentityHash(identity)
72
+ };
73
+ }
74
+ function withImmediateTransaction2(db, fn) {
75
+ return withImmediateTransaction(db, DURABILITY_CLASSES.qa_gate_profile, fn, {
76
+ beforeOuterCommit: (connection) => {
77
+ _internals.lastTxnSynchronous = connection.query("PRAGMA synchronous").get()?.synchronous ?? -1;
78
+ }
79
+ });
80
+ }
81
+ function rowToProfile(row) {
82
+ return rowToProfileWithBinding(row);
83
+ }
84
+ function rowToProfileWithBinding(row, binding) {
85
+ let parsed = {};
86
+ try {
87
+ const maybeGates = JSON.parse(row.gates);
88
+ if (maybeGates && typeof maybeGates === "object" && !Array.isArray(maybeGates)) {
89
+ parsed = maybeGates;
90
+ }
91
+ } catch {
92
+ parsed = {};
93
+ }
94
+ const raw = parsed;
95
+ if (raw.council_mode === true && raw.phase_council === undefined) {
96
+ parsed.phase_council = true;
97
+ parsed.council_mode = false;
98
+ }
99
+ const knownKeys = new Set(Object.keys(DEFAULT_QA_GATES));
100
+ const filteredParsed = {};
101
+ for (const key of Object.keys(parsed)) {
102
+ if (knownKeys.has(key) && typeof parsed[key] === "boolean") {
103
+ filteredParsed[key] = parsed[key];
104
+ }
105
+ }
106
+ const gates = { ...DEFAULT_QA_GATES, ...filteredParsed };
107
+ return {
108
+ id: row.id,
109
+ plan_id: binding?.readable_plan_id ?? row.plan_id,
110
+ created_at: row.created_at,
111
+ project_type: row.project_type,
112
+ gates,
113
+ locked_at: row.locked_at,
114
+ locked_by_snapshot_seq: row.locked_by_snapshot_seq,
115
+ raw_swarm: binding?.raw_swarm ?? row.raw_swarm,
116
+ raw_title: binding?.raw_title ?? row.raw_title,
117
+ identity_hash: binding?.identity_hash ?? row.identity_hash
118
+ };
119
+ }
120
+ function readProfileRowByPlanId(db, planId) {
121
+ return db.query("SELECT * FROM qa_gate_profile WHERE plan_id = ?").get(planId) ?? null;
122
+ }
123
+ function readProfileRowById(db, id) {
124
+ return db.query("SELECT * FROM qa_gate_profile WHERE id = ?").get(id) ?? null;
125
+ }
126
+ function readIdentityBindingByHash(db, identityHash) {
127
+ return db.query("SELECT * FROM qa_gate_profile_identity WHERE identity_hash = ?").get(identityHash) ?? null;
128
+ }
129
+ function readUnboundLegacyProfileRowByReadablePlanId(db, readablePlanId) {
130
+ return db.query(`SELECT p.*
131
+ FROM qa_gate_profile AS p
132
+ LEFT JOIN qa_gate_profile_identity AS qi
133
+ ON qi.profile_id = p.id
134
+ WHERE p.plan_id = ?
135
+ AND qi.profile_id IS NULL
136
+ LIMIT 1`).get(readablePlanId) ?? null;
137
+ }
138
+ function buildExactStoragePlanId(identityHash) {
139
+ return `qa2-${identityHash}`;
140
+ }
141
+ function hasAnyGatePatch(gates) {
142
+ return Object.values(gates).some((value) => value !== undefined);
143
+ }
144
+ function verifyBoundIdentityBinding(binding, identity) {
145
+ if (binding.identity_hash !== identity.identityHash || binding.raw_swarm !== identity.swarm || binding.raw_title !== identity.title || binding.readable_plan_id !== identity.planId) {
146
+ throw new Error(`QA gate profile identity binding is corrupt for swarm_id='${identity.swarm}' and plan_title='${identity.title}'`);
147
+ }
148
+ }
149
+ function lookupProfileForIdentityTx(db, identity) {
150
+ const binding = readIdentityBindingByHash(db, identity.identityHash);
151
+ if (binding) {
152
+ verifyBoundIdentityBinding(binding, identity);
153
+ const row = readProfileRowById(db, binding.profile_id);
154
+ if (!row) {
155
+ throw new Error(`QA gate profile identity binding points to missing profile_id=${binding.profile_id}`);
156
+ }
157
+ return {
158
+ kind: "bound",
159
+ identity,
160
+ profile: rowToProfileWithBinding(row, binding)
161
+ };
162
+ }
163
+ const legacyRow = readUnboundLegacyProfileRowByReadablePlanId(db, identity.planId);
164
+ if (legacyRow) {
165
+ return {
166
+ kind: "unbound_legacy",
167
+ identity,
168
+ profile: rowToProfile(legacyRow)
169
+ };
170
+ }
171
+ return {
172
+ kind: "missing",
173
+ identity
174
+ };
175
+ }
176
+ function createExactIdentityBindingTx(db, profileId, identity) {
177
+ db.run("INSERT INTO qa_gate_profile_identity (identity_hash, profile_id, raw_swarm, raw_title, readable_plan_id) VALUES (?, ?, ?, ?, ?)", [
178
+ identity.identityHash,
179
+ profileId,
180
+ identity.swarm,
181
+ identity.title,
182
+ identity.planId
183
+ ]);
184
+ }
185
+ function createExactProfileTx(db, identity, projectType, initialGates) {
186
+ const gatesJson = JSON.stringify({ ...DEFAULT_QA_GATES, ...initialGates });
187
+ db.run("INSERT INTO qa_gate_profile (plan_id, project_type, gates) VALUES (?, ?, ?)", [
188
+ buildExactStoragePlanId(identity.identityHash),
189
+ projectType ?? null,
190
+ gatesJson
191
+ ]);
192
+ const row = readProfileRowByPlanId(db, buildExactStoragePlanId(identity.identityHash));
193
+ if (!row) {
194
+ throw new Error(`Failed to create QA gate profile row for exact identity plan_id=${identity.planId}`);
195
+ }
196
+ createExactIdentityBindingTx(db, row.id, identity);
197
+ const binding = readIdentityBindingByHash(db, identity.identityHash);
198
+ if (!binding) {
199
+ throw new Error(`Failed to create QA gate profile identity binding for plan_id=${identity.planId}`);
200
+ }
201
+ return rowToProfileWithBinding(row, binding);
202
+ }
203
+ function shouldAdoptLegacyProfile(identity, options) {
204
+ if (options.allowLegacyAdoption !== true) {
205
+ return false;
206
+ }
207
+ return options.legacyAdoptionIdentity?.swarm === identity.swarm && options.legacyAdoptionIdentity?.title === identity.title;
208
+ }
209
+ function getProfile(directory, planId) {
210
+ if (!projectDbExists(directory))
211
+ return null;
212
+ const db = getProjectDb(directory);
213
+ const row = readProfileRowByPlanId(db, planId);
214
+ return row ? rowToProfile(row) : null;
215
+ }
216
+ function getProfileForIdentity(directory, identity) {
217
+ const lookup = getProfileLookupForIdentity(directory, identity);
218
+ if (lookup.kind === "bound") {
219
+ return lookup.profile;
220
+ }
221
+ if (lookup.kind === "unbound_legacy") {
222
+ throw new QaGateProfileIdentityUnboundError(lookup.identity);
223
+ }
224
+ return null;
225
+ }
226
+ function getProfileLookupForIdentity(directory, identity) {
227
+ const exact = buildProfileIdentity(identity);
228
+ if (!projectDbExists(directory)) {
229
+ return {
230
+ kind: "missing",
231
+ identity: exact
232
+ };
233
+ }
234
+ const db = getProjectDb(directory);
235
+ return lookupProfileForIdentityTx(db, exact);
236
+ }
237
+ function hasAnyProfileWithEnabledGate(directory, gate) {
238
+ if (!projectDbExists(directory))
239
+ return false;
240
+ const db = getProjectDb(directory);
241
+ const rows = db.query("SELECT gates FROM qa_gate_profile").all();
242
+ for (const row of rows) {
243
+ try {
244
+ const parsed = JSON.parse(row.gates);
245
+ if (parsed?.[gate] === true)
246
+ return true;
247
+ } catch (err) {
248
+ warn(`[qa-gate-profile] skipping unparseable qa_gate_profile row while checking gate "${gate}": ${err instanceof Error ? err.message : String(err)}`);
249
+ }
250
+ }
251
+ return false;
252
+ }
253
+ function getOrCreateProfile(directory, planId, projectType, initialGates = {}) {
254
+ const existing = _internals.getProfile(directory, planId);
255
+ if (existing)
256
+ return existing;
257
+ const db = getProjectDb(directory);
258
+ const seededGates = { ...DEFAULT_QA_GATES };
259
+ for (const key of Object.keys(DEFAULT_QA_GATES)) {
260
+ if (typeof initialGates[key] === "boolean") {
261
+ seededGates[key] = initialGates[key];
262
+ }
263
+ }
264
+ const gatesJson = JSON.stringify(seededGates);
265
+ try {
266
+ withImmediateTransaction2(db, () => {
267
+ db.run("INSERT INTO qa_gate_profile (plan_id, project_type, gates) VALUES (?, ?, ?)", [planId, projectType ?? null, gatesJson]);
268
+ });
269
+ } catch (err) {
270
+ const msg = err instanceof Error ? err.message : String(err);
271
+ if (!msg.toLowerCase().includes("unique")) {
272
+ throw err;
273
+ }
274
+ }
275
+ const after = _internals.getProfile(directory, planId);
276
+ if (!after) {
277
+ throw new Error(`Failed to create or load QA gate profile for plan_id=${planId}`);
278
+ }
279
+ return after;
280
+ }
281
+ function getOrCreateProfileForIdentity(directory, identity, projectType, initialGates = {}) {
282
+ const db = getProjectDb(directory);
283
+ const exact = buildProfileIdentity(identity);
284
+ return withImmediateTransaction2(db, () => {
285
+ const lookup = lookupProfileForIdentityTx(db, exact);
286
+ if (lookup.kind === "bound") {
287
+ return lookup.profile;
288
+ }
289
+ return createExactProfileTx(db, exact, projectType, initialGates);
290
+ });
291
+ }
292
+ function setGates(directory, planId, gates) {
293
+ const db = getProjectDb(directory);
294
+ return withImmediateTransaction2(db, () => {
295
+ const currentRow = db.query("SELECT * FROM qa_gate_profile WHERE plan_id = ?").get(planId);
296
+ if (!currentRow) {
297
+ throw new Error(`No QA gate profile found for plan_id=${planId} \u2014 call getOrCreateProfile first`);
298
+ }
299
+ const current = rowToProfile(currentRow);
300
+ if (current.locked_at !== null) {
301
+ throw new Error("Cannot modify gates: QA gate profile is locked after critic approval");
302
+ }
303
+ _internals.afterSetGatesRead(current);
304
+ const merged = { ...current.gates };
305
+ for (const key of Object.keys(gates)) {
306
+ const incoming = gates[key];
307
+ if (incoming === undefined)
308
+ continue;
309
+ if (incoming === false && current.gates[key] === true) {
310
+ throw new Error(`Cannot disable gate '${key}': sessions can only ratchet tighter`);
311
+ }
312
+ if (incoming === true) {
313
+ merged[key] = true;
314
+ }
315
+ }
316
+ db.run("UPDATE qa_gate_profile SET gates = ? WHERE plan_id = ?", [
317
+ JSON.stringify(merged),
318
+ planId
319
+ ]);
320
+ const updatedRow = db.query("SELECT * FROM qa_gate_profile WHERE plan_id = ?").get(planId);
321
+ if (!updatedRow) {
322
+ throw new Error(`Failed to re-read QA gate profile after update for plan_id=${planId}`);
323
+ }
324
+ return rowToProfile(updatedRow);
325
+ });
326
+ }
327
+ function setGatesForIdentity(directory, identity, gates, options = {}) {
328
+ const db = getProjectDb(directory);
329
+ const exact = buildProfileIdentity(identity);
330
+ return withImmediateTransaction2(db, () => {
331
+ let lookup = lookupProfileForIdentityTx(db, exact);
332
+ if (lookup.kind === "missing") {
333
+ return createExactProfileTx(db, exact, options.projectType, gates);
334
+ }
335
+ if (lookup.kind === "unbound_legacy") {
336
+ if (shouldAdoptLegacyProfile(exact, options)) {
337
+ createExactIdentityBindingTx(db, lookup.profile.id, exact);
338
+ lookup = lookupProfileForIdentityTx(db, exact);
339
+ if (lookup.kind !== "bound") {
340
+ throw new Error(`Failed to adopt legacy QA gate profile for exact identity plan_id=${exact.planId}`);
341
+ }
342
+ } else if (options.allowLegacyCollisionCreate === true) {
343
+ return createExactProfileTx(db, exact, options.projectType, gates);
344
+ } else {
345
+ throw new QaGateProfileIdentityUnboundError(lookup.identity);
346
+ }
347
+ }
348
+ const current = lookup.profile;
349
+ const currentRow = readProfileRowById(db, current.id);
350
+ if (!currentRow) {
351
+ throw new Error(`Failed to read QA gate profile row for profile_id=${current.id}`);
352
+ }
353
+ _internals.afterSetGatesForIdentityRead?.({
354
+ directory,
355
+ identity: exact,
356
+ profileId: current.id,
357
+ storagePlanId: currentRow.plan_id
358
+ });
359
+ if (current.locked_at !== null) {
360
+ if (!hasAnyGatePatch(gates)) {
361
+ return current;
362
+ }
363
+ throw new Error("Cannot modify gates: QA gate profile is locked after critic approval");
364
+ }
365
+ const merged = { ...current.gates };
366
+ for (const key of Object.keys(gates)) {
367
+ const incoming = gates[key];
368
+ if (incoming === undefined)
369
+ continue;
370
+ if (incoming === false && current.gates[key] === true) {
371
+ throw new Error(`Cannot disable gate '${key}': sessions can only ratchet tighter`);
372
+ }
373
+ if (incoming === true) {
374
+ merged[key] = true;
375
+ }
376
+ }
377
+ db.run("UPDATE qa_gate_profile SET gates = ? WHERE id = ?", [
378
+ JSON.stringify(merged),
379
+ current.id
380
+ ]);
381
+ const updatedRow = readProfileRowById(db, current.id);
382
+ const binding = readIdentityBindingByHash(db, exact.identityHash);
383
+ if (!updatedRow || !binding) {
384
+ throw new Error(`Failed to re-read QA gate profile after exact-identity update for plan_id=${exact.planId}`);
385
+ }
386
+ return rowToProfileWithBinding(updatedRow, binding);
387
+ });
388
+ }
389
+ function lockProfileForIdentity(directory, identity, snapshotSeq) {
390
+ const db = getProjectDb(directory);
391
+ const exact = buildProfileIdentity(identity);
392
+ return withImmediateTransaction2(db, () => {
393
+ const lookup = lookupProfileForIdentityTx(db, exact);
394
+ if (lookup.kind === "missing") {
395
+ throw new Error(`No QA gate profile found for exact identity plan_id=${exact.planId} \u2014 cannot lock`);
396
+ }
397
+ if (lookup.kind === "unbound_legacy") {
398
+ throw new QaGateProfileIdentityUnboundError(lookup.identity);
399
+ }
400
+ if (lookup.profile.locked_at !== null) {
401
+ return lookup.profile;
402
+ }
403
+ db.run("UPDATE qa_gate_profile SET locked_at = datetime('now'), locked_by_snapshot_seq = ? WHERE id = ?", [snapshotSeq, lookup.profile.id]);
404
+ const updatedRow = readProfileRowById(db, lookup.profile.id);
405
+ const binding = readIdentityBindingByHash(db, exact.identityHash);
406
+ if (!updatedRow || !binding) {
407
+ throw new Error(`Failed to re-read locked QA gate profile for exact identity plan_id=${exact.planId}`);
408
+ }
409
+ return rowToProfileWithBinding(updatedRow, binding);
410
+ });
411
+ }
412
+ function computeProfileHash(profile) {
413
+ const payload = JSON.stringify({
414
+ plan_id: profile.plan_id,
415
+ identity_hash: profile.identity_hash,
416
+ gates: profile.gates
417
+ });
418
+ return createHash("sha256").update(payload).digest("hex");
419
+ }
420
+ function getEffectiveGates(profile, sessionOverrides) {
421
+ const merged = { ...profile.gates };
422
+ for (const key of Object.keys(sessionOverrides)) {
423
+ if (sessionOverrides[key] === true) {
424
+ merged[key] = true;
425
+ }
426
+ }
427
+ return merged;
428
+ }
429
+ export { formatLegacyQaBindingOnlyCall, DEFAULT_QA_GATES, getProfileLookupForIdentity, setGatesForIdentity, computeProfileHash, getEffectiveGates };
@@ -5,7 +5,7 @@ import {
5
5
  batchDurabilityClass,
6
6
  classifyDbWriteError,
7
7
  getProjectDb
8
- } from "./index-b2nj04q6.js";
8
+ } from "./index-es64amqt.js";
9
9
  import {
10
10
  _internals,
11
11
  canonicalRootKeyFresh
@@ -16,6 +16,13 @@ import {
16
16
  warn
17
17
  } from "./index-zgwm4ryv.js";
18
18
 
19
+ // src/db/canonical-project.ts
20
+ var defaultCanonicalRootRealpath = _internals.realpathSync;
21
+ var defaultCanonicalRootNativeRealpath = _internals.realpathSyncNative;
22
+ function canonicalProjectKey(directory) {
23
+ return canonicalRootKeyFresh(directory);
24
+ }
25
+
19
26
  // src/background/event-bus.ts
20
27
  class AutomationEventBus {
21
28
  listeners = new Map;
@@ -83,13 +90,6 @@ function getGlobalEventBus() {
83
90
  return globalEventBus;
84
91
  }
85
92
 
86
- // src/db/canonical-project.ts
87
- var defaultCanonicalRootRealpath = _internals.realpathSync;
88
- var defaultCanonicalRootNativeRealpath = _internals.realpathSyncNative;
89
- function canonicalProjectKey(directory) {
90
- return canonicalRootKeyFresh(directory);
91
- }
92
-
93
93
  // src/db/group-commit-writer.ts
94
94
  init_logger();
95
95
  function isClosedHandleError(err) {
package/dist/cli/index.js CHANGED
@@ -11,72 +11,74 @@ import {
11
11
  readCachePackageVersion,
12
12
  resolveCommand,
13
13
  safeRealpathSync
14
- } from "./index-r656jh9j.js";
15
- import"./index-w95vxjde.js";
16
- import"./index-kch6yenm.js";
17
- import"./index-5kcvrpkt.js";
18
- import"./index-77z98j76.js";
19
- import"./index-pp2nya9v.js";
14
+ } from "./index-5wc5pbzc.js";
15
+ import"./index-8d90gzaz.js";
16
+ import"./index-hvz4ad2t.js";
17
+ import"./index-wasdrhev.js";
18
+ import"./index-b25t91a3.js";
19
+ import"./index-k0s8n6m5.js";
20
+ import"./index-x39hjdf1.js";
20
21
  import"./index-txdagbh7.js";
21
22
  import"./index-cw912re7.js";
22
- import"./index-3146wmgv.js";
23
- import"./index-1ww7wj8d.js";
24
- import"./index-7m32fjb4.js";
25
- import"./index-d9entpn3.js";
23
+ import"./index-hb7bh4r2.js";
24
+ import"./index-kxv193aq.js";
25
+ import"./index-40twgsyh.js";
26
26
  import"./index-70ha9e09.js";
27
- import"./index-nqsj0g5y.js";
28
- import"./index-b2nj04q6.js";
29
- import"./index-n4fzmqz8.js";
30
- import"./index-zfs3zqeq.js";
27
+ import"./index-ztm0q26v.js";
28
+ import"./index-9ss2m4rs.js";
29
+ import"./index-d3mpxsmy.js";
31
30
  import"./index-zsrtt42s.js";
32
- import"./index-47kh2103.js";
33
- import"./index-w3gtqey0.js";
34
- import"./index-n8688d12.js";
35
- import"./index-kc2tgcm7.js";
36
- import"./index-ggtmsm84.js";
37
- import"./index-rtry5xyf.js";
38
- import"./index-x43debgx.js";
39
- import"./index-4vb6qa73.js";
40
- import"./index-5jx22kwc.js";
41
- import"./index-c5v1w13g.js";
42
- import"./index-e90em0x4.js";
43
- import"./index-ry16d01s.js";
44
- import"./index-4gqxppcx.js";
45
- import"./index-556ja8an.js";
46
- import"./index-4fwbbad3.js";
31
+ import"./index-r69gzes2.js";
32
+ import"./index-6chhqq2n.js";
33
+ import"./index-xxfk62zd.js";
47
34
  import"./index-b43rt5ph.js";
48
35
  import"./index-q7sjgr1y.js";
49
- import"./index-qbw3yw2d.js";
50
- import"./index-ggrp3v00.js";
51
- import"./index-r5q5gd2a.js";
36
+ import"./index-ad9064j9.js";
37
+ import"./index-ebce775n.js";
38
+ import"./index-8vw2pjgr.js";
39
+ import"./index-0byep4pe.js";
40
+ import"./index-qqq04n70.js";
41
+ import"./index-z6xqpmqg.js";
42
+ import"./index-p612v1mv.js";
43
+ import"./index-hg09xemc.js";
44
+ import"./index-4mjmnysc.js";
45
+ import"./index-rtry5xyf.js";
46
+ import"./index-qgajv9rd.js";
52
47
  import"./index-3qf1vxtb.js";
53
48
  import"./index-n832052r.js";
54
- import"./index-zjg4chy2.js";
55
- import"./index-z6xqpmqg.js";
56
- import"./index-r3mvsbtq.js";
57
- import"./index-rhqdsc1x.js";
49
+ import"./index-wknpkfm8.js";
50
+ import"./index-4vb56w2k.js";
51
+ import"./index-mee9maf5.js";
52
+ import"./index-556ja8an.js";
53
+ import"./index-yvqg6kn5.js";
54
+ import"./index-c45662wc.js";
55
+ import"./index-es64amqt.js";
56
+ import"./index-ry16d01s.js";
57
+ import"./index-n4fzmqz8.js";
58
+ import"./index-eed0gkv6.js";
59
+ import"./index-888pq4xx.js";
60
+ import"./index-ae75rja9.js";
61
+ import"./index-sphahrmq.js";
62
+ import"./index-7qefgq4j.js";
63
+ import"./index-2bhz5k91.js";
64
+ import"./index-ewv8qa8q.js";
65
+ import"./index-r2p0pgst.js";
66
+ import"./index-7g4c7s5r.js";
67
+ import"./index-vw66q1rw.js";
68
+ import"./index-9e6fdz2h.js";
69
+ import"./index-4rhhvd1a.js";
58
70
  import {
59
71
  init_package,
60
72
  package_default
61
- } from "./index-aqppaaqx.js";
62
- import"./index-9e6fdz2h.js";
63
- import"./index-4rhhvd1a.js";
64
- import"./index-dsg9dw3b.js";
73
+ } from "./index-cgewrpw5.js";
65
74
  import {
66
75
  DEFAULT_AGENT_CONFIGS,
67
76
  init_constants
68
77
  } from "./index-50j914b5.js";
69
78
  import"./index-zjygnfay.js";
70
- import"./index-ae75rja9.js";
71
- import"./index-vdn32nws.js";
72
- import"./index-xnb3tk7x.js";
73
79
  import"./index-bk5tah7q.js";
74
- import"./index-7qefgq4j.js";
75
- import"./index-2bgr671r.js";
76
- import"./index-9gxbjkts.js";
77
- import"./index-ww6zm5hr.js";
78
- import"./index-7g4c7s5r.js";
79
80
  import"./index-bpmtbmy9.js";
81
+ import"./index-4fwbbad3.js";
80
82
  import"./index-zgwm4ryv.js";
81
83
  import"./index-a76rekgs.js";
82
84
 
@@ -9,31 +9,30 @@ import {
9
9
  maybeEscalateOnViolation,
10
10
  maybeQuarantineOnContradiction,
11
11
  readRecentEscalations
12
- } from "./index-7m32fjb4.js";
13
- import"./index-qbw3yw2d.js";
14
- import"./index-ggrp3v00.js";
15
- import"./index-r5q5gd2a.js";
12
+ } from "./index-kxv193aq.js";
13
+ import"./index-0byep4pe.js";
14
+ import"./index-qqq04n70.js";
15
+ import"./index-z6xqpmqg.js";
16
+ import"./index-p612v1mv.js";
17
+ import"./index-qgajv9rd.js";
16
18
  import"./index-3qf1vxtb.js";
17
19
  import"./index-n832052r.js";
18
- import"./index-zjg4chy2.js";
19
- import"./index-z6xqpmqg.js";
20
- import"./index-r3mvsbtq.js";
21
- import"./index-rhqdsc1x.js";
22
- import"./index-aqppaaqx.js";
20
+ import"./index-eed0gkv6.js";
21
+ import"./index-888pq4xx.js";
22
+ import"./index-ae75rja9.js";
23
+ import"./index-sphahrmq.js";
24
+ import"./index-7qefgq4j.js";
25
+ import"./index-2bhz5k91.js";
26
+ import"./index-ewv8qa8q.js";
27
+ import"./index-r2p0pgst.js";
28
+ import"./index-7g4c7s5r.js";
29
+ import"./index-vw66q1rw.js";
23
30
  import"./index-9e6fdz2h.js";
24
31
  import"./index-4rhhvd1a.js";
25
- import"./index-dsg9dw3b.js";
32
+ import"./index-cgewrpw5.js";
26
33
  import"./index-50j914b5.js";
27
34
  import"./index-zjygnfay.js";
28
- import"./index-ae75rja9.js";
29
- import"./index-vdn32nws.js";
30
- import"./index-xnb3tk7x.js";
31
35
  import"./index-bk5tah7q.js";
32
- import"./index-7qefgq4j.js";
33
- import"./index-2bgr671r.js";
34
- import"./index-9gxbjkts.js";
35
- import"./index-ww6zm5hr.js";
36
- import"./index-7g4c7s5r.js";
37
36
  import"./index-bpmtbmy9.js";
38
37
  import"./index-zgwm4ryv.js";
39
38
  import"./index-a76rekgs.js";