@boxxy/model 0.1.2 → 0.1.3

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 (234) hide show
  1. package/README.md +8 -6
  2. package/dist/closeouts/build-close-out-schema.d.ts +31 -0
  3. package/dist/closeouts/close-out-answer-schema.d.ts +3 -0
  4. package/dist/closeouts/close-out-schema.d.ts +3 -0
  5. package/dist/closeouts/design-close-out-schema.d.ts +30 -0
  6. package/dist/closeouts/friction-schema.d.ts +14 -0
  7. package/dist/closeouts/open-item-schema.d.ts +3 -0
  8. package/dist/closeouts/review-close-out-schema.d.ts +40 -0
  9. package/dist/closeouts/triage-close-out-schema.d.ts +40 -0
  10. package/dist/closeouts/types.d.ts +221 -0
  11. package/dist/dispatch/build-applied-change.d.ts +6 -0
  12. package/dist/dispatch/collect-seat-sync.d.ts +14 -0
  13. package/dist/dispatch/pick-seat-take.d.ts +10 -0
  14. package/dist/dispatch/types.d.ts +11 -0
  15. package/dist/{outbox-fact-schema.d.ts → facts/outbox-fact-schema.d.ts} +1 -1
  16. package/dist/facts/parse-new-fact.d.ts +2 -0
  17. package/dist/facts/types.d.ts +191 -0
  18. package/dist/facts/work-fact-schemas.d.ts +293 -0
  19. package/dist/index.d.ts +64 -23
  20. package/dist/items/build-item-views.d.ts +4 -0
  21. package/dist/items/collect-retries.d.ts +3 -0
  22. package/dist/items/collect-settled.d.ts +3 -0
  23. package/dist/items/derive-item-state.d.ts +17 -0
  24. package/dist/{live-levers.d.ts → items/live-levers.d.ts} +1 -1
  25. package/dist/items/types.d.ts +12 -0
  26. package/dist/pipeline/advance.d.ts +10 -0
  27. package/dist/pipeline/constants.d.ts +2 -0
  28. package/dist/pipeline/count-trailing.d.ts +1 -0
  29. package/dist/pipeline/find-position.d.ts +9 -0
  30. package/dist/pipeline/find-step.d.ts +3 -0
  31. package/dist/pipeline/merge-by-time.d.ts +9 -0
  32. package/dist/pipeline/position-schema.d.ts +3 -0
  33. package/dist/pipeline/types.d.ts +28 -0
  34. package/dist/planning/define-admission.d.ts +3 -0
  35. package/dist/planning/define-gate.d.ts +3 -0
  36. package/dist/planning/define-signal.d.ts +3 -0
  37. package/dist/planning/is-filter-match.d.ts +3 -0
  38. package/dist/planning/limit-fill-schema.d.ts +3 -0
  39. package/dist/{signal-key.d.ts → planning/signal-key.d.ts} +1 -1
  40. package/dist/planning/types.d.ts +155 -0
  41. package/dist/ports/types.d.ts +289 -0
  42. package/dist/reports/constants.d.ts +3 -0
  43. package/dist/reports/cost-to-land-schema.d.ts +29 -0
  44. package/dist/reports/outbox-status.d.ts +16 -0
  45. package/dist/reports/stage-time-schema.d.ts +25 -0
  46. package/dist/reports/types.d.ts +5 -0
  47. package/dist/rows/actor-ref-schema.d.ts +2 -0
  48. package/dist/rows/attempt-row-schema.d.ts +3 -0
  49. package/dist/rows/attempt-session-row-schema.d.ts +3 -0
  50. package/dist/{brand-schemas.d.ts → rows/brand-schemas.d.ts} +5 -2
  51. package/dist/rows/caller-identity-schema.d.ts +3 -0
  52. package/dist/rows/criterion-schema.d.ts +3 -0
  53. package/dist/rows/decision-row-schema.d.ts +34 -0
  54. package/dist/rows/evidence-row-schema.d.ts +3 -0
  55. package/dist/rows/item-row-schema.d.ts +28 -0
  56. package/dist/rows/item-view-schema.d.ts +3 -0
  57. package/dist/rows/lease-row-schema.d.ts +3 -0
  58. package/dist/rows/lever-row-schema.d.ts +12 -0
  59. package/dist/rows/limit-schema.d.ts +3 -0
  60. package/dist/rows/limit-seat-row-schema.d.ts +3 -0
  61. package/dist/rows/note-row-schema.d.ts +3 -0
  62. package/dist/rows/notice-row-schema.d.ts +3 -0
  63. package/dist/rows/pull-request-row-schema.d.ts +3 -0
  64. package/dist/rows/relation-row-schema.d.ts +3 -0
  65. package/dist/{row-schemas.d.ts → rows/row-schemas.d.ts} +2 -2
  66. package/dist/rows/runner-row-schema.d.ts +3 -0
  67. package/dist/rows/spawn-request-schema.d.ts +3 -0
  68. package/dist/rules/define-phase.d.ts +3 -0
  69. package/dist/rules/load-rejection-schema.d.ts +3 -0
  70. package/dist/rules/types.d.ts +244 -0
  71. package/dist/test-utils/build-mock-cost-to-land.d.ts +2 -0
  72. package/dist/test-utils/build-mock-evidence-row.d.ts +1 -1
  73. package/dist/test-utils/build-mock-fact-id.d.ts +1 -1
  74. package/dist/test-utils/build-mock-frame-item.d.ts +1 -1
  75. package/dist/test-utils/build-mock-frame.d.ts +2 -0
  76. package/dist/test-utils/build-mock-item-rules.d.ts +2 -0
  77. package/dist/test-utils/build-mock-lease-row.d.ts +1 -1
  78. package/dist/test-utils/build-mock-outbox-fact.d.ts +2 -0
  79. package/dist/test-utils/build-mock-phase-kind.d.ts +7 -0
  80. package/dist/test-utils/build-mock-pipeline.d.ts +7 -0
  81. package/dist/test-utils/build-mock-relation-row.d.ts +2 -0
  82. package/dist/test-utils/build-mock-settled.d.ts +9 -0
  83. package/dist/test-utils/build-mock-snapshot.d.ts +1 -1
  84. package/dist/test-utils/build-mock-v1-attempt-row.d.ts +2 -0
  85. package/dist/test-utils/build-mock-v1-item-row.d.ts +2 -0
  86. package/dist/test-utils/build-mock-v1-item-view.d.ts +2 -0
  87. package/dist/test-utils/build-mock-v1-lever-row.d.ts +2 -0
  88. package/dist/test-utils/build-mock-v1-pull-request-row.d.ts +2 -0
  89. package/dist/test-utils/build-mock-work-fact.d.ts +12 -0
  90. package/dist/test-utils/create-fake-notifier.d.ts +9 -0
  91. package/dist/test-utils/create-fake-pepys-reader.d.ts +13 -0
  92. package/dist/test-utils/fact-sink-contract.d.ts +14 -0
  93. package/dist/test-utils/pepys-reader-contract.d.ts +17 -0
  94. package/dist/{types/core.d.ts → types.d.ts} +93 -43
  95. package/package.json +13 -3
  96. package/src/{build-close-out-schema.ts → closeouts/build-close-out-schema.ts} +5 -10
  97. package/src/closeouts/close-out-answer-schema.ts +42 -0
  98. package/src/closeouts/close-out-schema.ts +13 -0
  99. package/src/closeouts/design-close-out-schema.ts +20 -0
  100. package/src/closeouts/friction-schema.ts +11 -0
  101. package/src/closeouts/open-item-schema.ts +8 -0
  102. package/src/closeouts/review-close-out-schema.ts +38 -0
  103. package/src/closeouts/triage-close-out-schema.ts +29 -0
  104. package/src/closeouts/types.ts +230 -0
  105. package/src/dispatch/build-applied-change.ts +57 -0
  106. package/src/dispatch/collect-seat-sync.ts +86 -0
  107. package/src/dispatch/pick-seat-take.ts +39 -0
  108. package/src/dispatch/types.ts +14 -0
  109. package/src/facts/outbox-fact-schema.ts +22 -0
  110. package/src/facts/parse-new-fact.ts +16 -0
  111. package/src/facts/types.ts +235 -0
  112. package/src/facts/work-fact-schemas.ts +201 -0
  113. package/src/index.ts +147 -55
  114. package/src/items/build-item-views.ts +146 -0
  115. package/src/items/collect-retries.ts +12 -0
  116. package/src/items/collect-settled.ts +20 -0
  117. package/src/items/derive-item-state.ts +95 -0
  118. package/src/{live-levers.ts → items/live-levers.ts} +1 -1
  119. package/src/items/types.ts +26 -0
  120. package/src/pipeline/advance.ts +78 -0
  121. package/src/pipeline/constants.ts +12 -0
  122. package/src/pipeline/count-trailing.ts +16 -0
  123. package/src/pipeline/find-position.ts +74 -0
  124. package/src/pipeline/find-step.ts +6 -0
  125. package/src/pipeline/merge-by-time.ts +33 -0
  126. package/src/pipeline/position-schema.ts +27 -0
  127. package/src/pipeline/types.ts +47 -0
  128. package/src/{define-admission.ts → planning/define-admission.ts} +2 -2
  129. package/src/{define-gate.ts → planning/define-gate.ts} +2 -2
  130. package/src/{define-signal.ts → planning/define-signal.ts} +2 -2
  131. package/src/planning/is-filter-match.ts +10 -0
  132. package/src/planning/limit-fill-schema.ts +12 -0
  133. package/src/{signal-key.ts → planning/signal-key.ts} +1 -1
  134. package/src/planning/types.ts +216 -0
  135. package/src/ports/types.ts +412 -0
  136. package/src/reports/constants.ts +6 -0
  137. package/src/reports/cost-to-land-schema.ts +47 -0
  138. package/src/reports/outbox-status.ts +22 -0
  139. package/src/reports/stage-time-schema.ts +21 -0
  140. package/src/reports/types.ts +7 -0
  141. package/src/rows/actor-ref-schema.ts +17 -0
  142. package/src/rows/attempt-row-schema.ts +69 -0
  143. package/src/rows/attempt-session-row-schema.ts +12 -0
  144. package/src/{brand-schemas.ts → rows/brand-schemas.ts} +5 -2
  145. package/src/rows/caller-identity-schema.ts +7 -0
  146. package/src/rows/criterion-schema.ts +9 -0
  147. package/src/rows/decision-row-schema.ts +34 -0
  148. package/src/rows/evidence-row-schema.ts +13 -0
  149. package/src/rows/item-row-schema.ts +32 -0
  150. package/src/rows/item-view-schema.ts +31 -0
  151. package/src/rows/lease-row-schema.ts +12 -0
  152. package/src/rows/lever-row-schema.ts +17 -0
  153. package/src/rows/limit-schema.ts +12 -0
  154. package/src/rows/limit-seat-row-schema.ts +12 -0
  155. package/src/rows/note-row-schema.ts +12 -0
  156. package/src/rows/notice-row-schema.ts +17 -0
  157. package/src/rows/pull-request-row-schema.ts +15 -0
  158. package/src/rows/relation-row-schema.ts +13 -0
  159. package/src/rows/row-schemas.ts +30 -0
  160. package/src/rows/runner-row-schema.ts +9 -0
  161. package/src/rows/spawn-request-schema.ts +15 -0
  162. package/src/rules/define-phase.ts +12 -0
  163. package/src/rules/load-rejection-schema.ts +51 -0
  164. package/src/rules/types.ts +291 -0
  165. package/src/test-utils/build-mock-cost-to-land.ts +31 -0
  166. package/src/test-utils/build-mock-evidence-row.ts +2 -2
  167. package/src/test-utils/build-mock-fact-id.ts +3 -3
  168. package/src/test-utils/build-mock-frame-item.ts +10 -5
  169. package/src/test-utils/build-mock-frame.ts +13 -0
  170. package/src/test-utils/build-mock-item-rules.ts +17 -0
  171. package/src/test-utils/build-mock-lease-row.ts +2 -2
  172. package/src/test-utils/build-mock-outbox-fact.ts +22 -0
  173. package/src/test-utils/build-mock-phase-kind.ts +29 -0
  174. package/src/test-utils/build-mock-pipeline.ts +52 -0
  175. package/src/test-utils/{build-mock-link-row.ts → build-mock-relation-row.ts} +4 -4
  176. package/src/test-utils/build-mock-settled.ts +18 -0
  177. package/src/test-utils/build-mock-snapshot.ts +10 -2
  178. package/src/test-utils/{build-mock-attempt-row.ts → build-mock-v1-attempt-row.ts} +28 -9
  179. package/src/test-utils/{build-mock-item-row.ts → build-mock-v1-item-row.ts} +7 -3
  180. package/src/test-utils/build-mock-v1-item-view.ts +29 -0
  181. package/src/test-utils/{build-mock-lever-row.ts → build-mock-v1-lever-row.ts} +5 -3
  182. package/src/test-utils/build-mock-v1-pull-request-row.ts +26 -0
  183. package/src/test-utils/build-mock-work-fact.ts +179 -0
  184. package/src/test-utils/create-fake-notifier.ts +54 -0
  185. package/src/test-utils/create-fake-pepys-reader.ts +73 -0
  186. package/src/test-utils/fact-sink-contract.ts +103 -0
  187. package/src/test-utils/pepys-reader-contract.ts +117 -0
  188. package/src/{types/core.ts → types.ts} +183 -59
  189. package/dist/actor-ref-schema.d.ts +0 -2
  190. package/dist/build-applied-change.d.ts +0 -13
  191. package/dist/build-close-out-schema.d.ts +0 -3
  192. package/dist/build-item-views.d.ts +0 -2
  193. package/dist/define-admission.d.ts +0 -3
  194. package/dist/define-gate.d.ts +0 -3
  195. package/dist/define-signal.d.ts +0 -3
  196. package/dist/derive-item-state.d.ts +0 -2
  197. package/dist/fact-schemas.d.ts +0 -5
  198. package/dist/find-slot-take.d.ts +0 -5
  199. package/dist/friction-schema.d.ts +0 -3
  200. package/dist/test-utils/build-mock-attempt-row.d.ts +0 -2
  201. package/dist/test-utils/build-mock-item-row.d.ts +0 -2
  202. package/dist/test-utils/build-mock-item-rows.d.ts +0 -2
  203. package/dist/test-utils/build-mock-item-view.d.ts +0 -2
  204. package/dist/test-utils/build-mock-lever-row.d.ts +0 -2
  205. package/dist/test-utils/build-mock-link-row.d.ts +0 -2
  206. package/dist/test-utils/build-mock-pull-request-row.d.ts +0 -2
  207. package/dist/types/dispatch.d.ts +0 -82
  208. package/dist/types/facts.d.ts +0 -154
  209. package/dist/types/planning.d.ts +0 -94
  210. package/dist/types/ports.d.ts +0 -218
  211. package/dist/types/registries.d.ts +0 -150
  212. package/src/actor-ref-schema.ts +0 -9
  213. package/src/build-applied-change.ts +0 -71
  214. package/src/build-item-views.ts +0 -128
  215. package/src/derive-item-state.ts +0 -76
  216. package/src/fact-schemas.ts +0 -132
  217. package/src/find-slot-take.ts +0 -12
  218. package/src/friction-schema.ts +0 -10
  219. package/src/outbox-fact-schema.ts +0 -25
  220. package/src/row-schemas.ts +0 -89
  221. package/src/test-utils/build-mock-item-rows.ts +0 -14
  222. package/src/test-utils/build-mock-item-view.ts +0 -8
  223. package/src/test-utils/build-mock-pull-request-row.ts +0 -16
  224. package/src/types/dispatch.ts +0 -95
  225. package/src/types/facts.ts +0 -166
  226. package/src/types/planning.ts +0 -136
  227. package/src/types/ports.ts +0 -262
  228. package/src/types/registries.ts +0 -185
  229. /package/dist/test-utils/{seed-faker.d.ts → pin-faker-seed.d.ts} +0 -0
  230. /package/dist/{format-key-path.d.ts → utils/format-key-path.d.ts} +0 -0
  231. /package/dist/{to-json-value.d.ts → utils/to-json-value.d.ts} +0 -0
  232. /package/src/test-utils/{seed-faker.ts → pin-faker-seed.ts} +0 -0
  233. /package/src/{format-key-path.ts → utils/format-key-path.ts} +0 -0
  234. /package/src/{to-json-value.ts → utils/to-json-value.ts} +0 -0
