@bluewombat/conductor 0.9.0 → 0.11.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.
package/SPECS.md CHANGED
@@ -129,9 +129,9 @@ Gates may send the work back before Conductor escalates.
129
129
 
130
130
  Constructor: `openConductor({ ledger, transformers, workLineStable, workspaceRoot,
131
131
  transformerDurationMs?, authority?, workLineTarget?, maxRefusals?,
132
- assemblyValidate?, assemblyFixDeclared?, observe? })`. `assemblyValidate` says
132
+ validate?, fixDeclared?, observe? })`. `validate` says
133
133
  whether a local judge runs after align, with or without an Authority.
134
- `assemblyFixDeclared` says whether a refusal has anything to repair it with; a
134
+ `fixDeclared` says whether a refusal has anything to repair it with; a
135
135
  validate refusal escalates on the spot when it does not.
136
136
  `observe` is told, mid-pass, when the work is submitted — awaited, and a throw
137
137
  from it changes nothing about the run.
@@ -212,7 +212,7 @@ One TicketStandard, one Project. Pause flag is off.
212
212
  workspace; the Integration in 4.3 takes it up.
213
213
  3. `escalated` from Implementer → `escalate({ kind: "unit" })` (Trace
214
214
  already recorded). Keep the workspace. `resumeTicket` returns the
215
- Ticket to `running`, and the unit starts again from zero.
215
+ Ticket to `running`, forgets the workspace, and the unit starts again from zero.
216
216
  4. After `markIntegrating`, if `pending_fingerprint` is set,
217
217
  `escalate({ kind: "unit" })` with a report that says the intention was
218
218
  edited in flight and what resume does. The ledger consumes the pending
@@ -231,25 +231,38 @@ One TicketStandard, one Project. Pause flag is off.
231
231
  stop. Do not align.
232
232
  2. If a parked refusal or a Submission `last_report` is set (the parked one
233
233
  wins when both are), `implement` on the ticket workspace with
234
- `stage: "assembly"`, `produce: true`, and that report **before** align.
234
+ `stage: "ticket"`, `produce: true`, and that report **before** align.
235
235
  `escalated` → `escalate({ kind: "assembly" })`.
236
236
  3. **Align.** `integrate` with WorkLineStable as **child** and the
237
237
  workspace as **parent**. What is loose in the workspace is first taken up
238
238
  as one commit whose subject is the Ticket's title (or its intention's
239
- headline); after a refusal it is the repair, with its own subject. `conflict` → return `refused` (`align-conflict`);
240
- state stays `integrating`. Cancel is still allowed. Retry `runProject`
241
- retries align. Do not `escalate({ kind: "merging" })` here: that would set
239
+ headline); after a refusal it is the repair, with its own subject. `conflict` → the work is **sent back** like any
240
+ refusal (see below), with a report that names the line and says what to do;
241
+ it is not a stop. Do not `escalate({ kind: "merging" })` here: that would set
242
242
  `born_in_merging` and block cancel before WorkLineStable is the fold parent.
243
- 4. **Validate**, when `assemblyValidate` is set — with or without an
244
- Authority. `implement` on the ticket workspace with `stage: "assembly"`
243
+ 3b. **Recheck.** Aligning brought other tickets' code in, so the unit's own
244
+ Gates run again: `implement` on the ticket workspace with
245
+ `stage: "ticket"`, `produce: false`, `recheck: true` (one attempt; Host
246
+ judges it by `ticket.build.gates`, no other list). `validated` →
247
+ `clearParkedRefusal`. `escalated` → sent back with the Gate's report and name.
248
+
249
+ **Sent back** (align conflict, failed recheck, `ticket.validate` refusal): with
250
+ `fixDeclared`, a retryable cause and budget left → `recordParkedRefusal`,
251
+ return `paused`; the next pass produces the fix, then aligns, rechecks and
252
+ validates again. Otherwise (blocking, budget spent, no fix declared) →
253
+ `escalate({ kind: "assembly" })`. **One budget** covers every loop of a ticket:
254
+ `submission.refusals + parked_refusals + submission.realigns`, against
255
+ `maxRefusals`.
256
+ 4. **Validate**, when `validate` is set — with or without an
257
+ Authority. `implement` on the ticket workspace with `stage: "ticket"`
245
258
  and `validate: true` (no gates, one attempt). `validated` →
246
259
  `clearParkedRefusal`, then continue to 5 or 6. `escalated`, retryable,
247
260
  under `maxRefusals` (the budget shared with `submission.refusals`), and
248
- `assemblyFixDeclared` → `recordParkedRefusal`, return `paused`. Do not
261
+ `fixDeclared` → `recordParkedRefusal`, return `paused`. Do not
249
262
  continue to 5 or 6. `escalated` otherwise (blocking, at the budget, or no
250
- `assembly.fix` declared) → `escalate({ kind: "assembly" })`.
263
+ `ticket.fix` declared) → `escalate({ kind: "assembly" })`.
251
264
  5. **Without an Authority.** `implement` on the ticket workspace with
252
- `stage: "assembly"` and `produce: false` (judgement only). `validated` →
265
+ `stage: "ticket"` and `produce: false` (judgement only). `validated` →
253
266
  `markMerging`. `escalated` → `escalate({ kind: "assembly" })`.
254
267
  Then **final fold**: `integrate` ticket child into WorkLineStable.
255
268
  `integrated` → `markDone`, delete ticket directory, `clearWorkspace`.
@@ -263,9 +276,16 @@ One TicketStandard, one Project. Pause flag is off.
263
276
  `escalate({ kind: "submitted" })`. Retryable refusal → `recordRefusal`
264
277
  (which also drops a stale parked refusal, if one is held),
265
278
  return `paused` (next pass repairs then aligns, then offers again).
266
- `validated` → Authority `fold`. `folded` → `markMerging` then `markDone` (with the fold's `reference`, when the Authority named one)
279
+ `validated` → ask the Authority whether the line moved on (`behind`, when
280
+ it can say): `unavailable` → `paused`; `behind` → `recordRealign` (state
281
+ `integrating`, no report kept, no fix owed) and `paused`, so the next pass
282
+ aligns, rechecks, validates, offers again and judges again; with the budget spent →
283
+ `escalate({ kind: "submitted" })`; `current`, or no `behind` → Authority
284
+ `fold`. `folded` → `markMerging` then `markDone` (with the fold's `reference`, when the Authority named one)
267
285
  (the Authority moved the work line; Conductor does not `integrate` into
268
- WorkLineStable). `conflict` → `escalate({ kind: "submitted" })`.
286
+ WorkLineStable). `conflict` → the same as `behind`: `recordRealign` and back to align
287
+ (the alignment conflicts, the fix is told); `escalate({ kind: "submitted" })` only
288
+ when the budget is spent.
269
289
 
270
290
  ## 9. Pause and interrupt
271
291
 
@@ -309,7 +329,6 @@ it was asked to run.
309
329
  | `interrupted` | A transformer returned `interrupted` |
310
330
  | `isolate-failed` | Isolation did not return `isolated` |
311
331
  | `warm-failed` | Warm (when configured) did not return `warmed` |
312
- | `align-conflict` | Align Integration returned `conflict`; state stays `integrating` |
313
332
  | `transformer-invalid` | A transformer returned `invalid-invocation` |
314
333
 
315
334
  Ledger codes (`project-busy`, `point-of-no-return`, …) pass through on `cancel`
@@ -321,9 +340,9 @@ Shipped:
321
340
 
322
341
  - Import face, `openConductor({ ledger, transformers, workLineStable, workspaceRoot })`
323
342
  - Optional Authority (`submit` / `fold`), `workLineTarget`, `maxRefusals`
324
- - Optional local `assemblyValidate`, before offer or the local judge, with or
343
+ - Optional local `validate`, before offer or the local judge, with or
325
344
  without an Authority. Its refusal is parked on the aggregate and shares the
326
- `maxRefusals` budget; `assemblyFixDeclared` says whether it escalates on the
345
+ `maxRefusals` budget; `fixDeclared` says whether it escalates on the
327
346
  spot instead
328
347
  - `reconcile`, `pause`, `resume`, `runProject`, `cancel`, `release`
329
348
  - Happy path: align, assembly judgement (`produce: false`), `markMerging`, final fold
@@ -370,6 +389,19 @@ src/
370
389
  then `escalate({ kind: "unit" })`; no `integrate`; the directory is not
371
390
  deleted by Conductor. After `resumeTicket` the unit starts from a fresh
372
391
  workspace.
392
+ 4b. `implement` `interrupted` (the process was stopped) → the Attempts that
393
+ finished are `recordAttempt`d (the interrupted one is not an Attempt), then
394
+ `releaseBail`: no Attempt is spent, the workspace stays declared and on disk.
395
+ The next pass over the Ticket finds a declared workspace that still holds
396
+ something and picks it up: no `isolate`, no second `warm`; the stage made
397
+ before the producer (the tests) is not made again when the ledger says it is
398
+ done; `implement` is given `firstAttempt` (the Attempts already recorded this
399
+ round, plus one) and, as `report`, the refusal of the last Attempt, or a
400
+ note that the pass before was stopped and left its work there. A declared
401
+ workspace that is gone or empty starts the unit from zero. `release` is the
402
+ way to start over: it drops the bail, destroys the directory and forgets it.
403
+ Conductor does not look inside the workspace, nor at the line it was cut
404
+ from: a Project that cannot pick up a stale one uses `release`.
373
405
  5. `cancel` of a `running` Ticket → ledger `cancelled`; declared directories
374
406
  destroyed. `cancel` after `markMerging` → ledger `point-of-no-return`;
375
407
  WorkLineStable untouched.
@@ -387,9 +419,8 @@ src/
387
419
  double still passes 1–9. No Transformer `dist/` and no filesystem persist are
388
420
  required for those.
389
421
 
390
- Gap, named: align `conflict` leaves `integrating` (`align-conflict`) rather than
391
- a first-class ledger kind. Do not hide that. A later WorkLedger command can
392
- close it. Assembly `escalated` uses `escalate({ kind: "assembly" })`;
422
+ An align `conflict` is not a stop: it is sent back to the fix like a refusal
423
+ (`recordParkedRefusal`), so no ledger kind is needed for it. Assembly `escalated` uses `escalate({ kind: "assembly" })`;
393
424
  `resumeTicket` returns that Ticket to `integrating`; a `unit` escalation returns
394
425
  it to `running`.
395
426
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- export type { Conductor, ConductorMoment, ConductorRefusalCode, OpenConductorOptions, ProjectRunResult, WarmOutcome, WarmPort, } from "./run/open-conductor.js";
1
+ export type { Delivery, DeliveryOptions, DeliveryRead, DeliveryStore, DeliveryUnit, } from "./run/delivery.js";
2
+ export { openDelivery, reasonOfTraces } from "./run/delivery.js";
3
+ export type { Conductor, ConductorMoment, ConductorRefusalCode, LinePort, OpenConductorOptions, ProjectRunResult, WarmOutcome, WarmPort, } from "./run/open-conductor.js";
2
4
  export { foldMessageOf, openConductor, subjectOf } from "./run/open-conductor.js";
3
- export { ticketWorkspacePath } from "./run/paths.js";
4
- export type { AuthorityFoldResult, AuthorityPort, ImplementResult, SubmitInput, SubmitResult, TransformerPort, } from "./transformers/port.js";
5
+ export { pathSegment, ticketWorkspacePath } from "./run/paths.js";
6
+ export type { AuthorityBehindResult, AuthorityFoldResult, AuthorityPort, ImplementResult, SubmitInput, SubmitResult, TransformerPort, } from "./transformers/port.js";
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,QAAQ,GACT,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,aAAa,EACb,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACjE,YAAY,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,QAAQ,EACR,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,QAAQ,GACT,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { openDelivery, reasonOfTraces } from "./run/delivery.js";
1
2
  export { foldMessageOf, openConductor, subjectOf } from "./run/open-conductor.js";
2
- export { ticketWorkspacePath } from "./run/paths.js";
3
+ export { pathSegment, ticketWorkspacePath } from "./run/paths.js";
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAWjE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,116 @@
1
+ import type { AuthorityPort, ImplementResult, ImplementTrace, TransformerPort } from "../transformers/port.js";
2
+ import type { ProjectRunResult } from "./results.js";
3
+ /**
4
+ * Getting assembled work from where it was made to where it lands.
5
+ *
6
+ * A Ticket does it to the Feature's line and a Feature does it to the Project's
7
+ * final one; the steps are the same and only what they are given differs. This
8
+ * module is the steps. It reads nothing from the ledger and writes nothing to
9
+ * it: whoever uses it says where the work is (`DeliveryUnit`), how a refusal is
10
+ * kept (`DeliveryStore`), and what the checks are (the Transformers).
11
+ *
12
+ * The steps, in order, each a pass that may end the pass early:
13
+ *
14
+ * 1. a fix, when something refused the last round and said why;
15
+ * 2. the align: the line brought into the work, and a conflict sent to the fix;
16
+ * 3. the work's own checks again, when the align or a fix changed the code
17
+ * (a Ticket has them; a Feature's are part of its review);
18
+ * 4. a local review, when the Project has one;
19
+ * — then the work is offered, which is the user's business (it is published in
20
+ * different ways) — and later:
21
+ * 5. the judgement of what was published;
22
+ * 6. whether the line moved on meanwhile, and a realign if so;
23
+ * 7. the fold.
24
+ */
25
+ /** The work to deliver, and where everything about it is. */
26
+ export type DeliveryUnit = {
27
+ /** The Ticket's or the Feature's key; every Transformer id derives from it. */
28
+ key: string;
29
+ intention: string;
30
+ title?: string | undefined;
31
+ /** What it is called in what is said about it. */
32
+ noun: "ticket" | "feature";
33
+ /** Where the work is: the Transformers produce, align and check here. */
34
+ workspace: string;
35
+ /** Where the Gates read the published work: its branch is checked out here. */
36
+ judgeWorkspace: string;
37
+ /** The line it is offered to; empty when the Project names none. */
38
+ target: string;
39
+ /** The directory holding that line, merged into the work at the align. */
40
+ line: string;
41
+ };
42
+ /** What the delivery needs to know of the unit's state, read fresh at each step. */
43
+ export type DeliveryRead = {
44
+ /** What refused the last round, when something did. The fresher of a parked refusal and a Submission's. */
45
+ sentBack?: {
46
+ report: string;
47
+ refusedBy?: string | undefined;
48
+ } | undefined;
49
+ /** Corrective rounds spent: refusals, parked refusals and realigns together. */
50
+ spent: number;
51
+ /** The Submission the work is offered under, once there is one. */
52
+ submission?: {
53
+ reference: string;
54
+ } | undefined;
55
+ };
56
+ /**
57
+ * How the unit keeps what the delivery decides. Each write answers `undefined`
58
+ * when it was done, or the result that ends the pass when it was refused.
59
+ */
60
+ export type DeliveryStore = {
61
+ read(): Promise<DeliveryRead | undefined>;
62
+ /** Stop for a person. */
63
+ freeze(input: {
64
+ kind: "assembly" | "submitted";
65
+ report?: string;
66
+ /** What refused the work, when it said its name. The report already carries it as a prefix. */
67
+ refusedBy?: string | undefined;
68
+ }): Promise<ProjectRunResult>;
69
+ /** A check refused the work before it was published: keep why, for the fix. */
70
+ park(why: {
71
+ report: string;
72
+ refusedBy?: string | undefined;
73
+ }): Promise<ProjectRunResult | undefined>;
74
+ /** Whatever sent the work back is repaired and checked. */
75
+ unpark(): Promise<ProjectRunResult | undefined>;
76
+ /** The Authority's judgement refused the Submission: keep why, and go back to the fix. */
77
+ refuse(why: {
78
+ report: string;
79
+ refusedBy?: string | undefined;
80
+ }): Promise<ProjectRunResult | undefined>;
81
+ /** The line moved on under the Submission: go back to be aligned. */
82
+ realign(): Promise<ProjectRunResult | undefined>;
83
+ };
84
+ export type DeliveryOptions = {
85
+ transformers: TransformerPort;
86
+ /** Absent: the work is not offered outside, and `settle` has nothing to ask. */
87
+ authority?: AuthorityPort | undefined;
88
+ durationMs: number;
89
+ maxRefusals: number;
90
+ /** Whether the unit's own checks run again after the align (the Ticket's `builder.gates`). */
91
+ recheck: boolean;
92
+ /** Whether a local review follows. For a Feature it is also where its checks run. */
93
+ validate: boolean;
94
+ /** Whether anything can repair a refusal. Without it a refusal is for a person. */
95
+ fixDeclared: boolean;
96
+ /** One job at a time over the directories the line lives in. */
97
+ onLine<T>(job: () => Promise<T>): Promise<T>;
98
+ /** The directory of the line brought up to date with it; false when it could not be. */
99
+ refreshLine(target: string): Promise<boolean>;
100
+ isPaused(): boolean;
101
+ };
102
+ export type Delivery = {
103
+ /** Steps 1 to 4. `ready` means the work may be offered. */
104
+ prepare(unit: DeliveryUnit, store: DeliveryStore): Promise<"ready" | ProjectRunResult>;
105
+ /** The Gates' judgement of the published work; nothing is produced. */
106
+ judge(unit: DeliveryUnit): Promise<ImplementResult>;
107
+ /** Steps 5 to 7. `folded` is the one outcome that is not a pass of its own. */
108
+ settle(unit: DeliveryUnit, store: DeliveryStore): Promise<{
109
+ folded: true;
110
+ reference?: string | undefined;
111
+ } | ProjectRunResult>;
112
+ };
113
+ /** What the last Attempt ended on, for whoever reads the escalation. */
114
+ export declare function reasonOfTraces(traces: ImplementTrace[]): string | undefined;
115
+ export declare function openDelivery(options: DeliveryOptions): Delivery;
116
+ //# sourceMappingURL=delivery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/run/delivery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,280 @@
1
+ import { foldMessageOf } from "./subject.js";
2
+ /** What the last Attempt ended on, for whoever reads the escalation. */
3
+ export function reasonOfTraces(traces) {
4
+ const last = traces.at(-1);
5
+ const report = last?.report?.trim();
6
+ if (report === undefined || report.length === 0) {
7
+ return undefined;
8
+ }
9
+ return last?.refusedBy === undefined ? report : `${last.refusedBy}: ${report}`;
10
+ }
11
+ export function openDelivery(options) {
12
+ const { transformers, authority, durationMs, maxRefusals } = options;
13
+ const refused = (code) => ({ outcome: "refused", code });
14
+ /**
15
+ * Something broke or refused the work before it was published: hand it to the
16
+ * fix with the reason. A human is asked only when nothing can fix it (no fix
17
+ * declared, a blocking refusal) or the budget is spent.
18
+ */
19
+ async function sendBack(unit, store, read, why) {
20
+ const canRepair = options.fixDeclared && why.blocking !== true && read.spent + 1 < maxRefusals;
21
+ if (!canRepair) {
22
+ return await store.freeze({
23
+ kind: "assembly",
24
+ report: why.refusedBy === undefined ? why.report : `${why.refusedBy}: ${why.report}`,
25
+ refusedBy: why.refusedBy,
26
+ });
27
+ }
28
+ const failure = await store.park(why);
29
+ if (failure !== undefined) {
30
+ return failure;
31
+ }
32
+ // Repair is on its way: do not offer, or judge, work that is already known to
33
+ // need it. The next pass produces the fix, then aligns and checks again.
34
+ return { outcome: "paused", key: unit.key };
35
+ }
36
+ /**
37
+ * The line moved on under a Submission, or refused the fold: go back to be
38
+ * aligned with it, judged and published again. Nothing was wrong with the
39
+ * work, so there is no report to repair; the round still counts.
40
+ */
41
+ async function realign(unit, store, read, why) {
42
+ if (read.spent + 1 >= maxRefusals) {
43
+ return await store.freeze({
44
+ kind: "submitted",
45
+ report: `${why} This ${unit.noun} has used all its corrective rounds, so it stops here for a person.`,
46
+ });
47
+ }
48
+ const failure = await store.realign();
49
+ if (failure !== undefined) {
50
+ return failure;
51
+ }
52
+ return { outcome: "paused", key: unit.key };
53
+ }
54
+ async function judge(unit) {
55
+ return await transformers.implement({
56
+ id: `${unit.key}:judgement`,
57
+ context: unit.key,
58
+ stage: unit.noun,
59
+ produce: false,
60
+ intention: unit.intention,
61
+ workspace: unit.judgeWorkspace,
62
+ });
63
+ }
64
+ async function prepare(unit, store) {
65
+ const read = await store.read();
66
+ if (read === undefined) {
67
+ return { outcome: "refused", code: "not-found" };
68
+ }
69
+ const line = unit.target.length > 0 ? unit.target : "the work line";
70
+ const sentBack = read.sentBack;
71
+ if (sentBack !== undefined) {
72
+ // Something refused the last round and said why. That report is the only
73
+ // reason this stage has to produce: the unit is already validated.
74
+ //
75
+ // Before the Integration below, and that order is the whole point. What a
76
+ // producer leaves is loose in the workspace; the Integration is the only
77
+ // thing that takes it up. Producing after it means the repair waits for
78
+ // the next round to be taken up at all, and what goes out meanwhile is the
79
+ // state that was already refused — the same refusal comes back, and the
80
+ // budget empties on the delay.
81
+ const remade = await transformers.implement({
82
+ id: `${unit.key}:fix`,
83
+ context: unit.key,
84
+ stage: unit.noun,
85
+ produce: true,
86
+ intention: unit.intention,
87
+ workspace: unit.workspace,
88
+ report: sentBack.report,
89
+ ...(sentBack.refusedBy === undefined ? {} : { reportFrom: sentBack.refusedBy }),
90
+ });
91
+ if (remade.outcome === "interrupted") {
92
+ return refused("interrupted");
93
+ }
94
+ if (remade.outcome === "invalid-invocation") {
95
+ return refused("transformer-invalid");
96
+ }
97
+ if (remade.outcome === "escalated") {
98
+ // The assembled work, not the unit: naming the unit here sends a reader
99
+ // to look at work that did not fail.
100
+ const why = reasonOfTraces(remade.traces);
101
+ return await store.freeze({
102
+ kind: "assembly",
103
+ ...(why === undefined ? {} : { report: why }),
104
+ });
105
+ }
106
+ }
107
+ // The line is brought current first: aligning with a copy that is behind
108
+ // would leave a Submission as far behind as it was, and send it round again.
109
+ const aligned = await options.onLine(async () => {
110
+ if (!(await options.refreshLine(unit.target))) {
111
+ return undefined;
112
+ }
113
+ return await transformers.integrate({
114
+ id: `${unit.key}:align`,
115
+ context: unit.key,
116
+ parent: unit.workspace,
117
+ child: unit.line,
118
+ durationMs,
119
+ // What is loose in the workspace here is the work the Builder made, or a
120
+ // repair of it.
121
+ subject: sentBack === undefined
122
+ ? foldMessageOf(unit.title ?? unit.intention)
123
+ : "Repair after it was refused",
124
+ mergeSubject: `Merge ${line} into the ${unit.noun}`,
125
+ });
126
+ });
127
+ if (aligned === undefined) {
128
+ return refused("line-refresh-failed");
129
+ }
130
+ if (aligned.outcome === "interrupted") {
131
+ return refused("interrupted");
132
+ }
133
+ if (aligned.outcome === "conflict") {
134
+ // Not a place to stop: the fix is told what happened and does the merge by hand.
135
+ return await sendBack(unit, store, read, {
136
+ report: `Merging the line "${line}" into this ${unit.noun} ` +
137
+ `conflicts: the ${unit.noun} and the line changed the same places. Look at what the line ` +
138
+ `changed since this ${unit.noun} started, and adapt the ${unit.noun}'s changes so they sit on top ` +
139
+ "of it. Keep what the line changed.",
140
+ refusedBy: "align",
141
+ });
142
+ }
143
+ if (aligned.outcome !== "integrated") {
144
+ return refused("transformer-invalid");
145
+ }
146
+ if (options.isPaused()) {
147
+ return { outcome: "paused", key: unit.key };
148
+ }
149
+ // The unit's own checks again, on what is there now. Skipped only when the
150
+ // code is the one they already passed: nothing was repaired this round and
151
+ // the line brought nothing in. `changed` absent means the fold could not
152
+ // say, which counts as changed.
153
+ const unchanged = !options.recheck || (sentBack === undefined && aligned.changed === false);
154
+ const rechecked = unchanged
155
+ ? { outcome: "validated", traces: [] }
156
+ : await transformers.implement({
157
+ id: `${unit.key}:recheck`,
158
+ context: unit.key,
159
+ stage: unit.noun,
160
+ produce: false,
161
+ recheck: true,
162
+ intention: unit.intention,
163
+ workspace: unit.workspace,
164
+ });
165
+ if (rechecked.outcome === "interrupted") {
166
+ return refused("interrupted");
167
+ }
168
+ if (rechecked.outcome === "invalid-invocation") {
169
+ return refused("transformer-invalid");
170
+ }
171
+ if (rechecked.outcome === "escalated") {
172
+ const last = rechecked.traces.at(-1);
173
+ return await sendBack(unit, store, read, {
174
+ report: last?.report ??
175
+ `The checks failed after the ${unit.noun} was aligned with the line, with no reason given.`,
176
+ ...(last?.refusedBy === undefined ? {} : { refusedBy: last.refusedBy }),
177
+ blocking: last?.ended === "fail-blocking",
178
+ });
179
+ }
180
+ // Whatever sent the work back is repaired and checked: it no longer asks for a fix.
181
+ const settled = await store.unpark();
182
+ if (settled !== undefined) {
183
+ return settled;
184
+ }
185
+ if (options.validate) {
186
+ const validated = await transformers.implement({
187
+ id: `${unit.key}:validate`,
188
+ context: unit.key,
189
+ stage: unit.noun,
190
+ validate: true,
191
+ intention: unit.intention,
192
+ workspace: unit.workspace,
193
+ });
194
+ if (validated.outcome === "interrupted") {
195
+ return refused("interrupted");
196
+ }
197
+ if (validated.outcome === "invalid-invocation") {
198
+ return refused("transformer-invalid");
199
+ }
200
+ if (validated.outcome === "escalated") {
201
+ const last = validated.traces.at(-1);
202
+ return await sendBack(unit, store, read, {
203
+ report: last?.report ?? `The assembled ${unit.noun} was refused, with no reason given.`,
204
+ ...(last?.refusedBy === undefined ? {} : { refusedBy: last.refusedBy }),
205
+ blocking: last?.ended === "fail-blocking",
206
+ });
207
+ }
208
+ const cleared = await store.unpark();
209
+ if (cleared !== undefined) {
210
+ return cleared;
211
+ }
212
+ }
213
+ return "ready";
214
+ }
215
+ async function settle(unit, store) {
216
+ const read = await store.read();
217
+ if (read === undefined) {
218
+ return { outcome: "refused", code: "not-found" };
219
+ }
220
+ const submission = read.submission;
221
+ if (authority === undefined || submission === undefined) {
222
+ return refused("transformer-invalid");
223
+ }
224
+ const judged = await judge(unit);
225
+ if (judged.outcome === "interrupted") {
226
+ return refused("interrupted");
227
+ }
228
+ if (judged.outcome === "invalid-invocation") {
229
+ return refused("transformer-invalid");
230
+ }
231
+ if (judged.outcome === "escalated") {
232
+ const last = judged.traces.at(-1);
233
+ const report = last?.report ?? "The Submission was refused, with no reason given.";
234
+ // A blocking refusal is not something another round repairs, and neither
235
+ // is one more refusal than the budget allows.
236
+ if (last?.ended === "fail-blocking" || read.spent + 1 >= maxRefusals) {
237
+ // The refusal that stopped it is never recorded as one — this is the
238
+ // only place it can be kept for the person who reads the escalation.
239
+ return await store.freeze({
240
+ kind: "submitted",
241
+ report: last?.refusedBy === undefined ? report : `${last.refusedBy}: ${report}`,
242
+ refusedBy: last?.refusedBy,
243
+ });
244
+ }
245
+ const failure = await store.refuse({ report, refusedBy: last?.refusedBy });
246
+ if (failure !== undefined) {
247
+ return failure;
248
+ }
249
+ // Back to where the work is made. The next pass produces with that report
250
+ // in hand and publishes to the same place.
251
+ return { outcome: "paused", key: unit.key };
252
+ }
253
+ // The Gates judged the work as it was published. If the line has moved on
254
+ // since — a person pushed to it, or later a ticket folded into it — a fold
255
+ // would produce something nobody judged. Go back to be aligned with the
256
+ // line again, then judged again, instead of folding.
257
+ const moved = await authority.behind?.({ reference: submission.reference });
258
+ if (moved?.outcome === "unavailable") {
259
+ return { outcome: "paused", key: unit.key };
260
+ }
261
+ if (moved?.outcome === "behind") {
262
+ // Back to where the work is aligned. The next pass brings the work line copy
263
+ // up to date, merges it into the work, checks it, judges it and publishes
264
+ // to the same place.
265
+ return await realign(unit, store, read, "The line moved on while this Submission waited to be folded, so what was judged is not what a fold would produce.");
266
+ }
267
+ const folded = await authority.fold({ reference: submission.reference });
268
+ if (folded.outcome === "unavailable") {
269
+ return { outcome: "paused", key: unit.key };
270
+ }
271
+ if (folded.outcome === "conflict") {
272
+ // The Authority will not fold it as it stands: go back and be aligned with the
273
+ // line again. If the alignment conflicts, the fix is told.
274
+ return await realign(unit, store, read, `The Authority refused the fold: ${folded.reason}`);
275
+ }
276
+ return { folded: true, reference: folded.reference };
277
+ }
278
+ return { prepare, judge, settle };
279
+ }
280
+ //# sourceMappingURL=delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/run/delivery.ts"],"names":[],"mappings":"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"}