@usine/engine 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/README.md +109 -36
  2. package/dist/board-moves/board-moves.d.ts +20 -0
  3. package/dist/board-moves/board-moves.d.ts.map +1 -0
  4. package/dist/board-moves/board-moves.js +74 -0
  5. package/dist/board-moves/board-moves.js.map +1 -0
  6. package/dist/board-moves/model.d.ts +21 -0
  7. package/dist/board-moves/model.d.ts.map +1 -0
  8. package/dist/board-moves/model.js +22 -0
  9. package/dist/board-moves/model.js.map +1 -0
  10. package/dist/cursor/cursor.d.ts +2 -6
  11. package/dist/cursor/cursor.d.ts.map +1 -1
  12. package/dist/cursor/cursor.js +2 -6
  13. package/dist/cursor/cursor.js.map +1 -1
  14. package/dist/cycle-budget/cycle-budget.d.ts +6 -6
  15. package/dist/cycle-budget/cycle-budget.d.ts.map +1 -1
  16. package/dist/cycle-budget/cycle-budget.js +5 -5
  17. package/dist/cycle-budget/cycle-budget.js.map +1 -1
  18. package/dist/cycle-budget/model.d.ts +2 -2
  19. package/dist/cycle-budget/model.d.ts.map +1 -1
  20. package/dist/cycle-budget/model.js +2 -2
  21. package/dist/cycle-budget/model.js.map +1 -1
  22. package/dist/cycle-budget/queries.d.ts +1 -1
  23. package/dist/cycle-budget/queries.d.ts.map +1 -1
  24. package/dist/cycle-budget/queries.js +3 -3
  25. package/dist/cycle-budget/queries.js.map +1 -1
  26. package/dist/database/database.d.ts +1 -1
  27. package/dist/database/database.d.ts.map +1 -1
  28. package/dist/database/local-sqlite.d.ts +10 -8
  29. package/dist/database/local-sqlite.d.ts.map +1 -1
  30. package/dist/database/local-sqlite.js +16 -9
  31. package/dist/database/local-sqlite.js.map +1 -1
  32. package/dist/database/schema.d.ts +581 -22
  33. package/dist/database/schema.d.ts.map +1 -1
  34. package/dist/database/schema.js +104 -23
  35. package/dist/database/schema.js.map +1 -1
  36. package/dist/{workflow → engine}/admission.d.ts +2 -2
  37. package/dist/engine/admission.d.ts.map +1 -0
  38. package/dist/{workflow → engine}/admission.js +4 -4
  39. package/dist/engine/admission.js.map +1 -0
  40. package/dist/engine/checkout-recovery.d.ts +69 -0
  41. package/dist/engine/checkout-recovery.d.ts.map +1 -0
  42. package/dist/engine/checkout-recovery.js +181 -0
  43. package/dist/engine/checkout-recovery.js.map +1 -0
  44. package/dist/engine/engine.d.ts +57 -24
  45. package/dist/engine/engine.d.ts.map +1 -1
  46. package/dist/engine/engine.js +144 -120
  47. package/dist/engine/engine.js.map +1 -1
  48. package/dist/engine/error.d.ts +36 -9
  49. package/dist/engine/error.d.ts.map +1 -1
  50. package/dist/engine/error.js +35 -7
  51. package/dist/engine/error.js.map +1 -1
  52. package/dist/engine/lifecycle.d.ts +81 -28
  53. package/dist/engine/lifecycle.d.ts.map +1 -1
  54. package/dist/engine/lifecycle.js +83 -44
  55. package/dist/engine/lifecycle.js.map +1 -1
  56. package/dist/engine/retry.d.ts +16 -0
  57. package/dist/engine/retry.d.ts.map +1 -0
  58. package/dist/engine/retry.js +18 -0
  59. package/dist/engine/retry.js.map +1 -0
  60. package/dist/engine/run-again.d.ts +45 -0
  61. package/dist/engine/run-again.d.ts.map +1 -0
  62. package/dist/engine/run-again.js +56 -0
  63. package/dist/engine/run-again.js.map +1 -0
  64. package/dist/engine/run-driver.d.ts +54 -0
  65. package/dist/engine/run-driver.d.ts.map +1 -0
  66. package/dist/engine/run-driver.js +362 -0
  67. package/dist/engine/run-driver.js.map +1 -0
  68. package/dist/engine/shutdown.d.ts +3 -4
  69. package/dist/engine/shutdown.d.ts.map +1 -1
  70. package/dist/engine/shutdown.js +3 -4
  71. package/dist/engine/shutdown.js.map +1 -1
  72. package/dist/engine/submission.d.ts +31 -11
  73. package/dist/engine/submission.d.ts.map +1 -1
  74. package/dist/engine/submission.js +42 -12
  75. package/dist/engine/submission.js.map +1 -1
  76. package/dist/item-projection/item-projection.d.ts +12 -4
  77. package/dist/item-projection/item-projection.d.ts.map +1 -1
  78. package/dist/item-projection/item-projection.js +41 -6
  79. package/dist/item-projection/item-projection.js.map +1 -1
  80. package/dist/item-projection/model.d.ts +5 -1
  81. package/dist/item-projection/model.d.ts.map +1 -1
  82. package/dist/item-projection/model.js +6 -2
  83. package/dist/item-projection/model.js.map +1 -1
  84. package/dist/loop-control/loop-control.d.ts +5 -5
  85. package/dist/loop-control/loop-control.d.ts.map +1 -1
  86. package/dist/loop-control/loop-control.js +4 -4
  87. package/dist/loop-control/loop-control.js.map +1 -1
  88. package/dist/loop-control/model.d.ts +1 -1
  89. package/dist/loop-control/model.d.ts.map +1 -1
  90. package/dist/loop-control/model.js +1 -1
  91. package/dist/loop-control/model.js.map +1 -1
  92. package/dist/repository-label-projection/model.d.ts +2 -2
  93. package/dist/repository-label-projection/model.d.ts.map +1 -1
  94. package/dist/repository-label-projection/model.js +2 -2
  95. package/dist/repository-label-projection/model.js.map +1 -1
  96. package/dist/repository-label-projection/repository-label-projection.d.ts +1 -1
  97. package/dist/repository-label-projection/repository-label-projection.d.ts.map +1 -1
  98. package/dist/repository-label-projection/repository-label-projection.js +1 -1
  99. package/dist/repository-label-projection/repository-label-projection.js.map +1 -1
  100. package/dist/run-reader/model.d.ts +62 -4
  101. package/dist/run-reader/model.d.ts.map +1 -1
  102. package/dist/run-reader/model.js +66 -7
  103. package/dist/run-reader/model.js.map +1 -1
  104. package/dist/run-reader/run-reader.d.ts +19 -9
  105. package/dist/run-reader/run-reader.d.ts.map +1 -1
  106. package/dist/run-reader/run-reader.js +23 -7
  107. package/dist/run-reader/run-reader.js.map +1 -1
  108. package/dist/step-executor.d.ts +65 -9
  109. package/dist/step-executor.d.ts.map +1 -1
  110. package/dist/step-executor.js +10 -2
  111. package/dist/step-executor.js.map +1 -1
  112. package/dist/store/attempt-windows.d.ts +8 -0
  113. package/dist/store/attempt-windows.d.ts.map +1 -0
  114. package/dist/store/attempt-windows.js +53 -0
  115. package/dist/store/attempt-windows.js.map +1 -0
  116. package/dist/store/codec.d.ts +381 -42
  117. package/dist/store/codec.d.ts.map +1 -1
  118. package/dist/store/codec.js +59 -15
  119. package/dist/store/codec.js.map +1 -1
  120. package/dist/store/leftovers.d.ts +10 -0
  121. package/dist/store/leftovers.d.ts.map +1 -0
  122. package/dist/store/leftovers.js +43 -0
  123. package/dist/store/leftovers.js.map +1 -0
  124. package/dist/store/loop-items.d.ts +16 -0
  125. package/dist/store/loop-items.d.ts.map +1 -0
  126. package/dist/store/loop-items.js +185 -0
  127. package/dist/store/loop-items.js.map +1 -0
  128. package/dist/store/queries.d.ts +345 -37
  129. package/dist/store/queries.d.ts.map +1 -1
  130. package/dist/store/queries.js +333 -160
  131. package/dist/store/queries.js.map +1 -1
  132. package/dist/store/store.d.ts +91 -54
  133. package/dist/store/store.d.ts.map +1 -1
  134. package/dist/store/store.js +481 -190
  135. package/dist/store/store.js.map +1 -1
  136. package/dist/store/transcript.d.ts +9 -0
  137. package/dist/store/transcript.d.ts.map +1 -0
  138. package/dist/store/transcript.js +90 -0
  139. package/dist/store/transcript.js.map +1 -0
  140. package/dist/transcript.d.ts +41 -20
  141. package/dist/transcript.d.ts.map +1 -1
  142. package/dist/transcript.js +45 -25
  143. package/dist/transcript.js.map +1 -1
  144. package/dist/trigger-condition.d.ts +23 -0
  145. package/dist/trigger-condition.d.ts.map +1 -0
  146. package/dist/trigger-condition.js +8 -0
  147. package/dist/trigger-condition.js.map +1 -0
  148. package/drizzle/20260912111855_operator_intervention/migration.sql +42 -0
  149. package/drizzle/20260912111855_operator_intervention/snapshot.json +1461 -0
  150. package/drizzle/20260917071139_resolve_run_failure/migration.sql +1 -0
  151. package/drizzle/20260917071139_resolve_run_failure/snapshot.json +1471 -0
  152. package/drizzle/20260918032643_attempt_salvage/migration.sql +1 -0
  153. package/drizzle/20260918032643_attempt_salvage/snapshot.json +1481 -0
  154. package/drizzle/20261011153856_drop_workflow_tables/migration.sql +4 -0
  155. package/drizzle/20261011153856_drop_workflow_tables/snapshot.json +1433 -0
  156. package/drizzle/20261017155043_attempt_salvage_check/migration.sql +41 -0
  157. package/drizzle/20261017155043_attempt_salvage_check/snapshot.json +1421 -0
  158. package/drizzle/20261018162700_discard_attempt_leftovers/migration.sql +1 -0
  159. package/drizzle/20261018162700_discard_attempt_leftovers/snapshot.json +1431 -0
  160. package/drizzle/20261018172605_loop_items_and_reopenings/migration.sql +15 -0
  161. package/drizzle/20261018172605_loop_items_and_reopenings/snapshot.json +1574 -0
  162. package/drizzle/20261018180339_attempt_ended_at/migration.sql +1 -0
  163. package/drizzle/20261018180339_attempt_ended_at/snapshot.json +1584 -0
  164. package/drizzle/20261019104043_run_approval_source/migration.sql +15 -0
  165. package/drizzle/20261019104043_run_approval_source/snapshot.json +1610 -0
  166. package/drizzle/20261019133538_board_moves/migration.sql +14 -0
  167. package/drizzle/20261019133538_board_moves/snapshot.json +1731 -0
  168. package/drizzle/20261019170538_item_projection_gone/migration.sql +1 -0
  169. package/drizzle/20261019170538_item_projection_gone/snapshot.json +1741 -0
  170. package/drizzle/20261019180649_run_again_events/migration.sql +7 -0
  171. package/drizzle/20261019180649_run_again_events/snapshot.json +1804 -0
  172. package/drizzle/20261019185008_trigger_event_permissions/migration.sql +1 -0
  173. package/drizzle/20261019185008_trigger_event_permissions/snapshot.json +1814 -0
  174. package/drizzle/20261020103746_attempt_start/migration.sql +5 -0
  175. package/drizzle/20261020103746_attempt_start/snapshot.json +1844 -0
  176. package/drizzle/20261020125211_attempt_comments/migration.sql +1 -0
  177. package/drizzle/20261020125211_attempt_comments/snapshot.json +1854 -0
  178. package/drizzle/20261020191320_run_closed_at/migration.sql +6 -0
  179. package/drizzle/20261020191320_run_closed_at/snapshot.json +1864 -0
  180. package/drizzle/20261023091428_rename_loop_item_hold_to_suppression/migration.sql +2 -0
  181. package/drizzle/20261023091428_rename_loop_item_hold_to_suppression/snapshot.json +1867 -0
  182. package/package.json +15 -5
  183. package/dist/workflow/admission.d.ts.map +0 -1
  184. package/dist/workflow/admission.js.map +0 -1
  185. package/dist/workflow/command.d.ts +0 -13
  186. package/dist/workflow/command.d.ts.map +0 -1
  187. package/dist/workflow/command.js +0 -17
  188. package/dist/workflow/command.js.map +0 -1
  189. package/dist/workflow/workflow.d.ts +0 -18
  190. package/dist/workflow/workflow.d.ts.map +0 -1
  191. package/dist/workflow/workflow.js +0 -108
  192. package/dist/workflow/workflow.js.map +0 -1