@@ -1,154 +0,0 @@
1
- import type { JsonValue } from '@boxxy/content-hash';
2
- import type { ActorRef, AgentSessionId, AtcSessionId, CommitSha, Criterion, CriterionId, DecisionRow, EvidenceKind, FactId, Instant, ItemId, ItemRow, LeverRow, LinkTypeName, PhaseName, PoolName, RecipeHash, RepoName, RulesVersion, RunnerId } from './core.ts';
3
- export interface BuildCloseOut {
4
- readonly result: {
5
- readonly kind: 'built';
6
- } | {
7
- readonly kind: 'blocked';
8
- readonly reason: string;
9
- } | {
10
- readonly kind: 'abandoned';
11
- readonly reason: string;
12
- };
13
- readonly criteria: readonly {
14
- readonly criterion: CriterionId;
15
- readonly evidence: FactId;
16
- }[];
17
- readonly openItems: readonly OpenItem[];
18
- readonly friction: readonly Friction[];
19
- readonly frictionDropped: number;
20
- }
21
- export interface OpenItem {
22
- readonly kind: 'core.issue';
23
- readonly title: string;
24
- readonly body: string;
25
- }
26
- export type FrictionTargetKind = 'skill' | 'rule' | 'lint' | 'agents-md' | 'tool';
27
- export interface Friction {
28
- readonly target: {
29
- readonly kind: FrictionTargetKind;
30
- readonly name: string;
31
- };
32
- readonly change: string;
33
- }
34
- export type EntityRef = `boxxy:item:${string}` | `boxxy:link:${string}:${string}:${string}` | `boxxy:attempt:${string}` | `boxxy:decision:${string}` | `boxxy:runner:${string}`;
35
- export interface FactEnvelope<M extends object = SliceOneFacts, T extends keyof M & string = keyof M & string> {
36
- readonly id: FactId;
37
- readonly type: T;
38
- readonly v: 1;
39
- readonly api: 'boxxy/1';
40
- readonly entity: EntityRef;
41
- readonly actor: ActorRef;
42
- readonly at: Instant;
43
- readonly payload: M[T] & {
44
- readonly storeVersion: number;
45
- };
46
- }
47
- export interface NewFact<T extends keyof M & string, M extends object = SliceOneFacts> {
48
- readonly id: FactId;
49
- readonly type: T;
50
- readonly entity: EntityRef;
51
- readonly actor: ActorRef;
52
- readonly payload: M[T];
53
- }
54
- export interface OutboxFact {
55
- readonly seq: number;
56
- readonly factId: FactId;
57
- readonly type: string;
58
- readonly entity: EntityRef;
59
- readonly actor: ActorRef;
60
- readonly at: Instant;
61
- readonly payload: JsonValue;
62
- readonly sentAt: Instant | null;
63
- }
64
- export type FactType = keyof SliceOneFacts;
65
- export interface LinkPayload {
66
- readonly source: ItemId;
67
- readonly target: ItemId;
68
- readonly type: LinkTypeName;
69
- }
70
- export interface SliceOneFacts {
71
- 'boxxy.item.filed': ItemRow;
72
- 'boxxy.item.edited': {
73
- readonly title?: string;
74
- readonly outcome?: string;
75
- readonly acceptance?: readonly Criterion[];
76
- };
77
- 'boxxy.item.closed': {
78
- readonly reason: string;
79
- };
80
- 'boxxy.link.added': LinkPayload;
81
- 'boxxy.link.removed': LinkPayload;
82
- 'boxxy.lever.recorded': LeverRow;
83
- 'boxxy.attempt.claimed': {
84
- readonly item: ItemId;
85
- readonly phase: PhaseName;
86
- readonly number: number;
87
- readonly pool: PoolName;
88
- readonly slot: number;
89
- readonly gen: number;
90
- readonly recipeHash: RecipeHash;
91
- readonly rulesVersion: RulesVersion;
92
- };
93
- 'boxxy.decision.recorded': DecisionRow;
94
- 'boxxy.attempt.started': {
95
- readonly atcSession: AtcSessionId;
96
- };
97
- 'boxxy.attempt.reconciling': {
98
- readonly reason: string;
99
- };
100
- 'boxxy.attempt.reconciled': {
101
- readonly atcSession: AtcSessionId;
102
- };
103
- 'boxxy.attempt.session_bound': {
104
- readonly atcSession: AtcSessionId;
105
- readonly agentSession: AgentSessionId;
106
- readonly seenAt: Instant;
107
- };
108
- 'boxxy.attempt.closed_out': {
109
- readonly closeOut: BuildCloseOut;
110
- };
111
- 'boxxy.attempt.settled': {
112
- readonly state: 'succeeded' | 'failed';
113
- readonly failure: string | null;
114
- readonly endedAt: Instant;
115
- readonly criteria: readonly {
116
- readonly criterion: CriterionId;
117
- readonly evidence: readonly FactId[];
118
- }[];
119
- readonly matched: readonly ItemId[];
120
- readonly frictionDropped: number;
121
- };
122
- 'boxxy.evidence.recorded': {
123
- readonly kind: EvidenceKind;
124
- readonly ref: string;
125
- readonly observed: string | null;
126
- };
127
- 'boxxy.evidence.pr_linked': {
128
- readonly repo: RepoName;
129
- readonly number: number;
130
- readonly url: string;
131
- };
132
- 'boxxy.evidence.commit_linked': {
133
- readonly repo: RepoName;
134
- readonly sha: CommitSha;
135
- readonly pr: number;
136
- };
137
- 'boxxy.pr.merged': {
138
- readonly repo: RepoName;
139
- readonly number: number;
140
- readonly mergedAt: Instant;
141
- readonly mergeCommit: CommitSha;
142
- };
143
- 'boxxy.pr.closed': {
144
- readonly repo: RepoName;
145
- readonly number: number;
146
- };
147
- 'boxxy.proposal.recorded': Friction;
148
- 'boxxy.runner.paused': {
149
- readonly runner: RunnerId;
150
- };
151
- 'boxxy.runner.resumed': {
152
- readonly runner: RunnerId;
153
- };
154
- }
@@ -1,94 +0,0 @@
1
- import type { FaultRecord, Instant, ItemId, ItemView, LeverRow, LinkRow, LinkTypeName, PhaseName, PoolName } from './core.ts';
2
- import type { Schema } from './registries.ts';
3
- export type SignalName = string;
4
- export type GateName = string;
5
- export type WaiverName = string;
6
- export type AdmissionName = string;
7
- export type ViewName = string;
8
- export type SignalKey = `${SignalName}#${string}`;
9
- export interface Snapshot {
10
- storeVersion: number;
11
- items: ItemView[];
12
- links: LinkRow[];
13
- levers: LeverRow[];
14
- freeSlots: Record<PoolName, number>;
15
- }
16
- export interface FrameItem extends ItemView {
17
- readonly phase: PhaseName;
18
- }
19
- export interface Frame {
20
- candidates: FrameItem[];
21
- fields: Map<ItemId, Readonly<Record<string, readonly string[]>>>;
22
- values: Map<SignalKey, Map<ItemId, number>>;
23
- holds: Map<ItemId, Hold[]>;
24
- lifted: Map<ItemId, Lift[]>;
25
- faults: Fault[];
26
- }
27
- export type FrameValues = ReadonlyMap<SignalKey, ReadonlyMap<ItemId, number>>;
28
- export interface Hold {
29
- readonly gate: GateName;
30
- readonly reason: string;
31
- readonly until?: Instant;
32
- }
33
- export interface Lift {
34
- readonly waiver: WaiverName;
35
- readonly gate: GateName;
36
- readonly reason: string;
37
- }
38
- export type Fault = FaultRecord;
39
- export interface Decision {
40
- picks: Pick[];
41
- }
42
- export interface Pick {
43
- item: ItemId;
44
- phase: PhaseName;
45
- pool: PoolName;
46
- }
47
- export interface Pool {
48
- readonly name: PoolName;
49
- readonly slots: number;
50
- readonly takes: Readonly<Record<string, readonly string[]>>;
51
- readonly order: readonly SignalKey[];
52
- }
53
- export interface PlanContext {
54
- now: Instant;
55
- levers: LeverRow[];
56
- links: LinkRow[];
57
- values: FrameValues;
58
- }
59
- export interface Signal<P> {
60
- name: SignalName;
61
- params: Schema<P>;
62
- value: (item: FrameItem, ctx: PlanContext, params: P) => number | null;
63
- combine?: (left: number, right: number) => number;
64
- }
65
- export interface Gate<P> {
66
- name: GateName;
67
- liftable: boolean;
68
- params: Schema<P>;
69
- hold: (item: FrameItem, ctx: PlanContext, params: P) => Hold | null;
70
- }
71
- export interface Waiver {
72
- name: WaiverName;
73
- lifts: GateName;
74
- lift: (item: FrameItem, hold: Hold, ctx: PlanContext) => Lift | null;
75
- }
76
- export interface Admission<P> {
77
- name: AdmissionName;
78
- params: Schema<P>;
79
- admit: (item: FrameItem, ctx: PlanContext, params: P) => AdmissionGrant | null;
80
- }
81
- export interface AdmissionGrant {
82
- readonly admission: AdmissionName;
83
- readonly pools: readonly PoolName[] | 'any';
84
- readonly reason: string;
85
- }
86
- export interface View<I = unknown, O = unknown> {
87
- name: ViewName;
88
- render: (frame: Frame, input: I) => O;
89
- }
90
- export interface PropagationLine {
91
- readonly value: SignalName;
92
- readonly over: LinkTypeName;
93
- readonly toward: 'source' | 'target';
94
- }
@@ -1,218 +0,0 @@
1
- import type { JsonValue } from '@boxxy/content-hash';
2
- import type { AgentSessionId, AtcSessionId, AttemptId, AttemptRow, AttemptSessionRow, CommitSha, DecisionRow, Effort, EvidenceRow, FactId, Instant, ItemId, ItemRow, ItemState, ItemView, ItemWithLevers, LeaseRow, LeverRow, LinkRow, MaxAttemptsByKind, PhaseName, PoolName, PoolSlotRow, PullRequestRef, PullRequestRow, RepoName, RunnerId, RunnerRow } from './core.ts';
3
- import type { FactType, NewFact, OutboxFact } from './facts.ts';
4
- import type { Snapshot } from './planning.ts';
5
- export interface ClaimStore {
6
- exclusive: <T>(work: (tx: StoreTx) => Promise<T>) => Promise<T>;
7
- read: <T>(work: (tx: StoreReader) => Promise<T>) => Promise<T>;
8
- }
9
- export interface StoreReader {
10
- readSnapshot: (now: Instant, maxAttemptsByKind: MaxAttemptsByKind) => Promise<Snapshot>;
11
- readItem: (id: ItemId, now: Instant, maxAttemptsByKind: MaxAttemptsByKind) => Promise<ItemView | null>;
12
- readItemDetail: (id: ItemId, now: Instant, maxAttemptsByKind: MaxAttemptsByKind) => Promise<ItemDetailRows | null>;
13
- listItems: (filter: ItemFilter, now: Instant, maxAttemptsByKind: MaxAttemptsByKind) => Promise<ItemWithLevers[]>;
14
- listOpenIssues: (repo: RepoName, now: Instant, maxAttemptsByKind: MaxAttemptsByKind) => Promise<ItemView[]>;
15
- readLastLeaseGen: (item: ItemId, phase: PhaseName) => Promise<number>;
16
- readAttempt: (id: AttemptId) => Promise<AttemptRow | null>;
17
- listEvidence: (attempt: AttemptId) => Promise<EvidenceRow[]>;
18
- listLiveAttempts: () => Promise<AttemptRow[]>;
19
- listSucceededAttemptsWithoutPr: () => Promise<AttemptRow[]>;
20
- findAttemptBySession: (session: AtcSessionId) => Promise<AttemptRow | null>;
21
- findAttemptByAgentSession: (session: AgentSessionId) => Promise<AttemptId | null>;
22
- listWatchedPullRequests: () => Promise<PullRequestRow[]>;
23
- listPoolSlots: () => Promise<PoolSlotRow[]>;
24
- readUnsentFacts: (limit: number) => Promise<OutboxFact[]>;
25
- readOutboxLag: () => Promise<{
26
- readonly unsent: number;
27
- readonly oldestUnsentAt: Instant | null;
28
- }>;
29
- readRunner: (id: RunnerId) => Promise<RunnerRow | null>;
30
- }
31
- export interface ItemDetailRows {
32
- readonly item: ItemWithLevers;
33
- readonly attempts: readonly AttemptRow[];
34
- readonly links: readonly LinkRow[];
35
- readonly evidence: readonly EvidenceRow[];
36
- readonly pullRequests: readonly PullRequestRow[];
37
- }
38
- export interface StoreTx extends StoreReader {
39
- applyChange: (change: StoreChange) => Promise<ApplyResult>;
40
- markFactsSent: (ids: FactId[], at: Instant) => Promise<void>;
41
- writeHeartbeat: (runner: RunnerId, at: Instant) => Promise<void>;
42
- syncPoolSlots: (pools: readonly {
43
- readonly name: PoolName;
44
- readonly slots: number;
45
- }[]) => Promise<void>;
46
- markPullRequestChecked: (ref: PullRequestRef, at: Instant) => Promise<void>;
47
- }
48
- export interface StoreChange {
49
- at: Instant;
50
- under?: {
51
- item: ItemId;
52
- phase: PhaseName;
53
- gen: number;
54
- slot?: {
55
- pool: PoolName;
56
- slot: number;
57
- gen: number;
58
- };
59
- };
60
- writes: RowWrite[];
61
- facts: AnyNewFact[];
62
- }
63
- export type ApplyResult = {
64
- kind: 'applied';
65
- slot: {
66
- pool: PoolName;
67
- slot: number;
68
- gen: number;
69
- } | null;
70
- } | {
71
- kind: 'stale-generation';
72
- } | {
73
- kind: 'lease-held';
74
- } | {
75
- kind: 'no-free-slot';
76
- } | {
77
- kind: 'guard-mismatch';
78
- table: TableName;
79
- key: JsonValue;
80
- };
81
- export interface ItemFilter {
82
- readonly state?: ItemState;
83
- readonly repo?: RepoName;
84
- }
85
- export interface Tables {
86
- items: ItemRow;
87
- links: LinkRow;
88
- levers: LeverRow;
89
- attempts: AttemptRow;
90
- attempt_sessions: AttemptSessionRow;
91
- leases: LeaseRow;
92
- pool_slots: PoolSlotRow;
93
- decisions: DecisionRow;
94
- evidence: EvidenceRow;
95
- pull_requests: PullRequestRow;
96
- runners: RunnerRow;
97
- }
98
- export type TableName = keyof Tables;
99
- export type RowWrite = {
100
- [T in TableName]: {
101
- readonly op: 'insert';
102
- readonly table: T;
103
- readonly row: Tables[T];
104
- };
105
- }[TableName] | {
106
- [T in TableName]: {
107
- readonly op: 'update';
108
- readonly table: T;
109
- readonly key: Partial<Tables[T]>;
110
- readonly expect: Partial<Tables[T]>;
111
- readonly set: Partial<Tables[T]>;
112
- };
113
- }[TableName] | {
114
- readonly op: 'take-slot';
115
- readonly pool: PoolName;
116
- readonly holder: AttemptId;
117
- } | {
118
- readonly op: 'release-slot';
119
- readonly pool: PoolName;
120
- readonly slot: number;
121
- readonly holder: AttemptId;
122
- };
123
- export type AnyNewFact = {
124
- [T in FactType]: NewFact<T>;
125
- }[FactType];
126
- export interface WorkerKind {
127
- start: (request: SpawnRequest) => Promise<StartOutcome>;
128
- reconcile: (attempt: AttemptRow) => Promise<SessionReading>;
129
- }
130
- export type StartOutcome = {
131
- kind: 'started';
132
- atcSession: AtcSessionId;
133
- agentSession: AgentSessionId | null;
134
- } | {
135
- kind: 'refused';
136
- reason: string;
137
- } | {
138
- kind: 'unknown';
139
- reason: string;
140
- };
141
- export type SessionReading = {
142
- kind: 'running';
143
- atcSession: AtcSessionId;
144
- agentSession: AgentSessionId | null;
145
- } | {
146
- kind: 'ended';
147
- atcSession: AtcSessionId;
148
- agentSession: AgentSessionId | null;
149
- } | {
150
- kind: 'absent';
151
- };
152
- export interface SpawnRequest {
153
- readonly cwd: string;
154
- readonly prompt: string;
155
- readonly agent: string;
156
- readonly model: string;
157
- readonly effort: Effort;
158
- readonly pluginDirs: readonly string[];
159
- readonly name: `boxxy/${string}`;
160
- readonly idempotencyKey: AttemptId;
161
- }
162
- export interface SessionFault {
163
- readonly kind: 'fault';
164
- readonly fault: 'agent-session-owned';
165
- readonly agentSession: AgentSessionId;
166
- readonly attempt: AttemptId;
167
- readonly holder: AttemptId;
168
- }
169
- export interface FactSink {
170
- append: (facts: OutboxFact[]) => Promise<'accepted' | {
171
- kind: 'unknown';
172
- reason: string;
173
- } | {
174
- kind: 'rejected';
175
- error: string;
176
- }>;
177
- }
178
- export interface CostToLandRow {
179
- readonly item: ItemId;
180
- readonly title: string;
181
- readonly repo: RepoName;
182
- readonly landedAt: Instant;
183
- readonly model: string;
184
- readonly attempts: number;
185
- readonly requests: number;
186
- readonly inputTokens: number;
187
- readonly outputTokens: number;
188
- readonly cacheReadTokens: number;
189
- readonly cacheCreationTokens: number;
190
- readonly totalInputTokens: number;
191
- readonly costUsd: number;
192
- }
193
- export interface CostToLandInput {
194
- readonly repo?: string;
195
- readonly landedFrom?: string;
196
- readonly landedTo?: string;
197
- }
198
- export interface CostReader {
199
- costToLand: (input: CostToLandInput) => Promise<CostToLandRow[]>;
200
- }
201
- export interface Forge {
202
- readPullRequest: (ref: PullRequestRef) => Promise<PullRequestReading | 'not-found'>;
203
- listOpenPullRequests: (repo: RepoName) => Promise<PullRequestRef[]>;
204
- }
205
- export interface PullRequestReading {
206
- url: string;
207
- state: 'open' | 'closed' | 'merged';
208
- mergedAt: Instant | null;
209
- mergeCommit: CommitSha | null;
210
- commits: {
211
- sha: CommitSha;
212
- message: string;
213
- }[];
214
- }
215
- export interface Clock {
216
- now: () => Instant;
217
- }
218
- export type NewId = () => string;
@@ -1,150 +0,0 @@
1
- import type { JsonValue } from '@boxxy/content-hash';
2
- import type { z } from 'zod';
3
- import type { ConceptPin, ItemKindName, LeverKind, LoadedRecipe, MaxAttemptsByKind, PhaseName, PipelineName, RecipeName, RulesVersion } from './core.ts';
4
- import type { Admission, FrameItem, Gate, Pool, PropagationLine, Signal, SignalKey, SignalName, View, Waiver } from './planning.ts';
5
- export type Schema<T> = z.ZodType<T>;
6
- export interface ParamKinds<P> {
7
- signal: Signal<P>;
8
- gate: Gate<P>;
9
- admission: Admission<P>;
10
- }
11
- export type ParamKindName = keyof ParamKinds<unknown>;
12
- export interface Registered<K extends ParamKindName> {
13
- readonly kind: K;
14
- readonly name: string;
15
- open: <R>(use: <P>(plugin: ParamKinds<P>[K]) => R) => R;
16
- }
17
- export interface Resolved<K extends ParamKindName> {
18
- readonly kind: K;
19
- readonly name: string;
20
- readonly key: string;
21
- open: <R>(use: <P>(plugin: ParamKinds<P>[K], params: P) => R) => R;
22
- }
23
- export type ConceptName = string;
24
- export interface Concept {
25
- name: ConceptName;
26
- version: number;
27
- signals?: Registered<'signal'>[];
28
- gates?: Registered<'gate'>[];
29
- waivers?: Waiver[];
30
- levers?: LeverKind[];
31
- filterFields?: FilterField[];
32
- }
33
- export interface FilterField {
34
- name: string;
35
- value: (item: FrameItem) => string | readonly string[] | null;
36
- }
37
- export interface PlainKinds {
38
- waiver: Waiver;
39
- 'filter-field': FilterField;
40
- lever: {
41
- readonly kind: LeverKind;
42
- };
43
- view: View;
44
- }
45
- export type PluginKindName = ParamKindName | keyof PlainKinds;
46
- export type Registry = {
47
- readonly [K in ParamKindName]: ReadonlyMap<string, Registered<K>>;
48
- } & {
49
- readonly [K in keyof PlainKinds]: ReadonlyMap<string, PlainKinds[K]>;
50
- } & {
51
- readonly pins: readonly ConceptPin[];
52
- };
53
- export interface KindRules {
54
- readonly pipeline: Pipeline;
55
- readonly recipes: Readonly<Record<PhaseName, RecipeName>>;
56
- }
57
- export interface Pipeline {
58
- readonly name: PipelineName;
59
- readonly steps: readonly PipelineStep[];
60
- }
61
- export interface PipelineStep {
62
- readonly phase: PhaseName;
63
- readonly maxAttempts: number;
64
- }
65
- export type ConceptEntry = `${string}@${number}`;
66
- export type PluginRef = string | Readonly<Record<string, JsonValue>>;
67
- export type SignalRef = SignalName | Readonly<Record<string, JsonValue>>;
68
- export interface RulesFile {
69
- readonly version: 1;
70
- readonly concepts: readonly ConceptEntry[];
71
- readonly kinds: Readonly<Record<string, {
72
- readonly pipeline: readonly string[] | PipelineName;
73
- readonly maxAttempts: Readonly<Record<string, number>>;
74
- readonly recipes: Readonly<Record<string, string>>;
75
- }>>;
76
- readonly pools: readonly {
77
- readonly name: string;
78
- readonly slots: number;
79
- readonly takes: Readonly<Record<string, JsonValue>>;
80
- readonly order: readonly SignalRef[];
81
- }[];
82
- readonly lead: readonly SignalRef[];
83
- readonly propagation: readonly {
84
- readonly value: string;
85
- readonly over: string;
86
- readonly toward: 'source' | 'target';
87
- }[];
88
- readonly recipes: Readonly<Record<string, {
89
- readonly agent: string;
90
- readonly model: string;
91
- readonly effort: string;
92
- readonly prompt: string;
93
- readonly source: string;
94
- }>>;
95
- }
96
- export interface LoadedRules {
97
- readonly version: RulesVersion;
98
- readonly commit: string;
99
- readonly registry: Registry;
100
- readonly signals: ReadonlyMap<SignalKey, Resolved<'signal'>>;
101
- readonly gates: readonly Resolved<'gate'>[];
102
- readonly kinds: ReadonlyMap<ItemKindName, KindRules>;
103
- readonly maxAttemptsByKind: MaxAttemptsByKind;
104
- readonly pools: readonly Pool[];
105
- readonly propagation: readonly PropagationLine[];
106
- readonly recipes: ReadonlyMap<RecipeName, LoadedRecipe>;
107
- }
108
- export interface LoadRejection {
109
- readonly file: string;
110
- readonly path: string;
111
- readonly reason: LoadRejectionReason;
112
- }
113
- export type LoadRejectionReason = {
114
- readonly kind: 'invalid';
115
- readonly message: string;
116
- } | {
117
- readonly kind: 'unknown-concept';
118
- readonly ref: string;
119
- } | {
120
- readonly kind: 'unknown-signal';
121
- readonly signal: string;
122
- } | {
123
- readonly kind: 'bad-plugin-params';
124
- readonly pluginKind: ParamKindName;
125
- readonly name: string;
126
- readonly message: string;
127
- } | {
128
- readonly kind: 'unknown-link-type';
129
- readonly link: string;
130
- } | {
131
- readonly kind: 'signal-without-combine';
132
- readonly signal: string;
133
- } | {
134
- readonly kind: 'missing-recipe';
135
- readonly itemKind: string;
136
- readonly phase: string;
137
- } | {
138
- readonly kind: 'missing-prompt';
139
- readonly path: string;
140
- } | {
141
- readonly kind: 'uncommitted-changes';
142
- };
143
- export type LoadResult = {
144
- readonly kind: 'loaded';
145
- readonly rules: LoadedRules;
146
- readonly warnings: readonly string[];
147
- } | {
148
- readonly kind: 'rejected';
149
- readonly rejections: readonly LoadRejection[];
150
- };
@@ -1,9 +0,0 @@
1
- import { z } from 'zod';
2
- import { brandSchemas } from './brand-schemas.ts';
3
-
4
- export const actorRefSchema = z.union([
5
- z.literal('boxxy:owner:local'),
6
- z.templateLiteral(['boxxy:runner:', brandSchemas.runnerId]),
7
- z.templateLiteral(['boxxy:attempt:', brandSchemas.attemptId]),
8
- z.templateLiteral(['boxxy:hook:', brandSchemas.attemptId]),
9
- ]);
@@ -1,71 +0,0 @@
1
- import type { AttemptId, PoolName } from './types/core.ts';
2
- import type { AnyNewFact, RowWrite, StoreChange } from './types/ports.ts';
3
-
4
- export interface TakenSlot {
5
- readonly holder: AttemptId;
6
- readonly pool: PoolName;
7
- readonly slot: number;
8
- readonly gen: number;
9
- }
10
-
11
- export interface ChangeAssignments {
12
- readonly taken: TakenSlot | null;
13
-
14
- // 0 when the store holds no lever
15
- readonly lastLeverSeq: number;
16
- }
17
-
18
- export function buildAppliedChange(
19
- change: StoreChange,
20
- assignments: ChangeAssignments,
21
- ): Pick<StoreChange, 'writes' | 'facts'> {
22
- const leverSeqs: number[] = [];
23
-
24
- const writes = change.writes.map((write): RowWrite => {
25
- if (write.op !== 'insert') {
26
- return write;
27
- }
28
-
29
- if (write.table === 'levers') {
30
- const seq = assignments.lastLeverSeq + leverSeqs.length + 1;
31
-
32
- leverSeqs.push(seq);
33
-
34
- return { ...write, row: { ...write.row, seq } };
35
- }
36
-
37
- if (write.table === 'attempts' && write.row.id === assignments.taken?.holder) {
38
- const taken = assignments.taken;
39
-
40
- return { ...write, row: { ...write.row, slot: taken.slot, slotGen: taken.gen } };
41
- }
42
-
43
- return write;
44
- });
45
-
46
- let leverFacts = 0;
47
-
48
- const facts = change.facts.map((fact): AnyNewFact => {
49
- if (fact.type === 'boxxy.lever.recorded') {
50
- const seq = leverSeqs[leverFacts];
51
-
52
- leverFacts += 1;
53
-
54
- return seq === undefined ? fact : { ...fact, payload: { ...fact.payload, seq } };
55
- }
56
-
57
- if (
58
- fact.type === 'boxxy.attempt.claimed' &&
59
- assignments.taken !== null &&
60
- fact.entity === `boxxy:attempt:${assignments.taken.holder}`
61
- ) {
62
- const taken = assignments.taken;
63
-
64
- return { ...fact, payload: { ...fact.payload, slot: taken.slot, gen: taken.gen } };
65
- }
66
-
67
- return fact;
68
- });
69
-
70
- return { writes, facts };
71
- }