@mastra/factory 0.12.1-alpha.0 → 0.13.0-alpha.10

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 (211) hide show
  1. package/README.md +163 -0
  2. package/dist/auth.d.ts +2 -0
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +35 -3
  5. package/dist/auth.js.map +1 -1
  6. package/dist/boards/define-board.d.ts +42 -0
  7. package/dist/boards/define-board.d.ts.map +1 -0
  8. package/dist/boards/define-board.js +53 -0
  9. package/dist/boards/define-board.js.map +1 -0
  10. package/dist/boards/index.d.ts +12 -0
  11. package/dist/boards/index.d.ts.map +1 -0
  12. package/dist/boards/index.js +20 -0
  13. package/dist/boards/index.js.map +1 -0
  14. package/dist/boards/registry.d.ts +16 -0
  15. package/dist/boards/registry.d.ts.map +1 -0
  16. package/dist/boards/registry.js +27 -0
  17. package/dist/boards/registry.js.map +1 -0
  18. package/dist/boards/review.d.ts +4 -0
  19. package/dist/boards/review.d.ts.map +1 -0
  20. package/dist/boards/review.js +76 -0
  21. package/dist/boards/review.js.map +1 -0
  22. package/dist/boards/transition-policy.d.ts +63 -0
  23. package/dist/boards/transition-policy.d.ts.map +1 -0
  24. package/dist/boards/transition-policy.js +36 -0
  25. package/dist/boards/transition-policy.js.map +1 -0
  26. package/dist/boards/work-transition-policy.d.ts +3 -0
  27. package/dist/boards/work-transition-policy.d.ts.map +1 -0
  28. package/dist/boards/work-transition-policy.js +31 -0
  29. package/dist/boards/work-transition-policy.js.map +1 -0
  30. package/dist/boards/work.d.ts +4 -0
  31. package/dist/boards/work.d.ts.map +1 -0
  32. package/dist/boards/work.js +154 -0
  33. package/dist/boards/work.js.map +1 -0
  34. package/dist/factory.d.ts +6 -1
  35. package/dist/factory.d.ts.map +1 -1
  36. package/dist/factory.js +101 -10
  37. package/dist/factory.js.map +1 -1
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +6 -1
  41. package/dist/integrations/github/acceptance-labels.d.ts +0 -1
  42. package/dist/integrations/github/acceptance-labels.d.ts.map +1 -1
  43. package/dist/integrations/github/acceptance-labels.js +2 -2
  44. package/dist/integrations/github/acceptance-labels.js.map +1 -1
  45. package/dist/integrations/github/default-rules.d.ts +194 -0
  46. package/dist/integrations/github/default-rules.d.ts.map +1 -0
  47. package/dist/integrations/github/default-rules.js +230 -0
  48. package/dist/integrations/github/default-rules.js.map +1 -0
  49. package/dist/integrations/github/integration.d.ts +4 -0
  50. package/dist/integrations/github/integration.d.ts.map +1 -1
  51. package/dist/integrations/github/integration.js +6 -0
  52. package/dist/integrations/github/integration.js.map +1 -1
  53. package/dist/integrations/github/provenance.d.ts +2 -0
  54. package/dist/integrations/github/provenance.d.ts.map +1 -1
  55. package/dist/integrations/github/provenance.js +3 -2
  56. package/dist/integrations/github/provenance.js.map +1 -1
  57. package/dist/integrations/github/routes.d.ts.map +1 -1
  58. package/dist/integrations/github/routes.js +15 -41
  59. package/dist/integrations/github/routes.js.map +1 -1
  60. package/dist/integrations/github/rules.d.ts +3 -1
  61. package/dist/integrations/github/rules.d.ts.map +1 -1
  62. package/dist/integrations/github/rules.js +36 -7
  63. package/dist/integrations/github/rules.js.map +1 -1
  64. package/dist/integrations/github/webhook.d.ts.map +1 -1
  65. package/dist/integrations/github/webhook.js +35 -3
  66. package/dist/integrations/github/webhook.js.map +1 -1
  67. package/dist/integrations/linear/agent-tools.d.ts +3 -3
  68. package/dist/integrations/linear/agent-tools.d.ts.map +1 -1
  69. package/dist/integrations/linear/agent-tools.js +5 -3
  70. package/dist/integrations/linear/agent-tools.js.map +1 -1
  71. package/dist/integrations/linear/default-rules.d.ts +44 -0
  72. package/dist/integrations/linear/default-rules.d.ts.map +1 -0
  73. package/dist/integrations/linear/default-rules.js +65 -0
  74. package/dist/integrations/linear/default-rules.js.map +1 -0
  75. package/dist/integrations/linear/integration.d.ts +5 -1
  76. package/dist/integrations/linear/integration.d.ts.map +1 -1
  77. package/dist/integrations/linear/integration.js +7 -1
  78. package/dist/integrations/linear/integration.js.map +1 -1
  79. package/dist/integrations/linear/issue-reconciler.d.ts +1 -1
  80. package/dist/integrations/linear/issue-reconciler.d.ts.map +1 -1
  81. package/dist/integrations/linear/issue-reconciler.js +2 -1
  82. package/dist/integrations/linear/issue-reconciler.js.map +1 -1
  83. package/dist/integrations/linear/rules.d.ts +5 -1
  84. package/dist/integrations/linear/rules.d.ts.map +1 -1
  85. package/dist/integrations/linear/rules.js +5 -4
  86. package/dist/integrations/linear/rules.js.map +1 -1
  87. package/dist/integrations/platform/github/integration.d.ts +4 -0
  88. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  89. package/dist/integrations/platform/github/integration.js +6 -0
  90. package/dist/integrations/platform/github/integration.js.map +1 -1
  91. package/dist/integrations/platform/linear/integration.d.ts +5 -1
  92. package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
  93. package/dist/integrations/platform/linear/integration.js +9 -3
  94. package/dist/integrations/platform/linear/integration.js.map +1 -1
  95. package/dist/integrations/slack/slack.d.ts +3 -1
  96. package/dist/integrations/slack/slack.d.ts.map +1 -1
  97. package/dist/integrations/slack/slack.js +20 -2
  98. package/dist/integrations/slack/slack.js.map +1 -1
  99. package/dist/routes/attention-proposed.d.ts +3 -0
  100. package/dist/routes/attention-proposed.d.ts.map +1 -0
  101. package/dist/routes/attention-proposed.js +21 -0
  102. package/dist/routes/attention-proposed.js.map +1 -0
  103. package/dist/routes/attention-providers.d.ts +33 -4
  104. package/dist/routes/attention-providers.d.ts.map +1 -1
  105. package/dist/routes/attention-providers.js +180 -47
  106. package/dist/routes/attention-providers.js.map +1 -1
  107. package/dist/routes/attention.d.ts.map +1 -1
  108. package/dist/routes/attention.js +31 -30
  109. package/dist/routes/attention.js.map +1 -1
  110. package/dist/routes/config.d.ts +2 -0
  111. package/dist/routes/config.d.ts.map +1 -1
  112. package/dist/routes/config.js +3 -2
  113. package/dist/routes/config.js.map +1 -1
  114. package/dist/routes/projects.d.ts +9 -1
  115. package/dist/routes/projects.d.ts.map +1 -1
  116. package/dist/routes/projects.js +26 -5
  117. package/dist/routes/projects.js.map +1 -1
  118. package/dist/routes/supervisor.d.ts +23 -0
  119. package/dist/routes/supervisor.d.ts.map +1 -0
  120. package/dist/routes/supervisor.js +34 -0
  121. package/dist/routes/supervisor.js.map +1 -0
  122. package/dist/routes/surface.d.ts +3 -0
  123. package/dist/routes/surface.d.ts.map +1 -1
  124. package/dist/routes/surface.js +11 -6
  125. package/dist/routes/surface.js.map +1 -1
  126. package/dist/routes/work-items.d.ts +3 -0
  127. package/dist/routes/work-items.d.ts.map +1 -1
  128. package/dist/routes/work-items.js +60 -53
  129. package/dist/routes/work-items.js.map +1 -1
  130. package/dist/rules/defaults.d.ts.map +1 -1
  131. package/dist/rules/defaults.js +2 -418
  132. package/dist/rules/defaults.js.map +1 -1
  133. package/dist/rules/dispatcher.d.ts +1 -0
  134. package/dist/rules/dispatcher.d.ts.map +1 -1
  135. package/dist/rules/dispatcher.js +87 -26
  136. package/dist/rules/dispatcher.js.map +1 -1
  137. package/dist/rules/index.d.ts +2 -2
  138. package/dist/rules/index.d.ts.map +1 -1
  139. package/dist/rules/index.js +2 -2
  140. package/dist/rules/processor.d.ts +2 -0
  141. package/dist/rules/processor.d.ts.map +1 -1
  142. package/dist/rules/processor.js +10 -7
  143. package/dist/rules/processor.js.map +1 -1
  144. package/dist/rules/resolve.d.ts +4 -5
  145. package/dist/rules/resolve.d.ts.map +1 -1
  146. package/dist/rules/resolve.js +4 -9
  147. package/dist/rules/resolve.js.map +1 -1
  148. package/dist/rules/start-coordinator.d.ts +3 -16
  149. package/dist/rules/start-coordinator.d.ts.map +1 -1
  150. package/dist/rules/start-coordinator.js +12 -43
  151. package/dist/rules/start-coordinator.js.map +1 -1
  152. package/dist/rules/terminal-cleanup.d.ts +3 -1
  153. package/dist/rules/terminal-cleanup.d.ts.map +1 -1
  154. package/dist/rules/terminal-cleanup.js +5 -0
  155. package/dist/rules/terminal-cleanup.js.map +1 -1
  156. package/dist/rules/transition-service.d.ts +3 -0
  157. package/dist/rules/transition-service.d.ts.map +1 -1
  158. package/dist/rules/transition-service.js +56 -31
  159. package/dist/rules/transition-service.js.map +1 -1
  160. package/dist/rules/types.d.ts +18 -17
  161. package/dist/rules/types.d.ts.map +1 -1
  162. package/dist/rules/types.js +10 -2
  163. package/dist/rules/types.js.map +1 -1
  164. package/dist/rules/validation.d.ts.map +1 -1
  165. package/dist/rules/validation.js +2 -38
  166. package/dist/rules/validation.js.map +1 -1
  167. package/dist/sandbox/session-retirement.js +1 -1
  168. package/dist/session/org-seed.d.ts +1 -1
  169. package/dist/session/org-seed.js +1 -1
  170. package/dist/session/org-seed.js.map +1 -1
  171. package/dist/storage/domains/comments/domain.js +1 -1
  172. package/dist/storage/domains/comments/routes.js +1 -1
  173. package/dist/storage/domains/work-items/base.d.ts +54 -19
  174. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  175. package/dist/storage/domains/work-items/base.js +215 -38
  176. package/dist/storage/domains/work-items/base.js.map +1 -1
  177. package/dist/supervisor/health-worker.d.ts +17 -0
  178. package/dist/supervisor/health-worker.d.ts.map +1 -0
  179. package/dist/supervisor/health-worker.js +72 -0
  180. package/dist/supervisor/health-worker.js.map +1 -0
  181. package/dist/supervisor/health.d.ts +81 -0
  182. package/dist/supervisor/health.d.ts.map +1 -0
  183. package/dist/supervisor/health.js +244 -0
  184. package/dist/supervisor/health.js.map +1 -0
  185. package/dist/supervisor/instructions.d.ts +6 -0
  186. package/dist/supervisor/instructions.d.ts.map +1 -0
  187. package/dist/supervisor/instructions.js +64 -0
  188. package/dist/supervisor/instructions.js.map +1 -0
  189. package/dist/supervisor/read-tools.d.ts +41 -0
  190. package/dist/supervisor/read-tools.d.ts.map +1 -0
  191. package/dist/supervisor/read-tools.js +338 -0
  192. package/dist/supervisor/read-tools.js.map +1 -0
  193. package/dist/supervisor/session.d.ts +38 -0
  194. package/dist/supervisor/session.d.ts.map +1 -0
  195. package/dist/supervisor/session.js +63 -0
  196. package/dist/supervisor/session.js.map +1 -0
  197. package/dist/supervisor/write-tools.d.ts +26 -0
  198. package/dist/supervisor/write-tools.d.ts.map +1 -0
  199. package/dist/supervisor/write-tools.js +227 -0
  200. package/dist/supervisor/write-tools.js.map +1 -0
  201. package/dist/work-item-branch.d.ts +6 -0
  202. package/dist/work-item-branch.d.ts.map +1 -1
  203. package/dist/work-item-branch.js +15 -9
  204. package/dist/work-item-branch.js.map +1 -1
  205. package/dist/workspace.d.ts +3 -0
  206. package/dist/workspace.d.ts.map +1 -1
  207. package/dist/workspace.js +15 -5
  208. package/dist/workspace.js.map +1 -1
  209. package/factory-skills/configure-factory-rules/SKILL.md +42 -11
  210. package/factory-skills/factory-triage/SKILL.md +1 -1
  211. package/package.json +13 -7