@@ -1,16 +1,18 @@
1
1
  import { Agent } from "@usine/core/agent";
2
2
  import { CycleBudgetAsk } from "@usine/core/cycle-budget";
3
- import { Event } from "@usine/core/event";
4
- import { Schema } from "effect";
3
+ import { DedupKey, Event } from "@usine/core/event";
4
+ import { Crypto, Effect, Schema } from "effect";
5
5
  declare const Submission_base: Schema.Class<Submission, Schema.Struct<{
6
6
  readonly event: typeof Event;
7
7
  readonly itemKey: Schema.brand<Schema.NonEmptyString, "ItemKey">;
8
8
  readonly loop: Schema.brand<Schema.NonEmptyString, "LoopName">;
9
9
  readonly step: Schema.brand<Schema.NonEmptyString, "StepName">;
10
10
  readonly approval: Schema.Literals<readonly ["none", "required"]>;
11
- /** Item Runs default to three rounds; schedule adapters explicitly supply None. */
11
+ /** The repository access of the Run's Attempts, from the Loop at match time. */
12
+ readonly permissions: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.Literals<readonly ["write", "read"]>, never>>;
13
+ /** The cycle limit; schedule triggers set `None`. */
12
14
  readonly cycleLimit: Schema.withConstructorDefault<Schema.withDecodingDefaultTypeKey<Schema.Option<Schema.brand<Schema.Int, "CycleLimit">>, never>>;
13
- /** Capture before fetching trigger input. A reset supersedes older observations. */
15
+ /** The Item's cycle generation, read before fetching trigger input. */
14
16
  readonly cycleGeneration: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.brand<Schema.Int, "CycleGeneration">, never>>;
15
17
  readonly repository: Schema.brand<Schema.String, "RepositoryName">;
16
18
  readonly revision: Schema.brand<Schema.String, "RepositoryRevision">;
@@ -18,20 +20,28 @@ declare const Submission_base: Schema.Class<Submission, Schema.Struct<{
18
20
  readonly agent: typeof Agent;
19
21
  readonly parentModel: Schema.Option<Schema.brand<Schema.String, "ModelId">>;
20
22
  }>, {}>;
21
- /** A matched Event with the Loop, Item, and execution choices that determine the work owed. */
23
+ /** A matched Event with its Loop, Item, and Run settings. */
22
24
  export declare class Submission extends Submission_base {
23
25
  }
26
+ /** Returns the Run ID for the Submission's Event: the first 16 bytes, in hex, of the SHA-256 of its namespaced dedup key. */
27
+ export declare const runIdFor: (submission: Submission) => Effect.Effect<string & import("effect/Brand").Brand<"RunId">, never, Crypto.Crypto>;
28
+ /**
29
+ * Returns the Submission recorded when the Item returns to the state of an Event whose Run was
30
+ * canceled. Its dedup key combines the original key and the reopening number, so the new Run
31
+ * gets its own ID (#267).
32
+ */
33
+ export declare const reopeningOf: (submission: Submission, original: DedupKey, reopening: number) => Submission;
24
34
  declare const Claimed_base: Schema.Class<Claimed, Schema.TaggedStruct<"Claimed", {
25
35
  readonly eventId: Schema.brand<Schema.NonEmptyString, "EventId">;
26
36
  readonly runId: Schema.brand<Schema.NonEmptyString, "RunId">;
27
37
  }>, {}>;
28
- /** The Event now owns a Run; submitting it again returns the same run id. */
38
+ /** A result for an Event that has a Run; submitting it again returns the same Run ID. */
29
39
  export declare class Claimed extends Claimed_base {
30
40
  }
31
41
  declare const Queued_base: Schema.Class<Queued, Schema.TaggedStruct<"Queued", {
32
42
  readonly eventId: Schema.brand<Schema.NonEmptyString, "EventId">;
33
43
  }>, {}>;
34
- /** A running Attempt on the same Item must finish before this Event is reconsidered. */
44
+ /** A result for an Event that waits until a running Attempt on the same Item finishes. */
35
45
  export declare class Queued extends Queued_base {
36
46
  }
37
47
  export declare const IGNORED_REASONS: readonly ["superseded", "revoked"];
@@ -41,18 +51,28 @@ declare const Ignored_base: Schema.Class<Ignored, Schema.TaggedStruct<"Ignored",
41
51
  readonly eventId: Schema.brand<Schema.NonEmptyString, "EventId">;
42
52
  readonly reason: Schema.Literals<readonly ["superseded", "revoked"]>;
43
53
  }>, {}>;
