@tacuchi/agent-workflow-cli 21.8.0 → 21.9.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/dist/adapters/git-cli.js +217 -0
- package/dist/adapters/git-cli.js.map +1 -1
- package/dist/application/flow/flow-service.js +7 -0
- package/dist/application/flow/flow-service.js.map +1 -1
- package/dist/application/flow/internal-actions.js +5 -0
- package/dist/application/flow/internal-actions.js.map +1 -1
- package/dist/application/history-table.js +37 -0
- package/dist/application/history-table.js.map +1 -1
- package/dist/application/local-proposal.js +37 -0
- package/dist/application/local-proposal.js.map +1 -1
- package/dist/application/retirement/apply.js +448 -0
- package/dist/application/retirement/apply.js.map +1 -0
- package/dist/application/retirement/attribution.js +395 -0
- package/dist/application/retirement/attribution.js.map +1 -0
- package/dist/application/retirement/graph.js +196 -0
- package/dist/application/retirement/graph.js.map +1 -0
- package/dist/application/retirement/history-events.js +158 -0
- package/dist/application/retirement/history-events.js.map +1 -0
- package/dist/application/retirement/journal.js +113 -0
- package/dist/application/retirement/journal.js.map +1 -0
- package/dist/application/retirement/prepare.js +233 -0
- package/dist/application/retirement/prepare.js.map +1 -0
- package/dist/application/retirement/preview.js +101 -0
- package/dist/application/retirement/preview.js.map +1 -0
- package/dist/application/retirement/resolve.js +356 -0
- package/dist/application/retirement/resolve.js.map +1 -0
- package/dist/application/session-create-service.js +103 -12
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/session-custody-recorder.js +137 -0
- package/dist/application/session-custody-recorder.js.map +1 -0
- package/dist/application/session-custody-service.js +171 -0
- package/dist/application/session-custody-service.js.map +1 -0
- package/dist/application/status-service.js +5 -0
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/workline-index-service.js +31 -0
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/application/worktree-service.js +47 -1
- package/dist/application/worktree-service.js.map +1 -1
- package/dist/cli/commands/index.js +6 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/retirement.js +137 -0
- package/dist/cli/commands/retirement.js.map +1 -0
- package/dist/cli/commands/session-create.js +4 -1
- package/dist/cli/commands/session-create.js.map +1 -1
- package/dist/cli/help-groups.js +4 -0
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/domain/flow/authority.js +8 -0
- package/dist/domain/flow/authority.js.map +1 -1
- package/dist/domain/retirement/proposal.js +83 -0
- package/dist/domain/retirement/proposal.js.map +1 -0
- package/dist/domain/retirement/selector.js +109 -0
- package/dist/domain/retirement/selector.js.map +1 -0
- package/dist/domain/session/custody.js +176 -0
- package/dist/domain/session/custody.js.map +1 -0
- package/dist/domain/workline-node.js +56 -0
- package/dist/domain/workline-node.js.map +1 -0
- package/package.json +1 -1
- package/skills/w/commands/discard.md +49 -0
- package/skills/w/commands/reset.md +50 -0
- package/skills/w/context/MANIFEST.json +147 -139
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `apply`: the coordinator that gives a retirement exactly two stable outcomes.
|
|
3
|
+
*
|
|
4
|
+
* Everything expensive, refusable or reversible happens BEFORE one hinge, and
|
|
5
|
+
* everything after it is unconditional completion. That is the whole design, and
|
|
6
|
+
* it is the shape the T3.1 probe demonstrated rather than one assumed here:
|
|
7
|
+
*
|
|
8
|
+
* 1. recompute — the proposal is built again under the lock; a different
|
|
9
|
+
* digest means the world moved and the approval no longer fits
|
|
10
|
+
* 2. journal — the only trace that exists before any effect, and it lives
|
|
11
|
+
* OUTSIDE every folder this operation may delete
|
|
12
|
+
* 3. stage — restores written into quarantine; the workspace untouched
|
|
13
|
+
* 4. reverts — built in a temporary detached worktree, held by private refs
|
|
14
|
+
* 5. COMMIT POINT — the ref's compare-and-swap, or the HISTORY row when there is
|
|
15
|
+
* no git side. Exactly one, and nothing else can be it
|
|
16
|
+
* 6. complete — sync the tree, move the staged bytes in, remove what was
|
|
17
|
+
* retired, invalidate bindings, append the row
|
|
18
|
+
* 7. cleanup — quarantine, private refs, journal
|
|
19
|
+
*
|
|
20
|
+
* A failure at any step before 5 leaves the observable state identical, because
|
|
21
|
+
* nothing observable was touched: the quarantine and the private refs are invisible
|
|
22
|
+
* to every Workline surface, and dropping them is not a compensation — it is
|
|
23
|
+
* discarding something nobody could see. A failure after 5 is not rolled back,
|
|
24
|
+
* ever: the ref cannot move backwards without rewriting history. It is FINISHED, by
|
|
25
|
+
* this process or by the next one that reads the journal.
|
|
26
|
+
*/
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
import { baselineDigest } from "../../domain/session/custody.js";
|
|
29
|
+
import { localDateIso } from "../dates.js";
|
|
30
|
+
import { withCwdLock } from "../lock-service.js";
|
|
31
|
+
import { invalidateBindingsTo } from "../session-binding-service.js";
|
|
32
|
+
import { appendEvent, eventOf, hasEvent } from "./history-events.js";
|
|
33
|
+
import { dropJournal, listPendingJournals, openJournal, quarantinePath, writeJournal, } from "./journal.js";
|
|
34
|
+
import { prepareRetirement } from "./prepare.js";
|
|
35
|
+
export async function applyRetirement(deps, input) {
|
|
36
|
+
const locked = await withCwdLock(deps.fs, deps.paths, () => runUnderLock(deps, input));
|
|
37
|
+
if ("error" in locked) {
|
|
38
|
+
return {
|
|
39
|
+
ok: false,
|
|
40
|
+
rejection: {
|
|
41
|
+
code: "EVIDENCE_MISSING",
|
|
42
|
+
message: locked.error,
|
|
43
|
+
candidates: [],
|
|
44
|
+
action: "esperá a que se libere el lock del workspace y volvé a aplicar",
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return locked;
|
|
49
|
+
}
|
|
50
|
+
async function runUnderLock(deps, input) {
|
|
51
|
+
// 1 — the proposal is computed AGAIN, from the live workspace. Trusting the one
|
|
52
|
+
// that produced the preview would authorize a state that may no longer exist.
|
|
53
|
+
const prepared = await prepareRetirement(deps, input);
|
|
54
|
+
if (!prepared.ok)
|
|
55
|
+
return { ok: false, rejection: prepared.rejection };
|
|
56
|
+
const proposal = prepared.proposal;
|
|
57
|
+
if (proposal.digest !== input.approval) {
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
rejection: {
|
|
61
|
+
code: "EVIDENCE_MISSING",
|
|
62
|
+
message: "lo aprobado no es lo que se aplicaría: el alcance cambió desde la vista previa",
|
|
63
|
+
candidates: [input.approval, proposal.digest],
|
|
64
|
+
action: "volvé a correr `prepare`, leé la vista previa vigente y aprobá ese digest",
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const stale = await staleReadSet(deps, proposal);
|
|
69
|
+
if (stale !== null)
|
|
70
|
+
return { ok: false, rejection: stale };
|
|
71
|
+
// An operation whose row is already in HISTORY is one that passed its commit
|
|
72
|
+
// point in a previous process. Retrying the same approval finishes it; it never
|
|
73
|
+
// starts a second one.
|
|
74
|
+
if (await hasEvent(deps.fs, deps.paths, proposal.digest)) {
|
|
75
|
+
return finish(deps, journalFor(deps, proposal), true);
|
|
76
|
+
}
|
|
77
|
+
const journal = journalFor(deps, proposal);
|
|
78
|
+
await writeJournal(deps.fs, deps.paths, journal);
|
|
79
|
+
const staged = await stage(deps, journal);
|
|
80
|
+
if (!staged.ok) {
|
|
81
|
+
await rollback(deps, journal);
|
|
82
|
+
return { ok: false, rejection: staged.rejection };
|
|
83
|
+
}
|
|
84
|
+
const built = await buildReverts(deps, journal);
|
|
85
|
+
if (!built.ok) {
|
|
86
|
+
await rollback(deps, journal);
|
|
87
|
+
return { ok: false, rejection: built.rejection };
|
|
88
|
+
}
|
|
89
|
+
await writeJournal(deps.fs, deps.paths, {
|
|
90
|
+
...journal,
|
|
91
|
+
phase: "ready",
|
|
92
|
+
private_refs: built.refs,
|
|
93
|
+
...(built.tip === null ? {} : { prepared_tip: built.tip }),
|
|
94
|
+
});
|
|
95
|
+
// 5 — THE COMMIT POINT. What it publishes is the commit this process just built
|
|
96
|
+
// and verified against the sealed TREE — the reverts' identity is free to differ
|
|
97
|
+
// between two builds (a commit id carries its timestamp), their result is not.
|
|
98
|
+
const publication = proposal.publication;
|
|
99
|
+
if (publication !== null && built.tip !== null) {
|
|
100
|
+
const swap = await deps.git.updateRefCas(publication.repo, publication.ref, built.tip, publication.expected_old);
|
|
101
|
+
if (!swap.ok) {
|
|
102
|
+
await rollback(deps, { ...journal, private_refs: built.refs });
|
|
103
|
+
return {
|
|
104
|
+
ok: false,
|
|
105
|
+
rejection: {
|
|
106
|
+
code: "EVIDENCE_MISSING",
|
|
107
|
+
message: `'${publication.ref}' se movió mientras se preparaba el retiro: ${swap.why}`,
|
|
108
|
+
candidates: [publication.ref],
|
|
109
|
+
action: "nada se aplicó; volvé a preparar sobre el estado vigente",
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const committed = {
|
|
115
|
+
...journal,
|
|
116
|
+
phase: "committed",
|
|
117
|
+
private_refs: built.refs,
|
|
118
|
+
...(built.tip === null ? {} : { prepared_tip: built.tip }),
|
|
119
|
+
};
|
|
120
|
+
await writeJournal(deps.fs, deps.paths, committed);
|
|
121
|
+
return finish(deps, committed, false);
|
|
122
|
+
}
|
|
123
|
+
function journalFor(deps, proposal) {
|
|
124
|
+
return openJournal({
|
|
125
|
+
proposal,
|
|
126
|
+
quarantine: quarantinePath(deps.paths, proposal.digest),
|
|
127
|
+
opened: localDateIso((deps.now ?? (() => new Date()))()),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Whether the world the proposal was computed from still holds.
|
|
132
|
+
*
|
|
133
|
+
* The digest already covers the closure and the bytes; this covers the things the
|
|
134
|
+
* proposal READ to decide — a custody, a document, a HEAD. A retirement authorized
|
|
135
|
+
* against one state and applied against another is the single failure mode the
|
|
136
|
+
* whole seal exists to prevent, and re-reading is the only way to know.
|
|
137
|
+
*/
|
|
138
|
+
async function staleReadSet(deps, proposal) {
|
|
139
|
+
for (const restore of proposal.restores) {
|
|
140
|
+
const absolute = join(deps.paths.workspaceDir(), restore.path);
|
|
141
|
+
const current = (await deps.fs.exists(absolute))
|
|
142
|
+
? baselineDigest(await deps.fs.readText(absolute))
|
|
143
|
+
: null;
|
|
144
|
+
if (current === restore.current_digest)
|
|
145
|
+
continue;
|
|
146
|
+
return {
|
|
147
|
+
code: "EVIDENCE_MISSING",
|
|
148
|
+
message: `'${restore.path}' cambió después de preparar el retiro`,
|
|
149
|
+
candidates: [restore.path],
|
|
150
|
+
action: "volvé a preparar: restaurar sobre bytes que ya no son los que se mostraron perdería ese cambio",
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* 3 — the restores land in quarantine, on the same filesystem as their destination.
|
|
157
|
+
*
|
|
158
|
+
* Same filesystem so the final move is a rename: the completion after the commit
|
|
159
|
+
* point has to be as short and as unlikely to fail as possible, because it is the
|
|
160
|
+
* part that cannot be rolled back.
|
|
161
|
+
*/
|
|
162
|
+
async function stage(deps, journal) {
|
|
163
|
+
try {
|
|
164
|
+
await deps.fs.mkdirp(journal.quarantine);
|
|
165
|
+
for (const [index, restore] of journal.proposal.restores.entries()) {
|
|
166
|
+
if (!restore.existed || restore.content === null)
|
|
167
|
+
continue;
|
|
168
|
+
await deps.fs.writeText(stagedPath(journal, index), restore.content);
|
|
169
|
+
}
|
|
170
|
+
return { ok: true };
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
return {
|
|
174
|
+
ok: false,
|
|
175
|
+
rejection: {
|
|
176
|
+
code: "EVIDENCE_MISSING",
|
|
177
|
+
message: `no se pudo preparar la cuarentena del retiro: ${message(err)}`,
|
|
178
|
+
candidates: [],
|
|
179
|
+
action: "liberá espacio o revisá permisos y volvé a aplicar; no se aplicó ningún efecto",
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function stagedPath(journal, index) {
|
|
185
|
+
return join(journal.quarantine, `restore-${index}`);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* 4 — the revert commits, built for real but held only by a private ref.
|
|
189
|
+
*
|
|
190
|
+
* Private because a name under `refs/aw-op/` is invisible to every branch listing
|
|
191
|
+
* and to every reader, so a process that dies here leaves objects nobody can see
|
|
192
|
+
* rather than a branch somebody might mistake for work. The rehearsal already
|
|
193
|
+
* proved they apply; this builds the ones that will actually be published.
|
|
194
|
+
*/
|
|
195
|
+
async function buildReverts(deps, journal) {
|
|
196
|
+
const publication = journal.proposal.publication;
|
|
197
|
+
if (publication === null)
|
|
198
|
+
return { ok: true, refs: [], tip: null };
|
|
199
|
+
const worktree = join(journal.quarantine, "revert-tree");
|
|
200
|
+
const privateRef = `refs/aw-op/${journal.digest.slice(0, 12)}/tip`;
|
|
201
|
+
try {
|
|
202
|
+
await deps.git.worktreeAddDetached(publication.repo, worktree, publication.expected_old ?? "HEAD");
|
|
203
|
+
for (const revert of journal.proposal.reverts) {
|
|
204
|
+
const attempt = await deps.git.rehearseRevert(worktree, revert.commit, revert.mainline);
|
|
205
|
+
if (!attempt.ok) {
|
|
206
|
+
return {
|
|
207
|
+
ok: false,
|
|
208
|
+
rejection: {
|
|
209
|
+
code: "EVIDENCE_MISSING",
|
|
210
|
+
message: `el revert de ${revert.commit.slice(0, 12)} ya no aplica limpio`,
|
|
211
|
+
candidates: attempt.conflicted,
|
|
212
|
+
action: "nada se aplicó; volvé a preparar sobre el estado vigente",
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
await deps.git.commitIn(worktree, `revert ${revert.commit.slice(0, 12)} (aw retiro)`);
|
|
217
|
+
}
|
|
218
|
+
const tip = await deps.git.refValue(worktree, "HEAD");
|
|
219
|
+
const tree = tip === null ? null : await deps.git.treeOf(worktree, tip);
|
|
220
|
+
// The RESULT is what was approved. Comparing the commit id instead would fail
|
|
221
|
+
// on nothing but the second it was built in.
|
|
222
|
+
if (tip === null || tree !== publication.expected_tree) {
|
|
223
|
+
return {
|
|
224
|
+
ok: false,
|
|
225
|
+
rejection: {
|
|
226
|
+
code: "EVIDENCE_MISSING",
|
|
227
|
+
message: "los reverts reconstruidos no producen el resultado aprobado",
|
|
228
|
+
candidates: [publication.expected_tree, tree ?? "sin árbol"],
|
|
229
|
+
action: "nada se aplicó; volvé a preparar y aprobá la vista previa vigente",
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
await deps.git.setRef(publication.repo, privateRef, tip);
|
|
234
|
+
return { ok: true, refs: [privateRef], tip };
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
return {
|
|
238
|
+
ok: false,
|
|
239
|
+
rejection: {
|
|
240
|
+
code: "EVIDENCE_MISSING",
|
|
241
|
+
message: `no se pudieron construir los reverts: ${message(err)}`,
|
|
242
|
+
candidates: [],
|
|
243
|
+
action: "nada se aplicó; revisá el repositorio y volvé a aplicar",
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
finally {
|
|
248
|
+
try {
|
|
249
|
+
await deps.git.worktreeRemove(publication.repo, worktree);
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// Reported by `worktree list` as an orphan: a visible state, not a silent one.
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 6 and 7 — everything after the commit point, and it never gives up.
|
|
258
|
+
*
|
|
259
|
+
* Each step is idempotent so a second entry finishes what a first one started: a
|
|
260
|
+
* path already restored is written with the same bytes, a folder already gone is a
|
|
261
|
+
* no-op removal, a row already there is recognized. There is deliberately no
|
|
262
|
+
* failure path back: the ref moved, and the only honest direction is forward.
|
|
263
|
+
*/
|
|
264
|
+
async function finish(deps, journal, alreadyApplied) {
|
|
265
|
+
const proposal = journal.proposal;
|
|
266
|
+
const publication = proposal.publication;
|
|
267
|
+
if (publication !== null) {
|
|
268
|
+
// The compare-and-swap moved the REF; the working tree still holds the old
|
|
269
|
+
// content. Its syncability was the precondition checked before the swap.
|
|
270
|
+
await deps.git.syncTree(publication.repo, publication.ref);
|
|
271
|
+
}
|
|
272
|
+
const restored = [];
|
|
273
|
+
for (const [index, restore] of proposal.restores.entries()) {
|
|
274
|
+
await applyRestore(deps, journal, restore, index);
|
|
275
|
+
restored.push(restore.path);
|
|
276
|
+
}
|
|
277
|
+
const removed = [];
|
|
278
|
+
for (const target of proposal.deletes) {
|
|
279
|
+
await deps.fs.remove(join(deps.paths.workspaceDir(), target.path));
|
|
280
|
+
removed.push(target.path);
|
|
281
|
+
}
|
|
282
|
+
const units = await reconcileUnits(deps, proposal);
|
|
283
|
+
const invalidated = await dropBindings(deps, proposal);
|
|
284
|
+
await appendEvent(deps.fs, deps.paths, eventOf(proposal, (deps.now ?? (() => new Date()))()));
|
|
285
|
+
for (const ref of journal.private_refs) {
|
|
286
|
+
if (publication === null)
|
|
287
|
+
continue;
|
|
288
|
+
await deps.git.deleteRef(publication.repo, ref);
|
|
289
|
+
}
|
|
290
|
+
await deps.fs.remove(journal.quarantine);
|
|
291
|
+
await dropJournal(deps.fs, deps.paths, journal.digest);
|
|
292
|
+
return {
|
|
293
|
+
ok: true,
|
|
294
|
+
result: {
|
|
295
|
+
digest: proposal.digest,
|
|
296
|
+
mode: proposal.mode,
|
|
297
|
+
target: proposal.event.key,
|
|
298
|
+
removed,
|
|
299
|
+
restored,
|
|
300
|
+
bindings_invalidated: invalidated,
|
|
301
|
+
published: publication === null
|
|
302
|
+
? null
|
|
303
|
+
: {
|
|
304
|
+
ref: publication.ref,
|
|
305
|
+
from: publication.expected_old,
|
|
306
|
+
// What really landed, read back from the journal that recorded it.
|
|
307
|
+
to: journal.prepared_tip ?? publication.expected_tree,
|
|
308
|
+
},
|
|
309
|
+
pending_remote_publication: proposal.reverts
|
|
310
|
+
.filter((r) => r.published)
|
|
311
|
+
.map((r) => `${r.alias}:${r.commit.slice(0, 12)}`),
|
|
312
|
+
units_released: units.released,
|
|
313
|
+
pending_reconciliation: units.unreconciled,
|
|
314
|
+
already_applied: alreadyApplied,
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Give back every isolation unit of the retired sessions, or report the ones git
|
|
320
|
+
* refuses to release.
|
|
321
|
+
*
|
|
322
|
+
* Past the commit point there is no failing, so a unit that still holds
|
|
323
|
+
* uncommitted work is REPORTED rather than forced away: removing a tree to tidy up
|
|
324
|
+
* is the one way this feature could destroy work nobody authorized. The branch is
|
|
325
|
+
* never deleted — it is the only thing keeping the session's commits reachable.
|
|
326
|
+
*/
|
|
327
|
+
async function reconcileUnits(deps, proposal) {
|
|
328
|
+
const released = [];
|
|
329
|
+
const unreconciled = [];
|
|
330
|
+
for (const unit of proposal.units) {
|
|
331
|
+
const name = `${unit.alias}:${unit.branch}`;
|
|
332
|
+
if (unit.repo.length === 0) {
|
|
333
|
+
unreconciled.push(name);
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
await deps.git.worktreeRemove(unit.repo, unit.path);
|
|
338
|
+
await deps.git.worktreePrune(unit.repo);
|
|
339
|
+
released.push(name);
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
unreconciled.push(name);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return { released, unreconciled };
|
|
346
|
+
}
|
|
347
|
+
/** Only the associations pointing at the retired sessions; never anybody else's. */
|
|
348
|
+
async function dropBindings(deps, proposal) {
|
|
349
|
+
let invalidated = 0;
|
|
350
|
+
for (const entry of proposal.closure) {
|
|
351
|
+
if (entry.node.kind !== "session")
|
|
352
|
+
continue;
|
|
353
|
+
const dropped = await invalidateBindingsTo(deps.fs, deps.paths, entry.node.key);
|
|
354
|
+
if (dropped.ok)
|
|
355
|
+
invalidated += dropped.removed;
|
|
356
|
+
}
|
|
357
|
+
return invalidated;
|
|
358
|
+
}
|
|
359
|
+
/** A restore is bytes back, or a path back out of existence. */
|
|
360
|
+
async function applyRestore(deps, journal, restore, index) {
|
|
361
|
+
const destination = join(deps.paths.workspaceDir(), restore.path);
|
|
362
|
+
if (!restore.existed) {
|
|
363
|
+
await deps.fs.remove(destination);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const staged = stagedPath(journal, index);
|
|
367
|
+
// The staged copy is preferred — it is the one the journal put there — and the
|
|
368
|
+
// content in the proposal is the fallback for a re-entry whose quarantine is
|
|
369
|
+
// already gone. Both are the same bytes; only one of them may still exist.
|
|
370
|
+
const content = (await deps.fs.exists(staged))
|
|
371
|
+
? await deps.fs.readText(staged)
|
|
372
|
+
: (restore.content ?? "");
|
|
373
|
+
await deps.fs.writeText(destination, content);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Undo what was never visible.
|
|
377
|
+
*
|
|
378
|
+
* Called only from BEFORE the commit point, and it is not a compensation: the
|
|
379
|
+
* quarantine and the private refs were never observable, so dropping them returns
|
|
380
|
+
* the workspace to a state it never left.
|
|
381
|
+
*/
|
|
382
|
+
async function rollback(deps, journal) {
|
|
383
|
+
const publication = journal.proposal.publication;
|
|
384
|
+
for (const ref of journal.private_refs) {
|
|
385
|
+
if (publication === null)
|
|
386
|
+
continue;
|
|
387
|
+
await deps.git.deleteRef(publication.repo, ref);
|
|
388
|
+
}
|
|
389
|
+
await deps.fs.remove(journal.quarantine);
|
|
390
|
+
await dropJournal(deps.fs, deps.paths, journal.digest);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Finish or discard every operation left in flight — the re-entry.
|
|
394
|
+
*
|
|
395
|
+
* The side of the commit point is read from the WORLD and never from the journal's
|
|
396
|
+
* own phase: the ref is at the prepared tip, or the row is already in HISTORY, or
|
|
397
|
+
* neither. A phase written by a process that then died is a claim about the past;
|
|
398
|
+
* the ref is the present.
|
|
399
|
+
*/
|
|
400
|
+
export async function recoverPendingRetirements(deps) {
|
|
401
|
+
const pending = await listPendingJournals(deps.fs, deps.paths);
|
|
402
|
+
const recovered = [];
|
|
403
|
+
for (const journal of pending.journals) {
|
|
404
|
+
const past = await commitPointPassed(deps, journal);
|
|
405
|
+
if (past) {
|
|
406
|
+
await finish(deps, journal, true);
|
|
407
|
+
recovered.push({
|
|
408
|
+
digest: journal.digest,
|
|
409
|
+
outcome: "completed",
|
|
410
|
+
target: journal.proposal.event.key,
|
|
411
|
+
});
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
await rollback(deps, journal);
|
|
415
|
+
recovered.push({
|
|
416
|
+
digest: journal.digest,
|
|
417
|
+
outcome: "rolled-back",
|
|
418
|
+
target: journal.proposal.event.key,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
return { recovered, unreadable: pending.unreadable };
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Which side of the commit point the WORLD is on.
|
|
425
|
+
*
|
|
426
|
+
* Three readings, and none of them is the journal's own phase. The row is the
|
|
427
|
+
* strongest — it only exists past the point. Then the commit this run recorded
|
|
428
|
+
* building. And failing both, the ref's own TREE: the identity of the revert commit
|
|
429
|
+
* may differ from the one a previous process built, but the result it produced
|
|
430
|
+
* cannot, so the tree is what says whether the result is already published.
|
|
431
|
+
*/
|
|
432
|
+
async function commitPointPassed(deps, journal) {
|
|
433
|
+
if (await hasEvent(deps.fs, deps.paths, journal.digest))
|
|
434
|
+
return true;
|
|
435
|
+
const publication = journal.proposal.publication;
|
|
436
|
+
if (publication === null)
|
|
437
|
+
return false;
|
|
438
|
+
const current = await deps.git.refValue(publication.repo, publication.ref);
|
|
439
|
+
if (current === null)
|
|
440
|
+
return false;
|
|
441
|
+
if (journal.prepared_tip !== undefined && current === journal.prepared_tip)
|
|
442
|
+
return true;
|
|
443
|
+
return (await deps.git.treeOf(publication.repo, current)) === publication.expected_tree;
|
|
444
|
+
}
|
|
445
|
+
function message(err) {
|
|
446
|
+
return err instanceof Error ? err.message : String(err);
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/application/retirement/apply.ts"],"names":[],"mappings":"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"}
|