@@ -65,6 +65,23 @@ function factoryDecisionAttentionIdentity(decisionId, failureOccurrence) {
65
65
  occurrence: failureOccurrence
66
66
  };
67
67
  }
68
+ function factoryProposalAttentionIdentity(decisionId) {
69
+ return {
70
+ kind: "automation-proposed",
71
+ sourceId: decisionId,
72
+ occurrence: 0
73
+ };
74
+ }
75
+ function proposalReceiptFilter(orgId, factoryProjectId, decisionId) {
76
+ const identity = factoryProposalAttentionIdentity(decisionId);
77
+ return {
78
+ org_id: orgId,
79
+ factory_project_id: factoryProjectId,
80
+ kind: identity.kind,
81
+ source_id: identity.sourceId,
82
+ occurrence: identity.occurrence
83
+ };
84
+ }
68
85
  function factoryMentionAttentionIdentity(commentId) {
69
86
  return {
70
87
  kind: "mention",
@@ -80,6 +97,13 @@ function factoryActivityAttentionIdentity(workItemId, occurrence) {
80
97
  occurrence
81
98
  };
82
99
  }
100
+ function factorySupervisorFindingAttentionIdentity(findingKey, occurrence) {
101
+ return {
102
+ kind: "supervisor-finding",
103
+ sourceId: findingKey,
104
+ occurrence
105
+ };
106
+ }
83
107
  function factoryAttentionKey(factoryProjectId, identity) {
84
108
  return `factory:${factoryProjectId}:attention:${identity.kind}:${identity.sourceId}:${identity.occurrence}`;
85
109
  }
@@ -101,6 +125,10 @@ const WORK_ITEMS_SCHEMA = {
101
125
  id: { type: "uuid-pk" },
102
126
  org_id: { type: "text" },
103
127
  factory_project_id: { type: "text" },
128
+ board: {
129
+ type: "text",
130
+ nullable: true
131
+ },
104
132
  external_source: {
105
133
  type: "json",
106
134
  nullable: true
@@ -196,6 +224,7 @@ function toWorkItem(row) {
196
224
  id: row.id,
197
225
  orgId: row.org_id,
198
226
  factoryProjectId: String(row.factory_project_id),
227
+ board: row.board ?? null,
199
228
  externalSource: row.external_source,
200
229
  parentWorkItemId: row.parent_work_item_id,
201
230
  title: row.title,
@@ -218,6 +247,7 @@ function toWorkItem(row) {
218
247
  const toRow = toWorkItem;
219
248
  function patchColumns(changes) {
220
249
  return {
250
+ ...changes.board !== void 0 ? { board: changes.board } : {},
221
251
  ...changes.parentWorkItemId !== void 0 ? { parent_work_item_id: changes.parentWorkItemId } : {},
222
252
  ...changes.title !== void 0 ? { title: changes.title } : {},
223
253
  ...changes.stages !== void 0 ? { stages: changes.stages } : {},
@@ -246,6 +276,14 @@ function priorState(row) {
246
276
  var WorkItemRelationError = class extends Error {
247
277
  code = "invalid_work_item_relation";
248
278
  };
279
+ var WorkItemUpdateConflictError = class extends Error {
280
+ reason;
281
+ code = "work_item_update_conflict";
282
+ constructor(reason) {
283
+ super(`Work item ${reason} precondition failed`);
284
+ this.reason = reason;
285
+ }
286
+ };
249
287
  function validateParentRelation(projectItems, itemId, parentWorkItemId) {
250
288
  if (parentWorkItemId === null) return;
251
289
  const byId = new Map(projectItems.map((item) => [item.id, item]));
@@ -296,6 +334,7 @@ function stampSessions(sessions, by) {
296
334
  function applyUpdate({ current, userId, input }) {
297
335
  const now = /* @__PURE__ */ new Date();
298
336
  return {
337
+ ...input.board !== void 0 ? { board: input.board } : {},
299
338
  ...input.parentWorkItemId !== void 0 ? { parent_work_item_id: input.parentWorkItemId } : {},
300
339
  ...input.title !== void 0 ? { title: input.title } : {},
301
340
  ...input.stages !== void 0 ? {
@@ -310,6 +349,7 @@ function applyUpdate({ current, userId, input }) {
310
349
  ...current.metadata ?? {},
311
350
  ...input.metadata
312
351
  } } : {},
352
+ ...input.plansPreapproved && !current.plans_preapproved_at ? { plans_preapproved_at: now } : {},
313
353
  revision: current.revision + 1,
314
354
  updated_at: now
315
355
  };
@@ -490,6 +530,41 @@ const FACTORY_GOVERNANCE_SCHEMAS = [
490
530
  }
491
531
  ]
492
532
  },
533
+ {
534
+ name: "factory_supervisor_findings",
535
+ columns: {
536
+ id: { type: "uuid-pk" },
537
+ org_id: { type: "text" },
538
+ factory_project_id: { type: "text" },
539
+ finding_key: { type: "text" },
540
+ occurrence: { type: "integer" },
541
+ finding: { type: "json" },
542
+ opened_at: { type: "timestamp" },
543
+ updated_at: { type: "timestamp" },
544
+ resolved_at: {
545
+ type: "timestamp",
546
+ nullable: true
547
+ }
548
+ },
549
+ uniqueIndexes: [{
550
+ name: "factory_supervisor_findings_project_key_unique",
551
+ columns: [
552
+ "org_id",
553
+ "factory_project_id",
554
+ "finding_key"
555
+ ]
556
+ }],
557
+ indexes: [{
558
+ name: "factory_supervisor_findings_project_open_idx",
559
+ columns: [
560
+ "org_id",
561
+ "factory_project_id",
562
+ "resolved_at",
563
+ "updated_at",
564
+ "id"
565
+ ]
566
+ }]
567
+ },
493
568
  {
494
569
  name: "factory_attention_receipts",
495
570
  columns: {
@@ -683,9 +758,22 @@ function toDeferredDecision(row) {
683
758
  };
684
759
  }
685
760
  function attentionReceiptKind(value) {
686
- if (value === "automation-failed" || value === "mention" || value === "activity") return value;
761
+ if (value === "automation-failed" || value === "automation-proposed" || value === "mention" || value === "activity" || value === "supervisor-finding") return value;
687
762
  throw new Error(`Unsupported attention receipt kind '${String(value)}'.`);
688
763
  }
764
+ function toSupervisorFinding(row) {
765
+ return {
766
+ id: row.id,
767
+ orgId: String(row.org_id),
768
+ factoryProjectId: String(row.factory_project_id),
769
+ findingKey: String(row.finding_key),
770
+ occurrence: Number(row.occurrence),
771
+ finding: row.finding,
772
+ openedAt: row.opened_at,
773
+ updatedAt: row.updated_at,
774
+ resolvedAt: row.resolved_at ?? null
775
+ };
776
+ }
689
777
  function attentionReceiptState(value) {
690
778
  if (value === "read" || value === "archived") return value;
691
779
  throw new Error(`Unsupported attention receipt state '${String(value)}'.`);
@@ -768,6 +856,86 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
768
856
  if (!count) throw new Error("[WorkItemsStorage] storage backend does not support collection counts.");
769
857
  return count.call(this.#db, collection, where);
770
858
  }
859
+ async syncSupervisorFindings(input) {
860
+ if (await this.#withProjectRelationTransaction(input.orgId, input.factoryProjectId, async (ops) => {
861
+ let changed = false;
862
+ const existingOpen = await ops.findMany("factory_supervisor_findings", {
863
+ org_id: input.orgId,
864
+ factory_project_id: input.factoryProjectId,
865
+ resolved_at: null
866
+ });
867
+ const currentKeys = new Set(input.findings.map((finding) => finding.id));
868
+ for (const row of existingOpen) if (!currentKeys.has(String(row.finding_key))) {
869
+ await ops.updateAtomic("factory_supervisor_findings", {
870
+ id: row.id,
871
+ resolved_at: null
872
+ }, () => ({
873
+ resolved_at: input.now,
874
+ updated_at: input.now
875
+ }));
876
+ changed = true;
877
+ }
878
+ const openByKey = new Map(existingOpen.map((row) => [String(row.finding_key), row]));
879
+ for (const finding of input.findings) {
880
+ const row = openByKey.get(finding.id) ?? await ops.findOne("factory_supervisor_findings", {
881
+ org_id: input.orgId,
882
+ factory_project_id: input.factoryProjectId,
883
+ finding_key: finding.id
884
+ });
885
+ if (!row) {
886
+ await ops.insertOne("factory_supervisor_findings", {
887
+ org_id: input.orgId,
888
+ factory_project_id: input.factoryProjectId,
889
+ finding_key: finding.id,
890
+ occurrence: 0,
891
+ finding,
892
+ opened_at: input.now,
893
+ updated_at: input.now,
894
+ resolved_at: null
895
+ });
896
+ changed = true;
897
+ continue;
898
+ }
899
+ const reopening = row.resolved_at !== null;
900
+ const findingChanged = stableJson(row.finding) !== stableJson(finding);
901
+ if (!reopening && !findingChanged) continue;
902
+ await ops.updateAtomic("factory_supervisor_findings", { id: row.id }, (current) => ({
903
+ finding,
904
+ occurrence: Number(current.occurrence) + (current.resolved_at !== null ? 1 : 0),
905
+ opened_at: current.resolved_at !== null ? input.now : current.opened_at,
906
+ updated_at: input.now,
907
+ resolved_at: null
908
+ }));
909
+ changed = true;
910
+ }
911
+ return changed;
912
+ })) this.#attentionChanged?.({
913
+ orgId: input.orgId,
914
+ factoryProjectId: input.factoryProjectId
915
+ });
916
+ }
917
+ async listSupervisorFindingPage(input) {
918
+ const rows = await this.#db.findMany("factory_supervisor_findings", {
919
+ org_id: input.orgId,
920
+ factory_project_id: input.factoryProjectId,
921
+ resolved_at: null
922
+ }, {
923
+ orderBy: [["updated_at", "desc"], ["id", "desc"]],
924
+ limit: input.limit + 1,
925
+ ...input.before ? { cursor: { values: [input.before.occurredAt, input.before.id] } } : {}
926
+ });
927
+ return {
928
+ rows: rows.slice(0, input.limit).map(toSupervisorFinding),
929
+ hasMore: rows.length > input.limit
930
+ };
931
+ }
932
+ async countOpenSupervisorFindings(input) {
933
+ return this.#countRows("factory_supervisor_findings", {
934
+ org_id: input.orgId,
935
+ factory_project_id: input.factoryProjectId,
936
+ resolved_at: null
937
+ });
938
+ }
771
939
  async #withProjectRelationTransaction(orgId, factoryProjectId, fn) {
772
940
  return withInProcessProjectLock(`work-items:${orgId}:${factoryProjectId}`, () => this.storage.withTransaction(fn, { isolationLevel: "serializable" }));
773
941
  }
@@ -1255,11 +1423,12 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
1255
1423
  hasMore: rows.length > input.limit
1256
1424
  };
1257
1425
  }