44
- /** The Event stays in the ledger but can no longer open a Run. */
54
+ /** A result for an Event that is recorded but can't open a Run. */
45
55
  export declare class Ignored extends Ignored_base {
46
56
  }
57
+ declare const Suppressed_base: Schema.Class<Suppressed, Schema.TaggedStruct<"Suppressed", {
58
+ readonly eventId: Schema.brand<Schema.NonEmptyString, "EventId">;
59
+ readonly runId: Schema.brand<Schema.NonEmptyString, "RunId">;
60
+ }>, {}>;
61
+ /**
62
+ * A result for an Event that waits because the Agent of `runId` stopped with a question or
63
+ * blocker. It opens a Run once the operator resolves the stop, or a later Event replaces it when
64
+ * the Item changes (#241, #341).
65
+ */
66
+ export declare class Suppressed extends Suppressed_base {
67
+ }
47
68
  declare const CycleBlocked_base: Schema.Class<CycleBlocked, Schema.TaggedStruct<"CycleBlocked", {
48
69
  readonly eventId: Schema.brand<Schema.NonEmptyString, "EventId">;
49
70
  readonly ask: typeof CycleBudgetAsk;
50
71
  }>, {}>;
51
- /** No Run opened because this Item requires an explicit cycle-budget reset. */
72
+ /** A result for an Event that opened no Run because the Item needs a cycle-budget reset. */
52
73
  export declare class CycleBlocked extends CycleBlocked_base {
53
74
  }
54
- /** Whether a recorded Event owns a Run, waits behind running work, or can no longer open a Run. */
55
- export declare const SubmissionResult: Schema.Union<readonly [typeof Claimed, typeof Queued, typeof Ignored, typeof CycleBlocked]>;
75
+ export declare const SubmissionResult: Schema.Union<readonly [typeof Claimed, typeof Queued, typeof Suppressed, typeof Ignored, typeof CycleBlocked]>;
56
76
  export type SubmissionResult = typeof SubmissionResult.Type;
57
77
  export {};
58
78
  //# sourceMappingURL=submission.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../../src/engine/submission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EACL,cAAc,EAIf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,KAAK,EAAW,MAAM,mBAAmB,CAAC;AAMnD,OAAO,EAAkB,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;;;IAS9C,mFAAmF;;IAKnF,oFAAoF;;;;;;;;AAZtF,+FAA+F;AAC/F,qBAAa,UAAW,SAAQ,eAqB9B;CAAG;;;;;AAEL,6EAA6E;AAC7E,qBAAa,OAAQ,SAAQ,YAG3B;CAAG;;;;AAEL,wFAAwF;AACxF,qBAAa,MAAO,SAAQ,WAE1B;CAAG;AAEL,eAAO,MAAM,eAAe,YAAI,YAAY,EAAE,SAAS,CAAU,CAAC;AAElE,eAAO,MAAM,YAAY,qDAAmC,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAC;;;;;AAEpD,kEAAkE;AAClE,qBAAa,OAAQ,SAAQ,YAG3B;CAAG;;;;;AAEL,+EAA+E;AAC/E,qBAAa,YAAa,SAAQ,iBAGjC;CAAG;AAEJ,mGAAmG;AACnG,eAAO,MAAM,gBAAgB,6FAAyD,CAAC;AAEvF,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAC"}
