@coreplane/switchboard 1.234.0 → 1.236.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/assets/Dockerfile +11 -0
- package/dist/assets/config/config.example.yaml +9 -4
- package/dist/assets/deploy/cloudflare-memory/worker.ts +12 -0
- package/dist/assets/deploy/cloudflare-resident/Dockerfile +18 -0
- package/dist/assets/deploy/cloudflare-resident/gc.ts +6 -9
- package/dist/assets/deploy/cloudflare-resident/worker.ts +225 -119
- package/dist/assets/deploy/cloudflare-sandbox/Dockerfile +11 -0
- package/dist/assets/deploy/cloudflare-sandbox/worker.ts +143 -13
- package/dist/assets/package-lock.json +212 -3
- package/dist/assets/package.json +4 -1
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/coordinator/contract.ts +24 -4
- package/dist/assets/src/core/coordinator/driver.ts +31 -3
- package/dist/assets/src/core/runEvents.ts +43 -1
- package/dist/assets/src/core/runFriction.ts +1 -0
- package/dist/assets/src/core/ship/contract.ts +3 -1
- package/dist/assets/src/core/ship/coordinator.ts +213 -29
- package/dist/assets/src/core/trace/types.ts +5 -0
- package/dist/assets/src/execution/residentCleanliness.ts +24 -0
- package/dist/assets/src/execution/residentDisk.ts +21 -10
- package/dist/assets/src/execution/residentDiskBudget.ts +7 -6
- package/dist/assets/src/execution/sandboxErrors.ts +77 -0
- package/dist/assets/src/execution/sandboxIdle.ts +220 -0
- package/dist/assets/src/execution/sandboxStart.ts +90 -0
- package/dist/assets/web/dist/.vite/manifest.json +437 -422
- package/dist/assets/web/dist/assets/{AppShell-lYVcj-k7.js → AppShell-DZdz_sl7.js} +1 -1
- package/dist/assets/web/dist/assets/{CostsPage-D-v8am88.js → CostsPage-BfJsol9y.js} +1 -1
- package/dist/assets/web/dist/assets/{DeliveryPage-CvlWP7Eq.js → DeliveryPage-CvInfu7y.js} +1 -1
- package/dist/assets/web/dist/assets/{NotFoundPage-BzWS4Ca1.js → NotFoundPage-d37EP8hS.js} +1 -1
- package/dist/assets/web/dist/assets/ResidentDetailPage-DQSD0SZD.js +1 -0
- package/dist/assets/web/dist/assets/ResidentsIndexPage-CZUGLen6.js +1 -0
- package/dist/assets/web/dist/assets/RunFoldRow-Bngn4GjF.js +9 -0
- package/dist/assets/web/dist/assets/RunRoutePage-a-tMrirB.js +6 -0
- package/dist/assets/web/dist/assets/RunsIndexPage-s0VKmRda.js +1 -0
- package/dist/assets/web/dist/assets/{RunsTabs-DEICQ4FY.js → RunsTabs-CyCdOhJ2.js} +1 -1
- package/dist/assets/web/dist/assets/ScheduledPage-ByCmyrDs.js +1 -0
- package/dist/assets/web/dist/assets/SettingsPage-DhKEokGK.js +1 -0
- package/dist/assets/web/dist/assets/{StatusDot-Ct6AtHhS.js → StatusDot-D-BPSPpw.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-qol5Boof.js → Tooltip-DPDx5tXT.js} +1 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-0eiekTHQ.js +1 -0
- package/dist/assets/web/dist/assets/{angular-html-Cw130Zyi.js → angular-html-Ni1Xil2G.js} +1 -1
- package/dist/assets/web/dist/assets/{angular-ts-DY1m4C2s.js → angular-ts-oCgo6p05.js} +1 -1
- package/dist/assets/web/dist/assets/{apl-W6Ty7v05.js → apl-CiWYl0gh.js} +1 -1
- package/dist/assets/web/dist/assets/{astro-DlLVHwVk.js → astro-B-VeKZ_J.js} +1 -1
- package/dist/assets/web/dist/assets/{blade-Bco3tDh4.js → blade-BIWEISKd.js} +1 -1
- package/dist/assets/web/dist/assets/{c-1LaFY_cj.js → c-DHxA5Byp.js} +1 -1
- package/dist/assets/web/dist/assets/{chapel-B-OvrOL5.js → chapel-D4qGLw-Q.js} +1 -1
- package/dist/assets/web/dist/assets/{cobol-Ch3EPlHu.js → cobol-BznX5Q-u.js} +1 -1
- package/dist/assets/web/dist/assets/{coffee-hZuITnto.js → coffee-CVr8Idlj.js} +1 -1
- package/dist/assets/web/dist/assets/{cpp-B8iRVo8m.js → cpp-wrk6NfW4.js} +1 -1
- package/dist/assets/web/dist/assets/{crystal-DKveI7lr.js → crystal-CGYWMeH1.js} +1 -1
- package/dist/assets/web/dist/assets/{css-_2_CD-rr.js → css-BgGytMsy.js} +1 -1
- package/dist/assets/web/dist/assets/{dist-DwtJj-ou.js → dist-DSkVB16z.js} +2 -2
- package/dist/assets/web/dist/assets/durationTone-DYogEPEk.js +1 -0
- package/dist/assets/web/dist/assets/{edge-BenMDPct.js → edge-CdR6AU9v.js} +1 -1
- package/dist/assets/web/dist/assets/{elixir-CBbdEqG6.js → elixir-CQRb3PZx.js} +1 -1
- package/dist/assets/web/dist/assets/{elm-DMub_2lY.js → elm-CpuA6W8B.js} +1 -1
- package/dist/assets/web/dist/assets/{erb-CI9He_Up.js → erb-CvlrblqH.js} +1 -1
- package/dist/assets/web/dist/assets/{favicon-BQsePYv5.js → favicon-CSt-qDvc.js} +1 -1
- package/dist/assets/web/dist/assets/{git-rebase-BBfhnyF8.js → git-rebase-COnovCVc.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-js-CR9Fxrau.js → glimmer-js-C-DS4g_J.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-ts-CwFwX_XS.js → glimmer-ts-DTkorWRI.js} +1 -1
- package/dist/assets/web/dist/assets/{glsl-Daiodp1r.js → glsl-CH51-JW7.js} +1 -1
- package/dist/assets/web/dist/assets/{graphql-DZvrsEkB.js → graphql-BO-XymNv.js} +1 -1
- package/dist/assets/web/dist/assets/{hack-BaXOzdg7.js → hack-C-N0oicf.js} +1 -1
- package/dist/assets/web/dist/assets/{haml-CMskq_VA.js → haml-BfmdtWoP.js} +1 -1
- package/dist/assets/web/dist/assets/{handlebars-Dhw_f7jD.js → handlebars-BqhO_te-.js} +1 -1
- package/dist/assets/web/dist/assets/{html-C9k99z0z.js → html-DUEZlTKV.js} +1 -1
- package/dist/assets/web/dist/assets/{html-derivative-VckPItXN.js → html-derivative-DOUJTS8A.js} +1 -1
- package/dist/assets/web/dist/assets/{http-DXU_3h9v.js → http-j7UH0Cqv.js} +1 -1
- package/dist/assets/web/dist/assets/{hurl-KU24JNdp.js → hurl-D6ZaBLJk.js} +1 -1
- package/dist/assets/web/dist/assets/indexRow-BjXBzI5Z.js +1 -0
- package/dist/assets/web/dist/assets/{java-BbZjTNgf.js → java-dugWx3wi.js} +1 -1
- package/dist/assets/web/dist/assets/{javascript-DXCdqcZZ.js → javascript-CK4GC4JO.js} +1 -1
- package/dist/assets/web/dist/assets/{jinja-pDlsjTVp.js → jinja-DrLKIyKG.js} +1 -1
- package/dist/assets/web/dist/assets/{jison-DsXDk66e.js → jison-CS1Th-TO.js} +1 -1
- package/dist/assets/web/dist/assets/{json-tCxXfRgG.js → json-CkBqdVys.js} +1 -1
- package/dist/assets/web/dist/assets/{jsx-B0ZYkCmi.js → jsx-CCxdg7n3.js} +1 -1
- package/dist/assets/web/dist/assets/{julia-BLzzeI6x.js → julia-BalKW2hA.js} +1 -1
- package/dist/assets/web/dist/assets/{just-DvD2_60c.js → just-BKw1G40D.js} +1 -1
- package/dist/assets/web/dist/assets/{latex-511zn3h7.js → latex-Dfad6ZN-.js} +1 -1
- package/dist/assets/web/dist/assets/{liquid-BD0BkMox.js → liquid-f_CMGBvd.js} +1 -1
- package/dist/assets/web/dist/assets/{indexFormat-B-pd4r7Y.js → localIso-CNA-bhS-.js} +1 -1
- package/dist/assets/web/dist/assets/{lua-NFicKm6N.js → lua-BcMK_uKM.js} +1 -1
- package/dist/assets/web/dist/assets/main-B77vAZVg.css +1 -0
- package/dist/assets/web/dist/assets/main-DR8iKpNt.js +28 -0
- package/dist/assets/web/dist/assets/{marko-1-G_nEXK.js → marko-B0oNLx2i.js} +1 -1
- package/dist/assets/web/dist/assets/{mdc-DUe3AQLp.js → mdc-Bc_MmIyq.js} +1 -1
- package/dist/assets/web/dist/assets/{nginx-Dg379_bA.js → nginx-Cmxv8RIt.js} +1 -1
- package/dist/assets/web/dist/assets/{nim-BnFq97ZO.js → nim-BtgRfaY0.js} +1 -1
- package/dist/assets/web/dist/assets/{org-F0uiwGvq.js → org-Dl9EzlHh.js} +1 -1
- package/dist/assets/web/dist/assets/{perl-B0euczkl.js → perl-BmF7x7BB.js} +1 -1
- package/dist/assets/web/dist/assets/{php-DkL3k_n7.js → php-rH6CVptQ.js} +1 -1
- package/dist/assets/web/dist/assets/{pug-L_OjjZP4.js → pug-CIN5Ccck.js} +1 -1
- package/dist/assets/web/dist/assets/{qml-BMjB00Zz.js → qml-BpLS3RFr.js} +1 -1
- package/dist/assets/web/dist/assets/{r-DoeLdnqR.js → r-BUMF3B-H.js} +1 -1
- package/dist/assets/web/dist/assets/{razor-BzYNkAWy.js → razor-B7sTBPdT.js} +1 -1
- package/dist/assets/web/dist/assets/{regexp-CPmElMk3.js → regexp-h2SvwrsJ.js} +1 -1
- package/dist/assets/web/dist/assets/residentsModel-VSJEepL1.js +1 -0
- package/dist/assets/web/dist/assets/{rst-DrsjgfI7.js → rst-DLOWEsD2.js} +1 -1
- package/dist/assets/web/dist/assets/{ruby-cB42ppvx.js → ruby-Cl_-I4k3.js} +1 -1
- package/dist/assets/web/dist/assets/{sas-R5Y3NM_I.js → sas-Cm4M-BvV.js} +1 -1
- package/dist/assets/web/dist/assets/{scss-C-zWxV9s.js → scss-CEFCEQUF.js} +1 -1
- package/dist/assets/web/dist/assets/{shellscript-oJF96aAU.js → shellscript-CE6zb5eS.js} +1 -1
- package/dist/assets/web/dist/assets/{shellsession-CznECKyi.js → shellsession-B4fDVzrM.js} +1 -1
- package/dist/assets/web/dist/assets/{soy-wjHLSRag.js → soy-DwXCMpjE.js} +1 -1
- package/dist/assets/web/dist/assets/{sql-C_BM8IOW.js → sql-DrnAKnyD.js} +1 -1
- package/dist/assets/web/dist/assets/{stata-D31HO8aQ.js → stata-BzlwPWD6.js} +1 -1
- package/dist/assets/web/dist/assets/{surrealql-CKCLyplA.js → surrealql-CeUieZXd.js} +1 -1
- package/dist/assets/web/dist/assets/{svelte-3geWk2iu.js → svelte-BERIpIKR.js} +1 -1
- package/dist/assets/web/dist/assets/{templ-DiJr_hTD.js → templ-6FSuUDwg.js} +1 -1
- package/dist/assets/web/dist/assets/{tex-BEJGWyeF.js → tex-SWCyMwNX.js} +1 -1
- package/dist/assets/web/dist/assets/{ts-tags-C8Mzdpxx.js → ts-tags-VWj7gWgY.js} +1 -1
- package/dist/assets/web/dist/assets/{tsx-UQiSm_p3.js → tsx-B6dzfL8L.js} +1 -1
- package/dist/assets/web/dist/assets/{twig-_Pvzkeo9.js → twig-BDXsr482.js} +1 -1
- package/dist/assets/web/dist/assets/{typescript-BWMkINKK.js → typescript-s100Dt8y.js} +1 -1
- package/dist/assets/web/dist/assets/{typst-Bdg9m-e7.js → typst-WfyEAUdt.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-CDZrrAZ8.js → vue-CkXOOJ-6.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-html-tAlpNhfN.js → vue-html-CEpzdcau.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-vine-C27UF_rh.js → vue-vine-D9dsfiFA.js} +1 -1
- package/dist/assets/web/dist/assets/{xml-CxeDr9Zh.js → xml-iBDofbJq.js} +1 -1
- package/dist/assets/web/dist/assets/{xsl-Bpi0uUnM.js → xsl-CqbJF4hD.js} +1 -1
- package/dist/assets/web/dist/assets/{yaml-BtUgZ1GN.js → yaml-D9i6OxYe.js} +1 -1
- package/dist/cli.js +2336 -1192
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/ResidentDetailPage-C_WNBUao.js +0 -1
- package/dist/assets/web/dist/assets/ResidentsIndexPage-D1sTyaZ_.js +0 -1
- package/dist/assets/web/dist/assets/RunFoldRow-C_bcTSjA.js +0 -5
- package/dist/assets/web/dist/assets/RunRoutePage-BWTi_6PG.js +0 -10
- package/dist/assets/web/dist/assets/RunsIndexPage-H6GkSv0a.js +0 -1
- package/dist/assets/web/dist/assets/ScheduledPage-BLcPzm1S.js +0 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-CIhTEwN7.js +0 -1
- package/dist/assets/web/dist/assets/indexRow-Bnj883ii.js +0 -1
- package/dist/assets/web/dist/assets/localIso-L06jV29p.js +0 -1
- package/dist/assets/web/dist/assets/main-CRtlGxRm.js +0 -28
- package/dist/assets/web/dist/assets/main-Dm11o0hc.css +0 -1
- package/dist/assets/web/dist/assets/residentDiskBudget-BMBKlYRH.js +0 -1
package/dist/assets/Dockerfile
CHANGED
|
@@ -87,6 +87,17 @@ RUN npm install -g @earendil-works/pi-coding-agent@0.85.1 \
|
|
|
87
87
|
&& pi --version | grep -qx '0.85.1' \
|
|
88
88
|
&& pi --help | grep -q -- '--mode <mode>'
|
|
89
89
|
|
|
90
|
+
# OpenCode, the second harness (docs/reference/specs/harness.md): `@opencode/cli`
|
|
91
|
+
# at the EXACT pin held by src/deploy/imageOpenCodeHarness.test.ts, beside pi.
|
|
92
|
+
# The wrapper's postinstall hard-links the platform binary into place, so it
|
|
93
|
+
# is the one install script allowed by name; the grep proves the binary on
|
|
94
|
+
# PATH prints the pin's version text (`opencode v2.0.3`, exactly); the npm
|
|
95
|
+
# cache (a 200 MB tarball) is dropped in the same layer. Dark until a
|
|
96
|
+
# deployment names it: nothing here starts it on its own.
|
|
97
|
+
RUN npm install -g --allow-scripts=@opencode/cli @opencode/cli@2.0.3 \
|
|
98
|
+
&& npm cache clean --force \
|
|
99
|
+
&& opencode --version | grep -qx 'opencode v2.0.3'
|
|
100
|
+
|
|
90
101
|
# Non-root user; agents run bash with this user's (container-scoped) permissions.
|
|
91
102
|
RUN useradd -m -u 1001 switchboard
|
|
92
103
|
WORKDIR /app
|
|
@@ -311,10 +311,15 @@ workspaceDir: ./workspaces
|
|
|
311
311
|
# them the request is refused naming what is missing. Per unit: at most
|
|
312
312
|
# `maxRounds` review rounds and `maxMinutes` minutes of wall clock — whichever
|
|
313
313
|
# hits first ends the unit, and each child round's own budget is clipped to the
|
|
314
|
-
# remaining time.
|
|
315
|
-
#
|
|
316
|
-
#
|
|
317
|
-
#
|
|
314
|
+
# remaining time. The pipeline is budgeted for the loop, not one round: the
|
|
315
|
+
# coding child's directive is additionally capped to leave two review rounds and
|
|
316
|
+
# one merge poll (11 minutes) on the clock, so a child that uses its whole
|
|
317
|
+
# budget still hands the review its time — which is why `maxMinutes` must be an
|
|
318
|
+
# integer >= 14 (the loop's reserve plus one round). `maxMinutes` is the ship
|
|
319
|
+
# preset's declared budget: a channel or user `boundary.maxMinutes` and a
|
|
320
|
+
# per-message `budget:` directive clip it like any preset's, and the card says
|
|
321
|
+
# so. Defaults shown; `maxRounds` must be an integer >= 1; any other key under
|
|
322
|
+
# `ship` fails the load by name.
|
|
318
323
|
# ship:
|
|
319
324
|
# maxRounds: 3 # review rounds per unit
|
|
320
325
|
# maxMinutes: 120 # the ship preset's wall-clock budget in minutes (the registry's default)
|
|
@@ -1807,6 +1807,18 @@ export class RunHistoryDO extends DurableObject<Env> {
|
|
|
1807
1807
|
this.ctx.storage.transactionSync(() => {
|
|
1808
1808
|
result = this.upsertInTransaction(record, proposal);
|
|
1809
1809
|
});
|
|
1810
|
+
// A coordinator child closed OUTSIDE the ledger's finish — the run loop or
|
|
1811
|
+
// a reclaim writing an `interrupted` record, the pi harness's typed restart,
|
|
1812
|
+
// a resume abandoning a lost workspace — still wakes its parent's wait at
|
|
1813
|
+
// once (run-history item 47): the same `run-finished-<runId>` event rides
|
|
1814
|
+
// this commit. The tombstone a run writes at its start is excluded (its
|
|
1815
|
+
// `finishedAt` equals `startedAt`); the parent confirms by `read-record`
|
|
1816
|
+
// before it acts, so a duplicate send is harmless.
|
|
1817
|
+
if (result.stored && record.parentInstanceId !== undefined && record.finishedAt > record.startedAt) {
|
|
1818
|
+
const event = await sendRunFinished(this.env.SHIP_COORDINATOR, record);
|
|
1819
|
+
if (event.kind === "failed")
|
|
1820
|
+
console.warn(`[runs/put] ${record.id} → ${event.type} not delivered to ${event.instance}: ${event.reason}`);
|
|
1821
|
+
}
|
|
1810
1822
|
if ((await this.ctx.storage.getAlarm()) === null)
|
|
1811
1823
|
await this.ctx.storage.setAlarm(systemClock() + RUN_SWEEP_INTERVAL_MS);
|
|
1812
1824
|
return result;
|
|
@@ -201,6 +201,18 @@ RUN npm install -g @earendil-works/pi-coding-agent@0.85.1 \
|
|
|
201
201
|
&& pi --version | grep -qx '0.85.1' \
|
|
202
202
|
&& pi --help | grep -q -- '--mode <mode>'
|
|
203
203
|
|
|
204
|
+
# OpenCode, the second harness (docs/reference/specs/harness.md): `@opencode/cli`
|
|
205
|
+
# at the EXACT pin held by src/deploy/imageOpenCodeHarness.test.ts, beside pi.
|
|
206
|
+
# The wrapper's postinstall hard-links the platform binary into place, so it
|
|
207
|
+
# is the one install script allowed by name; the grep proves the binary on
|
|
208
|
+
# PATH prints the pin's version text (`opencode v2.0.3`, exactly); the npm
|
|
209
|
+
# cache (a 200 MB tarball) is dropped in the same layer, and the proof runs
|
|
210
|
+
# again as worker1 below. Dark until a deployment names it: nothing here
|
|
211
|
+
# starts it on its own.
|
|
212
|
+
RUN npm install -g --allow-scripts=@opencode/cli @opencode/cli@2.0.3 \
|
|
213
|
+
&& npm cache clean --force \
|
|
214
|
+
&& opencode --version | grep -qx 'opencode v2.0.3'
|
|
215
|
+
|
|
204
216
|
# Agent commands never run as root (repo code runs unprivileged, one user per
|
|
205
217
|
# thread — docs/reference/specs/resident-repos.md). The SDK's exec has no user/uid option
|
|
206
218
|
# (verified against 0.13.0-next.751.1), so the container server itself runs as
|
|
@@ -230,6 +242,12 @@ RUN su -s /bin/bash worker1 -c "playwright screenshot --viewport-size=640,480 'd
|
|
|
230
242
|
# own, named by PI_CODING_AGENT_DIR at start).
|
|
231
243
|
RUN su -s /bin/bash worker1 -c "pi --version | grep -qx '0.85.1'"
|
|
232
244
|
|
|
245
|
+
# OpenCode once more, as worker1: a run's server is started as the thread's
|
|
246
|
+
# user through the same `su`, so the BUILD proves an unprivileged user finds
|
|
247
|
+
# the pin on PATH and the binary runs without a writable home (its roots are
|
|
248
|
+
# the run's own, named by the XDG variables at start).
|
|
249
|
+
RUN su -s /bin/bash worker1 -c "opencode --version | grep -qx 'opencode v2.0.3'"
|
|
250
|
+
|
|
233
251
|
# bun once more, as worker1: a thread's `bun install` runs as the thread's user
|
|
234
252
|
# through the same `su`, whose PATH is /etc/environment's rather than this
|
|
235
253
|
# file's — so the BUILD proves that PATH resolves the pin, not the base's bun.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Residency garbage collection — the PURE decision logic, kept free of
|
|
2
2
|
// the Sandbox SDK and DO storage so it runs under plain-Node vitest
|
|
3
3
|
// (gc.test.ts). worker.ts feeds it what it observed (mirror refs, the GitHub
|
|
4
|
-
// pulls list,
|
|
4
|
+
// pulls list, ops in flight, live views) and acts on the answers.
|
|
5
5
|
//
|
|
6
6
|
// Two mechanisms:
|
|
7
7
|
// 1. Event-triggered reclamation: after every refresh-cycle `fetch --prune`,
|
|
@@ -79,9 +79,6 @@ export interface ReclaimInput {
|
|
|
79
79
|
isDefaultRef: boolean;
|
|
80
80
|
/** Thread exec/read/write currently running on this binding. */
|
|
81
81
|
busy: number;
|
|
82
|
-
/** Tree cleanliness as the thread user; `null` = the runtime is down, so
|
|
83
|
-
* the tree is already gone with the disk and there is nothing to preserve. */
|
|
84
|
-
clean: boolean | null;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
84
|
/** The PR that decided the fate (for the audit trail): the open one, else the
|
|
@@ -97,13 +94,14 @@ export type ReclaimWhy =
|
|
|
97
94
|
| "fate-unknown"
|
|
98
95
|
| "busy"
|
|
99
96
|
| "re-attached"
|
|
100
|
-
| "dirty"
|
|
101
97
|
| Extract<RefFate, "gone" | "merged" | "closed">;
|
|
102
98
|
|
|
103
99
|
/** Evict this binding now? A finished ref (gone/merged/closed) is reclaimed
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
100
|
+
* when nothing runs on it — and nothing else is asked. What its tree holds
|
|
101
|
+
* is never a reason to keep it: a run starts from a clean tree, so dirt in a
|
|
102
|
+
* tree no run is using protects nothing (the next attach wipes it); the
|
|
103
|
+
* Worker measures and records what it removes instead. Keeps are named so
|
|
104
|
+
* the pass is auditable. */
|
|
107
105
|
export function reclaimDecision(input: ReclaimInput): { reclaim: boolean; why: ReclaimWhy } {
|
|
108
106
|
if (input.isDefaultRef) return { reclaim: false, why: "default-ref" };
|
|
109
107
|
switch (input.fate) {
|
|
@@ -115,7 +113,6 @@ export function reclaimDecision(input: ReclaimInput): { reclaim: boolean; why: R
|
|
|
115
113
|
return { reclaim: false, why: "fate-unknown" };
|
|
116
114
|
}
|
|
117
115
|
if (input.busy > 0) return { reclaim: false, why: "busy" };
|
|
118
|
-
if (input.clean === false) return { reclaim: false, why: "dirty" };
|
|
119
116
|
return { reclaim: true, why: input.fate };
|
|
120
117
|
}
|
|
121
118
|
|