1258
- async listFailedDecisionPage(input) {
1426
+ /** Newest-parked-first keyset over one status, on the `updated_at` the status was stamped. */
1427
+ async listDecisionPageByStatus(input) {
1259
1428
  const rows = await this.#db.findMany("factory_deferred_decisions", {
1260
1429
  org_id: input.orgId,
1261
1430
  factory_project_id: input.factoryProjectId,
1262
- status: "failed"
1431
+ status: input.status
1263
1432
  }, {
1264
1433
  orderBy: [["updated_at", "desc"], ["id", "desc"]],
1265
1434
  limit: input.limit + 1,
@@ -1353,6 +1522,18 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
1353
1522
  });
1354
1523
  return Boolean(decision) && currentOccurrence;
1355
1524
  }
1525
+ if (identity.kind === "automation-proposed") {
1526
+ let parked = false;
1527
+ const decision = await ops.updateAtomic("factory_deferred_decisions", {
1528
+ id: identity.sourceId,
1529
+ org_id: orgId,
1530
+ factory_project_id: factoryProjectId
1531
+ }, (current) => {
1532
+ parked = current.status === "proposed" && identity.occurrence === 0;
1533
+ return null;
1534
+ });
1535
+ return Boolean(decision) && parked;
1536
+ }
1356
1537
  if (identity.kind === "activity") return await ops.findOne("work_item_activity", {
1357
1538
  work_item_id: identity.sourceId,
1358
1539
  participant_id: userId,
@@ -1360,6 +1541,13 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
1360
1541
  factory_project_id: factoryProjectId,
1361
1542
  occurrence: identity.occurrence
1362
1543
  }) !== null;