1
+ {"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../../src/engine/submission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EACL,cAAc,EAIf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAW,MAAM,mBAAmB,CAAC;AAM7D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAoB,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;;;IAShE,gFAAgF;;IAKhF,qDAAqD;;IAKrD,uEAAuE;;;;;;;;AAjBzE,6DAA6D;AAC7D,qBAAa,UAAW,SAAQ,eA0B9B;CAAG;AAKL,6HAA6H;AAC7H,eAAO,MAAM,QAAQ,iHAMnB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,eACV,UAAU,YACZ,QAAQ,aACP,MAAM,KAChB,UAMF,CAAC;;;;;AAEF,yFAAyF;AACzF,qBAAa,OAAQ,SAAQ,YAG3B;CAAG;;;;AAEL,0FAA0F;AAC1F,qBAAa,MAAO,SAAQ,WAE1B;CAAG;AAEL,eAAO,MAAM,eAAe,YAAI,YAAY,EAAE,SAAS,CAAU,CAAC;AAElE,eAAO,MAAM,YAAY,qDAAmC,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAC;;;;;AAEpD,mEAAmE;AACnE,qBAAa,OAAQ,SAAQ,YAG3B;CAAG;;;;;AAEL;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,eAG/B;CAAG;;;;;AAEJ,4FAA4F;AAC5F,qBAAa,YAAa,SAAQ,iBAGjC;CAAG;AAEJ,eAAO,MAAM,gBAAgB,gHAAqE,CAAC;AAEnG,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAC"}
@@ -2,23 +2,25 @@ import { Agent } from "@usine/core/agent";
2
2
  import { CycleBudgetAsk, CycleGeneration, CycleLimit, DEFAULT_CYCLE_LIMIT, } from "@usine/core/cycle-budget";
3
3
  import { ModelId } from "@usine/core/agent/brain";
4
4
  import { AttemptTask } from "@usine/core/attempt";
5
- import { Event, EventId } from "@usine/core/event";
5
+ import { DedupKey, Event, EventId } from "@usine/core/event";
6
6
  import { ItemKey } from "@usine/core/item";
7
- import { LoopName, ApprovalRequirement } from "@usine/core/loop";
7
+ import { LoopName, ApprovalRequirement, LoopPermissions } from "@usine/core/loop";
8
8
  import { RepositoryName, RepositoryRevision } from "@usine/core/repository";
9
9
  import { RunId } from "@usine/core/run";
10
10
  import { StepName } from "@usine/core/step";