1544
+ if (identity.kind === "supervisor-finding") return await ops.findOne("factory_supervisor_findings", {
1545
+ org_id: orgId,
1546
+ factory_project_id: factoryProjectId,
1547
+ finding_key: identity.sourceId,
1548
+ occurrence: identity.occurrence,
1549
+ resolved_at: null
1550
+ }) !== null;
1363
1551
  if (identity.occurrence !== 0) return false;
1364
1552
  if (!await ops.findOne("work_item_comment_mentions", {
1365
1553
  comment_id: identity.sourceId,
@@ -1497,6 +1685,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
1497
1685
  });
1498
1686
  if (!settled || !row) return null;
1499
1687
  const record = toDeferredDecision(row);
1688
+ await ops.deleteMany("factory_attention_receipts", proposalReceiptFilter(orgId, factoryProjectId, decisionId));
1500
1689
  if (record.workItemId) await ops.updateAtomic("work_items", {
1501
1690
  org_id: orgId,
1502
1691
  id: record.workItemId
@@ -1553,20 +1742,23 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
1553
1742
  return superseded;
1554
1743
  }
1555
1744
  async #settleProposedDecision({ orgId, factoryProjectId, decisionId }, patch) {
1556
- let settled = false;
1557
- const row = await this.#db.updateAtomic("factory_deferred_decisions", {
1558
- id: decisionId,
1559
- org_id: orgId,
1560
- factory_project_id: factoryProjectId
1561
- }, (current) => {
1562
- if (current.status !== "proposed") return null;
1563
- settled = true;
1564
- return patch;
1745
+ const settled = await this.storage.withTransaction(async (ops) => {
1746
+ let updated = false;
1747
+ const row = await ops.updateAtomic("factory_deferred_decisions", {
1748
+ id: decisionId,
1749
+ org_id: orgId,
1750
+ factory_project_id: factoryProjectId
1751
+ }, (current) => {
1752
+ if (current.status !== "proposed") return null;
1753
+ updated = true;
1754
+ return patch;
1755
+ });
1756
+ if (!updated || !row) return null;
1757
+ await ops.deleteMany("factory_attention_receipts", proposalReceiptFilter(orgId, factoryProjectId, decisionId));
1758
+ return toDeferredDecision(row);
1565
1759
  });
1566
- if (!settled || !row) return null;
1567
- const record = toDeferredDecision(row);
1568
- this.#attentionChanged(record);
1569
- return record;
1760
+ if (settled) this.#attentionChanged(settled);
1761
+ return settled;
1570
1762
  }
1571
1763
  async #resolveFailedDecision({ orgId, factoryProjectId, decisionId, status, now }) {
1572
1764
  const resolved = await this.storage.withTransaction(async (ops) => {
@@ -1886,6 +2078,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
1886
2078
  org_id: input.orgId,
1887
2079
  created_by: input.userId,
1888
2080
  factory_project_id: input.factoryProjectId,
2081
+ board: create.board ?? null,
1889
2082
  external_source: create.externalSource ?? null,
1890
2083
  source_key: externalSourceKey(create.externalSource),
1891
2084
  parent_work_item_id: create.parentWorkItemId ?? null,
@@ -1900,14 +2093,6 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
1900
2093
  });
1901
2094
  item = toRow(row);
1902
2095
  }