11
- import { Effect, Option, Schema } from "effect";
12
- /** A matched Event with the Loop, Item, and execution choices that determine the work owed. */
11
+ import { Crypto, Effect, Encoding, Option, Schema } from "effect";
12
+ /** A matched Event with its Loop, Item, and Run settings. */
13
13
  export class Submission extends Schema.Class("@usine/engine/Submission")({
14
14
  event: Event,
15
15
  itemKey: ItemKey,
16
16
  loop: LoopName,
17
17
  step: StepName,
18
18
  approval: ApprovalRequirement,
19
- /** Item Runs default to three rounds; schedule adapters explicitly supply None. */
19
+ /** The repository access of the Run's Attempts, from the Loop at match time. */
20
+ permissions: LoopPermissions.pipe(Schema.withDecodingDefaultKey(Effect.succeed("write")), Schema.withConstructorDefault(Effect.succeed("write"))),
21
+ /** The cycle limit; schedule triggers set `None`. */
20
22
  cycleLimit: Schema.Option(CycleLimit).pipe(Schema.withDecodingDefaultTypeKey(Effect.succeed(Option.some(DEFAULT_CYCLE_LIMIT))), Schema.withConstructorDefault(Effect.succeed(Option.some(DEFAULT_CYCLE_LIMIT)))),
21
- /** Capture before fetching trigger input. A reset supersedes older observations. */
23
+ /** The Item's cycle generation, read before fetching trigger input. */
22
24
  cycleGeneration: CycleGeneration.pipe(Schema.withDecodingDefaultKey(Effect.succeed(CycleGeneration.make(0))), Schema.withConstructorDefault(Effect.succeed(CycleGeneration.make(0)))),
23
25
  repository: RepositoryName,
24
26
  revision: RepositoryRevision,
@@ -27,28 +29,56 @@ export class Submission extends Schema.Class("@usine/engine/Submission")({
27
29
  parentModel: Schema.Option(ModelId),
28
30
  }) {
29
31
  }
30
- /** The Event now owns a Run; submitting it again returns the same run id. */
32
+ // Older Runs used this Effect workflow execution ID; hashing the same input keeps Run IDs stable.
33
+ const RUN_ID_NAMESPACE = "@usine/engine/DurableRun";
34
+ /** Returns the Run ID for the Submission's Event: the first 16 bytes, in hex, of the SHA-256 of its namespaced dedup key. */
35
+ export const runIdFor = Effect.fn("Submission.runIdFor")(function* (submission) {
36
+ const crypto = yield* Crypto.Crypto;
37
+ const digest = yield* crypto
38
+ .digest("SHA-256", new TextEncoder().encode(`${RUN_ID_NAMESPACE}-${submission.event.dedupKey}`))
39
+ .pipe(Effect.orDie);
40
+ return RunId.make(Encoding.encodeHex(digest.subarray(0, 16)));
41
+ });
42
+ /**
43
+ * Returns the Submission recorded when the Item returns to the state of an Event whose Run was
44
+ * canceled. Its dedup key combines the original key and the reopening number, so the new Run
45
+ * gets its own ID (#267).
46
+ */
47
+ export const reopeningOf = (submission, original, reopening) => {
48
+ const dedupKey = DedupKey.make(JSON.stringify(["reopened", reopening, original]));
49
+ return new Submission({
50
+ ...submission,
51
+ event: new Event({ ...submission.event, id: EventId.make(dedupKey), dedupKey }),
52
+ });
53
+ };
54
+ /** A result for an Event that has a Run; submitting it again returns the same Run ID. */
31
55
  export class Claimed extends Schema.TaggedClass("@usine/engine/Claimed")("Claimed", {
32
56
  eventId: EventId,
33
57
  runId: RunId,
34
58
  }) {
35
59
  }
36
- /** A running Attempt on the same Item must finish before this Event is reconsidered. */
60
+ /** A result for an Event that waits until a running Attempt on the same Item finishes. */
37
61
  export class Queued extends Schema.TaggedClass("@usine/engine/Queued")("Queued", {
38
62
  eventId: EventId,
39
63
  }) {
40
64
  }
41
65
  export const IGNORED_REASONS = ["superseded", "revoked"];
42
66
  export const IgnoreReason = Schema.Literals(IGNORED_REASONS);
43
- /** The Event stays in the ledger but can no longer open a Run. */
67
+ /** A result for an Event that is recorded but can't open a Run. */
44
68
  export class Ignored extends Schema.TaggedClass("@usine/engine/Ignored")("Ignored", {
45
69
  eventId: EventId,
46
70
  reason: IgnoreReason,
47
71
  }) {
48
72
  }
49
- /** No Run opened because this Item requires an explicit cycle-budget reset. */
73
+ /**
74
+ * A result for an Event that waits because the Agent of `runId` stopped with a question or
75
+ * blocker. It opens a Run once the operator resolves the stop, or a later Event replaces it when
76
+ * the Item changes (#241, #341).
77
+ */
78
+ export class Suppressed extends Schema.TaggedClass("@usine/engine/Suppressed")("Suppressed", { eventId: EventId, runId: RunId }) {
79
+ }
80
+ /** A result for an Event that opened no Run because the Item needs a cycle-budget reset. */
50
81
  export class CycleBlocked extends Schema.TaggedClass("@usine/engine/CycleBlocked")("CycleBlocked", { eventId: EventId, ask: CycleBudgetAsk }) {
51
82
  }
52
- /** Whether a recorded Event owns a Run, waits behind running work, or can no longer open a Run. */
53
- export const SubmissionResult = Schema.Union([Claimed, Queued, Ignored, CycleBlocked]);
83
+ export const SubmissionResult = Schema.Union([Claimed, Queued, Suppressed, Ignored, CycleBlocked]);
54
84
  //# sourceMappingURL=submission.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"submission.js","sourceRoot":"","sources":["../../src/engine/submission.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"submission.js","sourceRoot":"","sources":["../../src/engine/submission.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,30 @@
1
+ import { type ItemKey, ItemNumber } from "@usine/core/item";
1
2
  import { RepositoryName } from "@usine/core/repository";
2
- import { Context, Effect, Layer } from "effect";
3
+ import { Context, DateTime, Effect, Layer } from "effect";
3
4
  import { RunDatabase } from "../database/database.ts";
4
5
  import { EnginePersistenceError } from "../engine/error.ts";
5
6
  import { ItemProjection } from "./model.ts";
6
- /** Newest Items first. The bound keeps a long-lived repository's Board response finite. */
7
+ /** The options for listing Item projections, newest first. */
7
8
  export interface ItemProjectionListOptions {
8
9
  readonly limit: number;
9
10
  }
10
11
  declare const ItemProjectionReader_base: Context.ServiceClass<ItemProjectionReader, "@usine/engine/ItemProjectionReader", {
11
- /** The newest `limit` Item projections of one repository, highest number first. */
12
+ /** Returns the newest `limit` Item projections of `repository`, highest number first. */
12
13
  readonly list: (repository: RepositoryName, options: ItemProjectionListOptions) => Effect.Effect<ReadonlyArray<ItemProjection>, EnginePersistenceError>;
14
+ /** Returns the numbers of `repository`'s open issues that aren't marked gone, lowest first, without a limit. */
15
+ readonly openIssues: (repository: RepositoryName) => Effect.Effect<ReadonlyArray<ItemNumber>, EnginePersistenceError>;
13
16
  }>;
14
17
  export declare class ItemProjectionReader extends ItemProjectionReader_base {
15
18
  static readonly layer: Layer.Layer<ItemProjectionReader, never, RunDatabase>;
16
19
  }
17
20
  declare const ItemProjectionWriter_base: Context.ServiceClass<ItemProjectionWriter, "@usine/engine/ItemProjectionWriter", {
18
- /** `true` means the durable projection changed. */
21
+ /** Stores `item`, clearing `goneAt` for an observed snapshot. Returns whether the stored projection changed. */
19
22
  readonly upsert: (item: ItemProjection) => Effect.Effect<boolean, EnginePersistenceError>;
23
+ /**
24
+ * Records that GitHub no longer has the Item, keeping its last payload. Returns whether a
25
+ * stored projection was marked; an Item already gone keeps its first `goneAt`.
26
+ */
27
+ readonly markGone: (itemKey: ItemKey, goneAt: DateTime.Utc) => Effect.Effect<boolean, EnginePersistenceError>;
20
28
  }>;
21
29
  export declare class ItemProjectionWriter extends ItemProjectionWriter_base {
22
30
  static readonly layer: Layer.Layer<ItemProjectionWriter, never, RunDatabase>;
@@ -1 +1 @@
1
- {"version":3,"file":"item-projection.d.ts","sourceRoot":"","sources":["../../src/item-projection/item-projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAmB,cAAc,EAAwB,MAAM,YAAY,CAAC;AAmBnF,2FAA2F;AAC3F,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;;IAqFG,mFAAmF;mBACpE,CACb,UAAU,EAAE,cAAc,EAC1B,OAAO,EAAE,yBAAyB,KAC/B,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,sBAAsB,CAAC;;AAP7E,qBAAa,oBAAqB,SAAQ,yBASD;IACvC,MAAM,CAAC,QAAQ,CAAC,KAAK,wDAAkD;CACxE;;IAKG,mDAAmD;qBAClC,CAAC,IAAI,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,sBAAsB,CAAC;;AAJ7F,qBAAa,oBAAqB,SAAQ,yBAMD;IACvC,MAAM,CAAC,QAAQ,CAAC,KAAK,wDAAkD;CACxE;AAED,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"item-projection.d.ts","sourceRoot":"","sources":["../../src/item-projection/item-projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAmB,cAAc,EAAwB,MAAM,YAAY,CAAC;AAsBnF,8DAA8D;AAC9D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;;IAiIG,yFAAyF;mBAC1E,CACb,UAAU,EAAE,cAAc,EAC1B,OAAO,EAAE,yBAAyB,KAC/B,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACzE,gHAAgH;yBAC3F,CACnB,UAAU,EAAE,cAAc,KACvB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,sBAAsB,CAAC;;AAXzE,qBAAa,oBAAqB,SAAQ,yBAaD;IACvC,MAAM,CAAC,QAAQ,CAAC,KAAK,wDAAkD;CACxE;;IAKG,gHAAgH;qBAC/F,CAAC,IAAI,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzF;;;OAGG;uBACgB,CACjB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,QAAQ,CAAC,GAAG,KACjB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,sBAAsB,CAAC;;AAZvD,qBAAa,oBAAqB,SAAQ,yBAcD;IACvC,MAAM,CAAC,QAAQ,CAAC,KAAK,wDAAkD;CACxE;AAED,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
@@ -1,10 +1,10 @@
1
+ import { ItemNumber } from "@usine/core/item";
1
2
  import { RepositoryName } from "@usine/core/repository";
2
- import { desc, eq, ne } from "drizzle-orm";
3
- import { Context, Effect, Layer, Schema } from "effect";
3
+ import { and, asc, desc, eq, isNull, sql } from "drizzle-orm";
4
+ import { Context, DateTime, Effect, Layer, Option, Schema } from "effect";
4
5
  import { RunDatabase } from "../database/database.js";
5
6
  import { itemProjections } from "../database/schema.js";
6
7
  import { EnginePersistenceError } from "../engine/error.js";
7
- import { ItemNumber } from "@usine/core/item";
8
8
  import { ItemContentHash, ItemProjection, ItemProjectionSource } from "./model.js";
9
9
  const ItemProjectionRow = Schema.Struct({
10
10
  itemKey: ItemProjection.fields.itemKey,
@@ -13,9 +13,12 @@ const ItemProjectionRow = Schema.Struct({
13
13
  number: ItemNumber,
14
14
  contentHash: ItemContentHash,
15
15
  payload: Schema.JsonObject,
16
+ goneAt: ItemProjection.fields.goneAt,
16
17
  });
17
18
  const decodeRows = Schema.decodeUnknownEffect(Schema.Array(ItemProjectionRow));
19
+ const decodeNumbers = Schema.decodeUnknownEffect(Schema.Array(ItemNumber));
18
20
  const encodePayload = Schema.encodeSync(Schema.JsonObject);
21
+ const encodeGoneAt = Schema.encodeSync(ItemProjectionRow.fields.goneAt);
19
22
  const persistence = (operation) => (effect) => Effect.mapError(effect, (cause) => new EnginePersistenceError({ operation, cause }));
20
23
  const makeReader = Effect.gen(function* () {
21
24
  const database = yield* RunDatabase;
@@ -30,6 +33,7 @@ const makeReader = Effect.gen(function* () {
30
33
  number: itemProjections.itemNumber,
31
34
  contentHash: itemProjections.contentHash,
32
35
  payload: itemProjections.payloadJson,
36
+ goneAt: itemProjections.goneAt,
33
37
  })
34
38
  .from(itemProjections)
35
39
  .where(eq(itemProjections.repository, repository))
@@ -37,7 +41,17 @@ const makeReader = Effect.gen(function* () {
37
41
  .limit(options.limit)
38
42
  .execute();
39
43
  return (yield* decodeRows(rows, { onExcessProperty: "error" })).map((row) => new ItemProjection(row));
40
- }, persistence("list Item projections")),
44
+ }, persistence("list item projections")),
45
+ openIssues: Effect.fn("ItemProjectionReader.openIssues")(function* (repository) {
46
+ yield* Effect.annotateCurrentSpan({ repository });
47
+ const rows = yield* database
48
+ .select({ number: itemProjections.itemNumber })
49
+ .from(itemProjections)
50
+ .where(and(eq(itemProjections.repository, repository), eq(itemProjections.source, "issue"), isNull(itemProjections.goneAt), sql `json_extract(${itemProjections.payloadJson}, '$.state') = 'OPEN'`))
51
+ .orderBy(asc(itemProjections.itemNumber))
52
+ .execute();
53
+ return yield* decodeNumbers(rows.map(({ number }) => number));
54
+ }, persistence("list open issue projections")),
41
55
  };
42
56
  });
43
57
  const makeWriter = Effect.gen(function* () {
@@ -49,6 +63,7 @@ const makeWriter = Effect.gen(function* () {
49
63
  item: item.number,
50
64
  itemKey: item.itemKey,
51
65
  });
66
+ const goneAt = encodeGoneAt(item.goneAt);
52
67
  const changed = yield* database
53
68
  .insert(itemProjections)
54
69
  .values({
@@ -58,6 +73,7 @@ const makeWriter = Effect.gen(function* () {
58
73
  itemNumber: item.number,
59
74
  contentHash: item.contentHash,
60
75
  payloadJson: encodePayload(item.payload),
76
+ goneAt,
61
77
  })
62
78
  .onConflictDoUpdate({
63
79
  target: itemProjections.itemKey,
@@ -67,8 +83,9 @@ const makeWriter = Effect.gen(function* () {
67
83
  itemNumber: item.number,
68
84
  contentHash: item.contentHash,
69
85
  payloadJson: encodePayload(item.payload),
86
+ goneAt,
70
87
  },
71
- setWhere: ne(itemProjections.contentHash, item.contentHash),
88
+ setWhere: sql `${itemProjections.contentHash} != ${item.contentHash} OR ${itemProjections.goneAt} IS NOT ${goneAt}`,
72
89
  })
73
90
  .returning({ itemKey: itemProjections.itemKey })
74
91
  .execute();
@@ -87,7 +104,25 @@ const makeWriter = Effect.gen(function* () {
87
104
  contentHash: item.contentHash,
88
105
  });
89
106
  return true;
90
- }, persistence("write Item projection")),
107
+ }, persistence("write item projection")),
108
+ markGone: Effect.fn("ItemProjectionWriter.markGone")(function* (itemKey, goneAt) {
109
+ yield* Effect.annotateCurrentSpan({ itemKey });
110
+ const marked = yield* database
111
+ .update(itemProjections)
112
+ .set({ goneAt: encodeGoneAt(Option.some(goneAt)) })
113
+ .where(and(eq(itemProjections.itemKey, itemKey), isNull(itemProjections.goneAt)))
114
+ .returning({ itemKey: itemProjections.itemKey })
115
+ .execute();
116
+ if (marked.length === 0) {
117
+ yield* Effect.logDebug("Item projection already gone or never stored", { itemKey });
118
+ return false;
119
+ }
120
+ yield* Effect.logInfo("Item projection marked gone from GitHub", {
121
+ itemKey,
122
+ goneAt: DateTime.formatIso(goneAt),
123
+ });
124
+ return true;
125
+ }, persistence("mark item projection gone")),
91
126
  };
92
127
  });
93
128
  export class ItemProjectionReader extends Context.Service()("@usine/engine/ItemProjectionReader") {
@@ -1 +1 @@
1
- {"version":3,"file":"item-projection.js","sourceRoot":"","sources":["../../src/item-projection/item-projection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"item-projection.js","sourceRoot":"","sources":["../../src/item-projection/item-projection.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,12 @@ declare const ItemProjection_base: Schema.Class<ItemProjection, Schema.Struct<{
10
10
  readonly number: Schema.brand<Schema.Int, "ItemNumber">;
11
11
  readonly contentHash: Schema.brand<Schema.NonEmptyString, "ItemContentHash">;
12
12
  readonly payload: Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>;
13
+ readonly goneAt: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.OptionFromNullOr<Schema.DateTimeUtcFromString>, never>>;
13
14
  }>, {}>;
14
- /** The latest payload a trigger observed for one Item, whatever the source adapter. */
15
+ /**
16
+ * The latest payload a trigger observed for one Item. `goneAt` is the time a poll or re-check
17
+ * found the Item missing on GitHub, or `None` while GitHub has it.
18
+ */
15
19
  export declare class ItemProjection extends ItemProjection_base {
16
20
  }
17
21
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/item-projection/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,eAAO,MAAM,oBAAoB,6DAEhC,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC,IAAI,CAAC;AAEpE,eAAO,MAAM,eAAe,wDAA8D,CAAC;AAC3F,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAC;;;;;;;;;AAE1D,uFAAuF;AACvF,qBAAa,cAAe,SAAQ,mBAOlC;CAAG"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/item-projection/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE/D,eAAO,MAAM,oBAAoB,6DAEhC,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC,IAAI,CAAC;AAEpE,eAAO,MAAM,eAAe,wDAA8D,CAAC;AAC3F,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAC;;;;;;;;;;AAE1D;;;GAGG;AACH,qBAAa,cAAe,SAAQ,mBAWlC;CAAG"}
@@ -1,9 +1,12 @@
1
1
  import { ItemKey, ItemNumber } from "@usine/core/item";
2
2
  import { RepositoryName } from "@usine/core/repository";
3
- import { Schema } from "effect";
3
+ import { Effect, Option, Schema } from "effect";
4
4
  export const ItemProjectionSource = Schema.NonEmptyString.pipe(Schema.brand("ItemProjectionSource"));
5
5
  export const ItemContentHash = Schema.NonEmptyString.pipe(Schema.brand("ItemContentHash"));
6
- /** The latest payload a trigger observed for one Item, whatever the source adapter. */
6
+ /**
7
+ * The latest payload a trigger observed for one Item. `goneAt` is the time a poll or re-check
8
+ * found the Item missing on GitHub, or `None` while GitHub has it.
9
+ */
7
10
  export class ItemProjection extends Schema.Class("@usine/engine/ItemProjection")({
8
11
  itemKey: ItemKey,
9
12
  repository: RepositoryName,
@@ -11,6 +14,7 @@ export class ItemProjection extends Schema.Class("@usine/engine/ItemProjection")
11
14
  number: ItemNumber,
12
15
  contentHash: ItemContentHash,
13
16
  payload: Schema.JsonObject,
17
+ goneAt: Schema.OptionFromNullOr(Schema.DateTimeUtcFromString).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null)), Schema.withConstructorDefault(Effect.succeed(Option.none()))),
14
18
  }) {
15
19
  }
16
20
  //# sourceMappingURL=model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/item-projection/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAC5D,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CACrC,CAAC;AAGF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAG3F,uFAAuF;AACvF,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,KAAK,CAAiB,8BAA8B,CAAC,CAAC;IAC/F,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,cAAc;IAC1B,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC,UAAU;CAC3B,CAAC;CAAG"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/item-projection/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAiB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE/D,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAC5D,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CACrC,CAAC;AAGF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAG3F;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,KAAK,CAAiB,8BAA8B,CAAC,CAAC;IAC/F,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,cAAc;IAC1B,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAChE,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EACnD,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAgB,CAAC,CAAC,CAC3E;CACF,CAAC;CAAG"}
@@ -4,16 +4,16 @@ import { RunDatabase } from "../database/database.ts";
4
4
  import { EnginePersistenceError } from "../engine/error.ts";
5
5
  import { LoopRuntimeState } from "./model.ts";
6
6
  declare const LoopControl_base: Context.ServiceClass<LoopControl, "@usine/engine/LoopControl", {
7
- /** Whether new Runs are paused; a Loop with no recorded runtime state is unpaused. */
7
+ /** Returns whether new Runs are paused; a Loop without recorded state isn't paused. */
8
8
  readonly isPaused: (loop: LoopName) => Effect.Effect<boolean, EnginePersistenceError>;
9
- /** Pauses new trigger work for this Loop without stopping its existing Runs. */
9
+ /** Pauses new Runs for the Loop without stopping its existing Runs. */
10
10
  readonly pause: (loop: LoopName) => Effect.Effect<LoopRuntimeState, EnginePersistenceError>;
11
- /** Recorded runtime states ordered by Loop name; Loops without stored state are omitted. */
11
+ /** Reads the recorded runtime states by Loop name, omitting Loops without stored state. */
12
12
  readonly states: Effect.Effect<ReadonlyArray<LoopRuntimeState>, EnginePersistenceError>;
13
- /** Allows triggers to open new Runs for this Loop again. */
13
+ /** Lets triggers open new Runs for the Loop again. */
14
14
  readonly unpause: (loop: LoopName) => Effect.Effect<LoopRuntimeState, EnginePersistenceError>;
15
15
  }>;
16
- /** Records whether triggers may open new Runs for each Loop; existing Runs and authored files stay unchanged. */
16
+ /** The service that records whether triggers can open new Runs for each Loop, without changing Runs or Loop files. */
17
17
  export declare class LoopControl extends LoopControl_base {
18
18
  static readonly layer: Layer.Layer<LoopControl, never, RunDatabase>;
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loop-control.d.ts","sourceRoot":"","sources":["../../src/loop-control/loop-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;;IA6E1C,sFAAsF;uBACnE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACrF,gFAAgF;oBAChE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;IAC3F,4FAA4F;qBAC3E,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IACvF,4DAA4D;sBAC1C,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;;AAXjG,iHAAiH;AACjH,qBAAa,WAAY,SAAQ,gBAYD;IAC9B,MAAM,CAAC,QAAQ,CAAC,KAAK,+CAA8C;CACpE;AAED,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"loop-control.d.ts","sourceRoot":"","sources":["../../src/loop-control/loop-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;;IA6E1C,uFAAuF;uBACpE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACrF,uEAAuE;oBACvD,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;IAC3F,2FAA2F;qBAC1E,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IACvF,sDAAsD;sBACpC,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;;AAXjG,sHAAsH;AACtH,qBAAa,WAAY,SAAQ,gBAYD;IAC9B,MAAM,CAAC,QAAQ,CAAC,KAAK,+CAA8C;CACpE;AAED,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -20,7 +20,7 @@ const makeLoopControl = Effect.gen(function* () {
20
20
  return stored === undefined
21
21
  ? new LoopRuntimeState({ loop, paused: false })
22
22
  : new LoopRuntimeState(stored);
23
- }, persistence("read Loop runtime state"));
23
+ }, persistence("read loop runtime state"));
24
24
  const states = Effect.fn("LoopControl.states")(function* () {
25
25
  const rows = yield* database
26
26
  .select({ loop: loopRuntime.loopName, paused: loopRuntime.paused })
@@ -28,7 +28,7 @@ const makeLoopControl = Effect.gen(function* () {
28
28
  .orderBy(asc(loopRuntime.loopName))
29
29
  .execute();
30
30
  return rows.map((row) => new LoopRuntimeState(row));
31
- }, persistence("list Loop runtime states"));
31
+ }, persistence("list loop runtime states"));
32
32
  const write = Effect.fn("LoopControl.write")(function* (next) {
33
33
  yield* Effect.annotateCurrentSpan({ loop: next.loop });
34
34
  const current = yield* stateFor(next.loop);
@@ -47,7 +47,7 @@ const makeLoopControl = Effect.gen(function* () {
47
47
  set: { paused: next.paused },
48
48
  })
49
49
  .execute()
50
- .pipe(persistence("write Loop runtime state"));
50
+ .pipe(persistence("write loop runtime state"));
51
51
  yield* Effect.logInfo(next.paused ? "Loop paused" : "Loop unpaused", {
52
52
  loop: next.loop,
53
53
  paused: next.paused,
@@ -63,7 +63,7 @@ const makeLoopControl = Effect.gen(function* () {
63
63
  unpause: Effect.fn("LoopControl.unpause")((loop) => write(new LoopRuntimeState({ loop, paused: false }))),
64
64
  };
65
65
  });
66
- /** Records whether triggers may open new Runs for each Loop; existing Runs and authored files stay unchanged. */
66
+ /** The service that records whether triggers can open new Runs for each Loop, without changing Runs or Loop files. */
67
67
  export class LoopControl extends Context.Service()("@usine/engine/LoopControl") {
68
68
  static layer = Layer.effect(LoopControl, makeLoopControl);
69
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loop-control.js","sourceRoot":"","sources":["../../src/loop-control/loop-control.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop-control.js","sourceRoot":"","sources":["../../src/loop-control/loop-control.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ declare const LoopRuntimeState_base: Schema.Class<LoopRuntimeState, Schema.Struc
3
3
  readonly loop: Schema.brand<Schema.NonEmptyString, "LoopName">;
4
4
  readonly paused: Schema.Boolean;
5
5
  }>, {}>;
6
- /** Runtime state for one Loop. Authored loop files never carry this toggle. */
6
+ /** The runtime state of a Loop, not stored in Loop files. */
7
7
  export declare class LoopRuntimeState extends LoopRuntimeState_base {
8
8
  }
9
9
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/loop-control/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;AAEhC,+EAA+E;AAC/E,qBAAa,gBAAiB,SAAQ,qBAKpC;CAAG"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/loop-control/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;AAEhC,6DAA6D;AAC7D,qBAAa,gBAAiB,SAAQ,qBAKpC;CAAG"}
@@ -1,6 +1,6 @@
1
1
  import { LoopName } from "@usine/core/loop";
2
2
  import { Schema } from "effect";
3
- /** Runtime state for one Loop. Authored loop files never carry this toggle. */
3
+ /** The runtime state of a Loop, not stored in Loop files. */
4
4
  export class LoopRuntimeState extends Schema.Class("@usine/engine/LoopRuntimeState")({
5
5
  loop: LoopName,
6
6
  paused: Schema.Boolean,
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/loop-control/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,+EAA+E;AAC/E,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,KAAK,CAChD,gCAAgC,CACjC,CAAC;IACA,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,MAAM,CAAC,OAAO;CACvB,CAAC;CAAG"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/loop-control/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,6DAA6D;AAC7D,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,KAAK,CAChD,gCAAgC,CACjC,CAAC;IACA,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,MAAM,CAAC,OAAO;CACvB,CAAC;CAAG"}
@@ -1,5 +1,5 @@
1
1
  import { Schema } from "effect";
2
- /** Six hex digits, as GitHub stores label colors. Absent for catalogs stored before colors were kept. */
2
+ /** A label color as six hex digits, absent in older catalogs. */
3
3
  export declare const RepositoryLabelColor: Schema.String;
4
4
  declare const RepositoryLabel_base: Schema.Class<RepositoryLabel, Schema.Struct<{
5
5
  readonly name: Schema.String;
@@ -12,7 +12,7 @@ declare const RepositoryLabelProjection_base: Schema.Class<RepositoryLabelProjec
12
12
  readonly repository: Schema.brand<Schema.String, "RepositoryName">;
13
13
  readonly labels: Schema.$Array<typeof RepositoryLabel>;
14
14
  }>, {}>;
15
- /** The latest complete label catalog polling observed for one repository. */
15
+ /** The latest complete label catalog that polling observed for a repository. */
16
16
  export declare class RepositoryLabelProjection extends RepositoryLabelProjection_base {
17
17
  }
18
18
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/repository-label-projection/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMhC,yGAAyG;AACzG,eAAO,MAAM,oBAAoB,eAEhC,CAAC;;;;;;AAEF,qBAAa,eAAgB,SAAQ,oBAMpC;CAAG;;;;;AAQJ,6EAA6E;AAC7E,qBAAa,yBAA0B,SAAQ,8BAK7C;CAAG"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/repository-label-projection/model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMhC,iEAAiE;AACjE,eAAO,MAAM,oBAAoB,eAEhC,CAAC;;;;;;AAEF,qBAAa,eAAgB,SAAQ,oBAMpC;CAAG;;;;;AAQJ,gFAAgF;AAChF,qBAAa,yBAA0B,SAAQ,8BAK7C;CAAG"}
@@ -1,7 +1,7 @@
1
1
  import { RepositoryName } from "@usine/core/repository";
2
2
  import { Schema } from "effect";
3
3
  const RepositoryLabelName = Schema.String.check(Schema.isPattern(/\S/u, { message: "Expected a non-blank repository label" }));
4
- /** Six hex digits, as GitHub stores label colors. Absent for catalogs stored before colors were kept. */
4
+ /** A label color as six hex digits, absent in older catalogs. */
5
5
  export const RepositoryLabelColor = Schema.String.check(Schema.isPattern(/^[0-9a-fA-F]{6}$/u, { message: "Expected a six-digit hex label color" }));
6
6
  export class RepositoryLabel extends Schema.Class("@usine/engine/RepositoryLabel")({
7
7
  name: RepositoryLabelName,
@@ -11,7 +11,7 @@ export class RepositoryLabel extends Schema.Class("@usine/engine/RepositoryLabel
11
11
  }
12
12
  const uniqueLabelNames = Schema.makeFilter((labels) => new Set(labels.map(({ name }) => name)).size === labels.length, { message: "Expected unique label names" });
13
13
  const RepositoryLabels = Schema.Array(RepositoryLabel).check(uniqueLabelNames);
14
- /** The latest complete label catalog polling observed for one repository. */
14
+ /** The latest complete label catalog that polling observed for a repository. */
15
15
  export class RepositoryLabelProjection extends Schema.Class("@usine/engine/RepositoryLabelProjection")({
16
16
  repository: RepositoryName,
17
17
  labels: RepositoryLabels,