1903
- if (input.armAutonomy && !item.autonomyArmedAt) {
1904
- const armedRow = await ops.updateAtomic("work_items", { id: item.id }, (current) => current.autonomy_armed_at ? null : { autonomy_armed_at: now });
1905
- if (armedRow) item = toRow(armedRow);
1906
- }
1907
- if (input.preapprovePlans && !item.plansPreapprovedAt) {
1908
- const grantedRow = await ops.updateAtomic("work_items", { id: item.id }, (current) => current.plans_preapproved_at ? null : { plans_preapproved_at: now });
1909
- if (grantedRow) item = toRow(grantedRow);
1910
- }
1911
2096
  await ops.updateMany("factory_run_bindings", {
1912
2097
  org_id: input.orgId,
1913
2098
  factory_project_id: input.factoryProjectId,
@@ -2034,6 +2219,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
2034
2219
  } : fullPatch;
2035
2220
  if (patch.parentWorkItemId !== void 0) validateParentRelation(await this.#listWithOps(ops, orgId, factoryProjectId), current.id, patch.parentWorkItemId);
2036
2221
  return {
2222
+ board: reuseMode === "non-stage" ? current.board : input.board ?? current.board ?? null,
2037
2223
  external_source: input.externalSource ?? null,
2038
2224
  ...applyUpdate({
2039
2225
  current,
@@ -2057,6 +2243,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
2057
2243
  item: toWorkItem(await ops.insertOne("work_items", {
2058
2244
  org_id: orgId,
2059
2245
  factory_project_id: factoryProjectId,
2246
+ board: input.board ?? null,
2060
2247
  external_source: input.externalSource ?? null,
2061
2248
  source_key: key,
2062
2249
  parent_work_item_id: input.parentWorkItemId ?? null,
@@ -2100,7 +2287,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
2100
2287
  return row ? toWorkItem(row) : null;
2101
2288
  });
2102
2289
  }
2103
- async update({ orgId, id, userId, patch }) {
2290
+ async update({ orgId, id, userId, patch, expectedRevision, expectedBoard }) {
2104
2291
  const run = async (ops) => {
2105
2292
  let previous = emptyPrior();
2106
2293
  const row = await ops.updateAtomic("work_items", {
@@ -2108,6 +2295,8 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
2108
2295
  id
2109
2296
  }, async (current) => {
2110
2297
  previous = priorState(current);
2298
+ if (expectedBoard !== void 0 && current.board !== expectedBoard) throw new WorkItemUpdateConflictError("board");
2299
+ if (expectedRevision !== void 0 && current.revision !== expectedRevision) throw new WorkItemUpdateConflictError("revision");
2111
2300
  if (patch.parentWorkItemId !== void 0) validateParentRelation(await this.#listWithOps(ops, orgId, current.factory_project_id), current.id, patch.parentWorkItemId);
2112
2301
  return applyUpdate({
2113
2302
  current,
@@ -2129,18 +2318,6 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
2129
2318
  return this.#withProjectRelationTransaction(orgId, candidate.factory_project_id, run);
2130
2319
  }
2131
2320
  /**
2132
- * Record that a person committed this item to the Factory. Only the first
2133
- * time counts: the timestamp marks when the item stopped needing permission,
2134
- * so later runs must not push it forward. Bumps no revision, because arming
2135
- * is not a change anyone is editing against.
2136
- */
2137
- async armAutonomy({ orgId, id, now }) {
2138
- await this.#db.updateAtomic("work_items", {
2139
- org_id: orgId,
2140
- id
2141
- }, (current) => current.autonomy_armed_at ? null : { autonomy_armed_at: now });
2142
- }
2143
- /**
2144
2321
  * Drop the governance rows that materialized a source key so a deleted work item
2145
2322
  * is not resurrected by the prior-ingress replay path on the next intake poll.
2146
2323
  */
@@ -2247,6 +2424,6 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
2247
2424
  }
2248
2425
  };
2249
2426
  //#endregion
2250
- export { FACTORY_PULL_REQUEST_RECONCILIATION_KEY, FACTORY_RULE_MATERIALIZATION_KEY, WORK_ITEMS_SCHEMA, WorkItemRelationError, WorkItemsStorage, applyStageTransition, externalSourceKey, factoryActivityAttentionIdentity, factoryAttentionKey, factoryDecisionAttentionIdentity, factoryDecisionHash, factoryMentionAttentionIdentity, isAgentActor, stampSessions, validateParentRelation };
2427
+ export { FACTORY_PULL_REQUEST_RECONCILIATION_KEY, FACTORY_RULE_MATERIALIZATION_KEY, WORK_ITEMS_SCHEMA, WorkItemRelationError, WorkItemUpdateConflictError, WorkItemsStorage, applyStageTransition, externalSourceKey, factoryActivityAttentionIdentity, factoryAttentionKey, factoryDecisionAttentionIdentity, factoryDecisionHash, factoryMentionAttentionIdentity, factoryProposalAttentionIdentity, factorySupervisorFindingAttentionIdentity, isAgentActor, stampSessions, validateParentRelation };
2251
2428
 
2252
2429
  //# sourceMappingURL=base.js.map