toolroll 0.9.92 → 0.9.94
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/CHANGELOG.md +87 -0
- package/dist/activity-line.d.ts +7 -4
- package/dist/activity-line.js +9 -7
- package/dist/agent-fence.d.ts +4 -0
- package/dist/agent-fence.js +4 -1
- package/dist/approval-authority.d.ts +7 -1
- package/dist/approval-authority.js +11 -2
- package/dist/approval-password.d.ts +31 -0
- package/dist/approval-password.js +26 -0
- package/dist/assignment-status.d.ts +1 -1
- package/dist/assignment-ui.js +3 -3
- package/dist/assignment.js +16 -3
- package/dist/boot-identity.d.ts +2 -1
- package/dist/boot-identity.js +6 -4
- package/dist/bounded-spawn.d.ts +57 -0
- package/dist/bounded-spawn.js +220 -0
- package/dist/browser/terminal.js +42 -42
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +26 -26
- package/dist/browser-crew.js +2 -2
- package/dist/browser-shell.d.ts +1 -1
- package/dist/browser-shell.js +2 -2
- package/dist/browser-workspace.d.ts +48 -7
- package/dist/browser-workspace.js +3 -3
- package/dist/builder-restart.d.ts +21 -0
- package/dist/builder-restart.js +50 -0
- package/dist/builder.d.ts +4 -0
- package/dist/builder.js +73 -25
- package/dist/chat-acceptance.js +1 -1
- package/dist/chat-actions.d.ts +12 -2
- package/dist/chat-actions.js +25 -2
- package/dist/chat-channel.js +11 -0
- package/dist/chat-decide.d.ts +7 -2
- package/dist/chat-decide.js +37 -9
- package/dist/chat-quiet.js +3 -3
- package/dist/chat-voice.d.ts +1 -1
- package/dist/chat-voice.js +2 -2
- package/dist/check-facts.d.ts +126 -0
- package/dist/check-facts.js +318 -0
- package/dist/check-failure.d.ts +22 -3
- package/dist/check-failure.js +57 -13
- package/dist/check-levels-ui.d.ts +4 -0
- package/dist/check-levels-ui.js +10 -1
- package/dist/check-load.d.ts +85 -0
- package/dist/check-load.js +147 -0
- package/dist/check-only-standing.d.ts +36 -0
- package/dist/check-only-standing.js +39 -0
- package/dist/check-only.d.ts +15 -0
- package/dist/check-only.js +99 -0
- package/dist/check-report.d.ts +7 -0
- package/dist/check-report.js +4 -3
- package/dist/check-stamp.d.ts +46 -0
- package/dist/check-stamp.js +93 -0
- package/dist/checkout-cleanup.d.ts +36 -5
- package/dist/checkout-cleanup.js +166 -14
- package/dist/cli-help.d.ts +4 -1
- package/dist/cli-help.js +47 -30
- package/dist/cli.js +16 -1
- package/dist/code-extract.d.ts +44 -0
- package/dist/code-extract.js +88 -0
- package/dist/code-map-acts.d.ts +24 -0
- package/dist/code-map-acts.js +53 -0
- package/dist/code-map-admission.d.ts +52 -0
- package/dist/code-map-admission.js +295 -0
- package/dist/code-map-build.d.ts +63 -0
- package/dist/code-map-build.js +415 -0
- package/dist/code-map-cli.d.ts +153 -0
- package/dist/code-map-cli.js +103 -0
- package/dist/code-map-main.d.ts +1 -0
- package/dist/code-map-main.js +48 -0
- package/dist/code-map-read.d.ts +106 -0
- package/dist/code-map-read.js +171 -0
- package/dist/code-map-report.d.ts +37 -0
- package/dist/code-map-report.js +95 -0
- package/dist/code-map-shape.d.ts +172 -0
- package/dist/code-map-shape.js +327 -0
- package/dist/code-map-store.d.ts +136 -0
- package/dist/code-map-store.js +233 -0
- package/dist/coding-provider.d.ts +2 -0
- package/dist/coding-provider.js +3 -2
- package/dist/coding-update.js +3 -2
- package/dist/coding-workspace.js +4 -4
- package/dist/console-chrome.js +2 -2
- package/dist/containment.d.ts +5 -0
- package/dist/containment.js +14 -1
- package/dist/contracts/chat-actions.d.ts +9 -0
- package/dist/contracts/chat-actions.js +2 -0
- package/dist/contracts/cli.d.ts +52 -0
- package/dist/contracts/cli.js +4 -0
- package/dist/contracts/console-api.d.ts +12 -5
- package/dist/contracts/console-api.js +12 -5
- package/dist/contracts/gateway-tools.d.ts +17 -0
- package/dist/contracts/gateway-tools.js +3 -1
- package/dist/contracts/lead-tools.d.ts +61 -0
- package/dist/contracts/lead-tools.js +10 -1
- package/dist/contracts/project-knowledge.d.ts +38 -5
- package/dist/contracts/project-knowledge.js +11 -5
- package/dist/contracts/project-memory.d.ts +3 -1
- package/dist/contracts/project-memory.js +3 -2
- package/dist/contracts/release-check.d.ts +25 -1
- package/dist/contracts/release-check.js +19 -0
- package/dist/contracts/storage.d.ts +14 -0
- package/dist/contracts/storage.js +3 -1
- package/dist/contracts/store-json.d.ts +2 -0
- package/dist/contracts/youiyoux-request.d.ts +1 -1
- package/dist/contracts/youiyoux-request.js +1 -1
- package/dist/desktop-access.js +6 -2
- package/dist/desktop-update.d.ts +2 -2
- package/dist/desktop-update.js +13 -9
- package/dist/dispatch.js +18 -15
- package/dist/dispose.js +8 -2
- package/dist/easy-start.js +2 -3
- package/dist/eval-hooks.d.ts +55 -0
- package/dist/eval-hooks.js +227 -4
- package/dist/evals.js +2 -1
- package/dist/fast-start.d.ts +136 -0
- package/dist/fast-start.js +431 -0
- package/dist/fast-terms.d.ts +9 -0
- package/dist/fast-terms.js +23 -0
- package/dist/fenced-check-coverage.d.ts +62 -0
- package/dist/fenced-check-coverage.js +54 -0
- package/dist/first-run.js +1 -1
- package/dist/flaky-ci.d.ts +31 -0
- package/dist/flaky-ci.js +149 -0
- package/dist/flaky-cli.d.ts +60 -0
- package/dist/flaky-cli.js +60 -0
- package/dist/flaky.d.ts +83 -0
- package/dist/flaky.js +264 -0
- package/dist/flow-card-task.js +3 -0
- package/dist/flow-triggers.d.ts +1 -1
- package/dist/flow-triggers.js +1 -1
- package/dist/github-import.d.ts +62 -0
- package/dist/github-import.js +146 -0
- package/dist/guides.js +15 -10
- package/dist/invoke.d.ts +5 -1
- package/dist/invoke.js +49 -14
- package/dist/job-object-helper.ps1 +10 -3
- package/dist/keymap.d.ts +41 -0
- package/dist/keymap.js +51 -0
- package/dist/knowledge-cli.js +1 -1
- package/dist/knowledge-ui.d.ts +21 -4
- package/dist/knowledge-ui.js +75 -7
- package/dist/laptop-background.d.ts +16 -0
- package/dist/laptop-background.js +108 -2
- package/dist/lead-context.js +1 -1
- package/dist/lead-contract.d.ts +1 -1
- package/dist/lead-contract.js +2 -2
- package/dist/lead-progress.js +3 -0
- package/dist/lead-status.d.ts +2 -0
- package/dist/lead-status.js +6 -2
- package/dist/lead-tools.js +51 -2
- package/dist/lead.js +1 -1
- package/dist/lesson-notes.d.ts +81 -0
- package/dist/lesson-notes.js +336 -0
- package/dist/limits-ui.js +1 -1
- package/dist/local-owner.d.ts +1 -1
- package/dist/local-owner.js +11 -0
- package/dist/machine-check.d.ts +16 -0
- package/dist/machine-check.js +26 -0
- package/dist/machine-identity.d.ts +75 -0
- package/dist/machine-identity.js +170 -0
- package/dist/mcp-core.js +11 -1
- package/dist/memory-cli.d.ts +300 -1
- package/dist/memory-cli.js +62 -9
- package/dist/memory-pass.d.ts +16 -0
- package/dist/memory-pass.js +67 -3
- package/dist/memory-tidy.d.ts +181 -0
- package/dist/memory-tidy.js +523 -0
- package/dist/memory-use.d.ts +35 -0
- package/dist/memory-use.js +109 -0
- package/dist/merge-checklist.d.ts +55 -0
- package/dist/merge-checklist.js +182 -0
- package/dist/needs-you.d.ts +32 -13
- package/dist/needs-you.js +108 -49
- package/dist/nightly-github.d.ts +2 -0
- package/dist/nightly-github.js +4 -4
- package/dist/operate-remote-arguments.js +6 -1
- package/dist/operate-remote.js +3 -1
- package/dist/operate.d.ts +6 -1
- package/dist/operate.js +540 -70
- package/dist/phase-routing.js +2 -2
- package/dist/plain-schema.d.ts +23 -0
- package/dist/plain-schema.js +94 -0
- package/dist/plain-words.d.ts +20 -0
- package/dist/plain-words.js +66 -0
- package/dist/planner.js +2 -1
- package/dist/process-liveness.d.ts +2 -0
- package/dist/process-liveness.js +61 -17
- package/dist/project-delete-ui.d.ts +7 -2
- package/dist/project-delete-ui.js +12 -1
- package/dist/project-delete.js +13 -2
- package/dist/project-knowledge.d.ts +18 -11
- package/dist/project-knowledge.js +39 -9
- package/dist/project-learning.d.ts +2 -1
- package/dist/project-learning.js +15 -45
- package/dist/project-memory.d.ts +5 -0
- package/dist/project-memory.js +22 -2
- package/dist/proof.js +30 -5
- package/dist/provider-auth.js +1 -1
- package/dist/publish.js +9 -1
- package/dist/pull-request-flow.js +5 -0
- package/dist/push.d.ts +26 -3
- package/dist/push.js +55 -15
- package/dist/release-adapters.d.ts +9 -0
- package/dist/release-adapters.js +87 -1
- package/dist/release-approval.d.ts +191 -0
- package/dist/release-approval.js +382 -0
- package/dist/release-auto.js +26 -17
- package/dist/release-card.d.ts +74 -6
- package/dist/release-card.js +179 -23
- package/dist/release-carry.d.ts +7 -2
- package/dist/release-carry.js +39 -9
- package/dist/release-cli.d.ts +4 -0
- package/dist/release-cli.js +38 -23
- package/dist/release-coverage.js +1 -1
- package/dist/release-next.d.ts +48 -0
- package/dist/release-next.js +161 -0
- package/dist/release.d.ts +50 -1
- package/dist/release.js +118 -11
- package/dist/remote-destination.d.ts +36 -0
- package/dist/remote-destination.js +217 -0
- package/dist/remote-main.d.ts +48 -0
- package/dist/remote-main.js +84 -5
- package/dist/repository-context.d.ts +3 -2
- package/dist/repository-context.js +112 -70
- package/dist/restart-certification.d.ts +1 -0
- package/dist/restart-certification.js +8 -6
- package/dist/result-acts.d.ts +29 -21
- package/dist/result-acts.js +36 -25
- package/dist/result-follow-ups.d.ts +2 -2
- package/dist/result-follow-ups.js +18 -4
- package/dist/result-review.d.ts +1 -1
- package/dist/route-change-check.d.ts +4 -0
- package/dist/route-change-check.js +13 -0
- package/dist/route-change.d.ts +22 -0
- package/dist/route-change.js +89 -0
- package/dist/route-hooks.js +3 -2
- package/dist/route-results.d.ts +6 -1
- package/dist/route-results.js +14 -5
- package/dist/run-closeout.d.ts +1 -1
- package/dist/run-closeout.js +7 -5
- package/dist/runner-process.js +3 -2
- package/dist/runner.js +2 -1
- package/dist/scope.d.ts +6 -1
- package/dist/scope.js +22 -9
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +24 -18
- package/dist/server/chat.js +14 -12
- package/dist/server/chrome.d.ts +1 -1
- package/dist/server/chrome.js +26 -35
- package/dist/server/console.css +23 -0
- package/dist/server/guards.js +4 -0
- package/dist/server/home.d.ts +6 -0
- package/dist/server/home.js +21 -13
- package/dist/server/http.js +1 -1
- package/dist/server/kit.js +1 -1
- package/dist/server/merge-ready-view.d.ts +10 -0
- package/dist/server/merge-ready-view.js +30 -0
- package/dist/server/pages-assets.d.ts +1 -0
- package/dist/server/pages-assets.js +8 -5
- package/dist/server/pages.js +103 -82
- package/dist/server/render-chat.js +2 -2
- package/dist/server/render-code-map.d.ts +30 -0
- package/dist/server/render-code-map.js +137 -0
- package/dist/server/render-flaky.d.ts +20 -0
- package/dist/server/render-flaky.js +59 -0
- package/dist/server/render-history.js +1 -1
- package/dist/server/render-new-task.d.ts +26 -1
- package/dist/server/render-new-task.js +30 -5
- package/dist/server/render-pages.d.ts +1 -175
- package/dist/server/render-pages.js +38 -313
- package/dist/server/render-projects.d.ts +2 -1
- package/dist/server/render-projects.js +9 -7
- package/dist/server/render-release.d.ts +19 -0
- package/dist/server/render-release.js +84 -0
- package/dist/server/render-results.d.ts +2 -2
- package/dist/server/render-results.js +71 -73
- package/dist/server/render-tasks.d.ts +13 -2
- package/dist/server/render-tasks.js +156 -139
- package/dist/server/retired-routes.d.ts +17 -0
- package/dist/server/retired-routes.js +53 -0
- package/dist/server/route-table.d.ts +4 -1
- package/dist/server/route-table.js +52 -13
- package/dist/server/settings.js +129 -22
- package/dist/server/task-views.js +61 -26
- package/dist/server/tasks.d.ts +17 -6
- package/dist/server/tasks.js +273 -338
- package/dist/server/welcome.js +1 -1
- package/dist/settings-groups-ui.js +1 -1
- package/dist/setup-guide.d.ts +2 -2
- package/dist/stop-proof.d.ts +67 -0
- package/dist/stop-proof.js +295 -0
- package/dist/storage-sweep-process.js +1 -1
- package/dist/storage-sweep.d.ts +5 -3
- package/dist/storage-sweep.js +30 -9
- package/dist/storage-ui.js +28 -17
- package/dist/storage.d.ts +27 -2
- package/dist/storage.js +39 -2
- package/dist/store.d.ts +148 -34
- package/dist/store.js +626 -177
- package/dist/surface.js +46 -5
- package/dist/sweep-quarantine.d.ts +1 -0
- package/dist/sweep-quarantine.js +6 -4
- package/dist/tamper-scan.d.ts +4 -0
- package/dist/tamper-scan.js +90 -0
- package/dist/task-aliases.d.ts +5 -0
- package/dist/task-aliases.js +9 -0
- package/dist/task-control.js +4 -1
- package/dist/task-outcome-cli.d.ts +2 -0
- package/dist/task-outcome-cli.js +36 -17
- package/dist/task-sizing.d.ts +5 -0
- package/dist/task-sizing.js +2 -0
- package/dist/task-source.d.ts +7 -0
- package/dist/task-source.js +14 -0
- package/dist/task-status.d.ts +9 -0
- package/dist/task-status.js +40 -49
- package/dist/teardown-git.d.ts +16 -0
- package/dist/teardown-git.js +63 -5
- package/dist/telegram-progress.js +5 -3
- package/dist/telegram-status.js +6 -4
- package/dist/test-infra.d.ts +8 -0
- package/dist/test-infra.js +18 -0
- package/dist/tidy.js +1 -1
- package/dist/toolroll-update-ui.js +2 -2
- package/dist/toolroll-update.js +18 -5
- package/dist/tui-contract.d.ts +24 -0
- package/dist/tui-source.js +67 -8
- package/dist/tui.js +51 -51
- package/dist/vanished-retry.d.ts +30 -0
- package/dist/vanished-retry.js +174 -0
- package/dist/work-index.d.ts +2 -0
- package/dist/work-index.js +82 -70
- package/dist/work-summary.d.ts +2 -2
- package/dist/work-summary.js +2 -0
- package/dist/workspace-ui.d.ts +4 -2
- package/dist/workspace-ui.js +28 -22
- package/dist/worktree.d.ts +12 -3
- package/dist/worktree.js +68 -13
- package/package.json +1 -1
- package/dist/server/render-next.d.ts +0 -63
- package/dist/server/render-next.js +0 -109
package/dist/storage-ui.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Settings → Storage: how much space task checkouts use, what a clean-up would free now, the
|
|
2
|
+
* Settings → Storage: how much space task folders (checkouts) use, what a clean-up would free now, what the next sweep's
|
|
3
|
+
* idle cleanup takes and when, the folders with uncommitted changes a person decides about, the clean-up's preview (what
|
|
3
4
|
* goes, what stays and why, with paths) and its Remove behind the password, what the last storage sweep removed and
|
|
4
5
|
* when (its paths in a disclosure) and why the next one waits, what landed work's teardown did and still waits on (in a
|
|
5
|
-
* disclosure, with the one-time command for older work), and when a
|
|
6
|
-
*
|
|
6
|
+
* disclosure, with the one-time command for older work), and when a task's clean folder goes by itself. An instance
|
|
7
|
+
* operator's page, built from the revamp kit; the Settings frame adds the title.
|
|
7
8
|
*/
|
|
8
9
|
import { homedir } from "node:os";
|
|
9
10
|
import { basename } from "node:path";
|
|
10
11
|
import { html, joinHtml } from "./html.js";
|
|
11
12
|
import { previewDigest, whyWords } from "./checkout-cleanup.js";
|
|
12
|
-
import { CLEANUP_CHOICES, bytesWords } from "./storage.js";
|
|
13
|
+
import { CLEANUP_CHOICES, IDLE_CHOICES, bytesWords, idleCleanupWords } from "./storage.js";
|
|
13
14
|
import { sweepDetails, sweepWords } from "./storage-sweep.js";
|
|
14
15
|
import { sweepScheduleWords } from "./storage-sweep-schedule.js";
|
|
15
16
|
import { codeLine, disclose, formRow, icon, infoLine, note, notice, select, settingsRecord, settingsSection } from "./server/kit.js";
|
|
@@ -48,17 +49,18 @@ function sweepHtml(sweep) {
|
|
|
48
49
|
/** Landed work, on demand: what its teardown did, what it waits on and why, and the one-time command for older work. */
|
|
49
50
|
function landedHtml(landed) {
|
|
50
51
|
const done = landed.completed + landed.checkouts + landed.branches === 0 ? "No landed work cleaned up yet."
|
|
51
|
-
: `${plural(landed.completed, "task")} marked complete; ${plural(landed.checkouts, "
|
|
52
|
+
: `${plural(landed.completed, "task")} marked complete; ${plural(landed.checkouts, "task folder")} and ${plural(landed.branches, "local branch", "local branches")} removed.`;
|
|
52
53
|
const waiting = landed.waiting.length === 0 ? "" : html `<div data-landed-waiting>${note(`Waiting (${landed.waiting.length}):`)}${landed.waiting.map(one => settingsRecord({ title: html `<span class="k-mono">${tilde(one.target)}</span>`, sub: one.why ?? "" }))}</div>`;
|
|
53
54
|
return html `<div data-landed>${disclose("Landed work", joinHtml([note(done), waiting,
|
|
54
55
|
note(html `For work that landed before this: <code class="k-mono">toolroll storage clean --landed</code> shows what would go; add <code class="k-mono">--yes</code> to do it.`)]))}</div>`;
|
|
55
56
|
}
|
|
56
|
-
/** One
|
|
57
|
+
/** One task folder: the task it was for, its size, where it is (the home folder as ~), why it stays, and Discard when it has changes. */
|
|
57
58
|
function item(one) {
|
|
58
|
-
|
|
59
|
+
// Under "Uncommitted changes" the heading already says why it stays.
|
|
60
|
+
const why = one.why === null || one.why === "has changes" ? "" : `${whyWords(one)[0].toUpperCase()}${whyWords(one).slice(1)}`;
|
|
59
61
|
const discard = one.why === "has changes"
|
|
60
62
|
? disclose("Discard", kitSectionForm({ proof: "storage-discard", action: "/settings/storage/discard", id: `discard-${previewId(one.path)}`, hidden: { path: one.path },
|
|
61
|
-
save: { label: "Discard changes", variant: "danger" }, body: note("Throws away this
|
|
63
|
+
save: { label: "Discard changes", variant: "danger" }, body: note("Throws away this folder and its uncommitted changes. Its branch stays.") }))
|
|
62
64
|
: "";
|
|
63
65
|
return settingsRecord({ title: one.taskId ?? basename(one.path), attrs: { "data-checkout": one.path }, when: bytesWords(one.bytes),
|
|
64
66
|
sub: html `<span class="k-mono">${tilde(one.path)}</span>${why === "" ? "" : ` · ${why}`}`, more: discard });
|
|
@@ -67,29 +69,38 @@ function item(one) {
|
|
|
67
69
|
const previewId = (path) => path.replace(/[^a-z0-9]+/gi, "-").replace(/^-|-$/g, "").slice(-48) || "checkout";
|
|
68
70
|
export function storageHtml(view, said) {
|
|
69
71
|
const { plan } = view;
|
|
70
|
-
const facts = [plural(plan.count, "
|
|
72
|
+
const facts = [plural(plan.count, "task folder"), `${plan.waitingReview} waiting for review`, `${plan.withChanges} with uncommitted changes`].join(" · ");
|
|
71
73
|
const frees = plan.go.length === 0 ? "Nothing to clean up now." : `Cleaning up now frees about ${bytesWords(plan.freeBytes)}.`;
|
|
72
|
-
const checkouts = settingsSection({ id: "checkouts", title: `
|
|
74
|
+
const checkouts = settingsSection({ id: "checkouts", title: `Task folders use ${bytesWords(plan.totalBytes)}`,
|
|
73
75
|
body: joinHtml([
|
|
74
76
|
said.problem ? notice(said.problem) : said.said ? infoLine(said.said) : "",
|
|
75
77
|
html `<p class="k-note" data-checkout-bytes="${plan.totalBytes}">${facts}</p>`,
|
|
76
78
|
view.measured ?? "",
|
|
77
79
|
html `<p class="k-note" data-clean-bytes="${plan.freeBytes}">${frees}</p>`,
|
|
80
|
+
html `<p class="k-note" data-idle-bytes="${plan.idleBytes}">${idleCleanupWords(plan)}</p>`,
|
|
78
81
|
view.sweep === undefined ? "" : sweepHtml(view.sweep),
|
|
79
82
|
view.landed === undefined ? "" : landedHtml(view.landed),
|
|
80
83
|
]) });
|
|
81
84
|
const remove = plan.go.length === 0 ? "" : kitSectionForm({ proof: "storage-clean", action: "/settings/storage/clean", id: "clean-form", hidden: { preview: previewDigest(plan) },
|
|
82
|
-
save: { label: `Remove ${plural(plan.go.length, "
|
|
85
|
+
save: { label: `Remove ${plural(plan.go.length, "task folder")}`, variant: "danger" }, body: html `` });
|
|
83
86
|
const goes = plan.go.length === 0 ? note("Nothing to remove now.")
|
|
84
87
|
: html `<div data-goes>${plan.go.map(one => item(one))}</div>`;
|
|
85
|
-
const
|
|
88
|
+
const changed = plan.stay.filter(one => one.why === "has changes");
|
|
89
|
+
const others = plan.stay.filter(one => one.why !== "has changes");
|
|
90
|
+
const stays = others.length === 0 ? "" : disclose(`Stays (${others.length})`, html `<div data-stays>${others.map(one => item(one))}</div>`);
|
|
91
|
+
// Never removed by itself: a person looks at each and keeps it or discards it.
|
|
92
|
+
const changes = changed.length === 0 ? "" : settingsSection({ id: "uncommitted", title: `Uncommitted changes (${changed.length})`,
|
|
93
|
+
lead: `${changed.length === 1 ? "This folder has" : "These folders have"} work that isn't on any branch, about ${bytesWords(changed.reduce((sum, one) => sum + one.bytes, 0))}. Toolroll never removes ${changed.length === 1 ? "it" : "them"} by itself.`,
|
|
94
|
+
body: html `<div data-uncommitted>${changed.map(one => item(one))}</div>` });
|
|
86
95
|
const cleanUp = settingsSection({ id: "clean-up", title: "Clean up now",
|
|
87
|
-
lead: plan.go.length === 0 ? "Nothing to remove now." : `Removes ${plural(plan.go.length, "
|
|
96
|
+
lead: plan.go.length === 0 ? "Nothing to remove now." : `Removes ${plural(plan.go.length, "task folder")}, about ${bytesWords(plan.freeBytes)}. Their branches stay, so nothing committed is lost.`,
|
|
88
97
|
body: html `<div data-clean-up>${joinHtml([plan.go.length === 0 ? "" : goes, remove, stays])}</div>` });
|
|
89
98
|
const automatic = settingsSection({ id: "automatic-cleanup", title: "Automatic cleanup",
|
|
90
|
-
lead: "
|
|
99
|
+
lead: "Branches stay, so a later run, revision or retry makes a new folder. Folders with uncommitted changes, commits on no branch, or in use are kept. When a task's work is already in main, Toolroll marks it complete and removes its folder and local branches.",
|
|
91
100
|
body: kitSectionForm({ proof: "storage-cleanup", action: "/settings/storage", id: "cleanup-form", gate: true,
|
|
92
|
-
body: formRow("Remove a finished task's clean
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
body: joinHtml([formRow("Remove a finished task's clean folder", null, select({ id: "storage-cleanup", name: "cleanup", label: "Remove a finished task's clean folder", current: plan.cleanup,
|
|
102
|
+
items: CLEANUP_CHOICES.map(one => [one.value, one.label]) }), "inline"),
|
|
103
|
+
formRow("Remove an idle task's clean folder", "Even with its result waiting for review or the task unfinished. Idle means no run, no one acting on it and no open lease.", select({ id: "storage-idle", name: "idle", label: "Remove an idle task's clean folder", current: plan.idle,
|
|
104
|
+
items: IDLE_CHOICES.map(one => [one.value, one.label]) }), "inline")]) }) });
|
|
105
|
+
return joinHtml([checkouts, changes, cleanUp, automatic]);
|
|
95
106
|
}
|
package/dist/storage.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Store } from "./store.js";
|
|
2
|
-
import { type CheckoutCleanup } from "./contracts/storage.js";
|
|
2
|
+
import { type CheckoutCleanup, type CheckoutIdle } from "./contracts/storage.js";
|
|
3
3
|
/** Settings → Storage: when a finished task's clean checkout is removed. One row, or none (the default). */
|
|
4
4
|
export declare const CHECKOUT_CLEANUP_SCHEMA = "\nCREATE TABLE IF NOT EXISTS checkout_cleanup_setting (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n cleanup TEXT NOT NULL CHECK (cleanup IN ('finished', '2d', '7d', 'never')),\n updated_by TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n";
|
|
5
5
|
/**
|
|
@@ -10,7 +10,7 @@ export declare const CHECKOUT_CLEANUP_SCHEMA = "\nCREATE TABLE IF NOT EXISTS che
|
|
|
10
10
|
export declare const LANDED_CLEANUP_SCHEMA = "\nCREATE TABLE IF NOT EXISTS landed_cleanup (\n id INTEGER PRIMARY KEY,\n repo TEXT NOT NULL,\n task_id TEXT,\n run_id INTEGER,\n receipt TEXT,\n head TEXT NOT NULL,\n how TEXT NOT NULL CHECK (how IN ('merged', 'in-main', 'content-in-main')),\n reason TEXT NOT NULL,\n completed INTEGER NOT NULL DEFAULT 0 CHECK (completed IN (0, 1)),\n actor TEXT NOT NULL,\n created_at TEXT NOT NULL,\n finished_at TEXT\n);\nCREATE UNIQUE INDEX IF NOT EXISTS landed_cleanup_result ON landed_cleanup(run_id) WHERE run_id IS NOT NULL;\nCREATE TABLE IF NOT EXISTS landed_cleanup_item (\n id INTEGER PRIMARY KEY,\n cleanup INTEGER NOT NULL REFERENCES landed_cleanup(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK (kind IN ('checkout', 'branch')),\n repo TEXT NOT NULL,\n target TEXT NOT NULL,\n expect TEXT NOT NULL,\n state TEXT NOT NULL DEFAULT 'pending' CHECK (state IN ('pending', 'done', 'kept')),\n why TEXT,\n done_at TEXT\n);\nCREATE UNIQUE INDEX IF NOT EXISTS landed_cleanup_pending ON landed_cleanup_item(kind, repo, target) WHERE state = 'pending';\nCREATE INDEX IF NOT EXISTS landed_cleanup_item_of ON landed_cleanup_item(cleanup, state);\n";
|
|
11
11
|
/** What each storage sweep or clean-up by hand did (storage-sweep.ts): the latest few. */
|
|
12
12
|
export declare const STORAGE_SWEEP_SCHEMA = "\nCREATE TABLE IF NOT EXISTS storage_sweep (\n id INTEGER PRIMARY KEY,\n at TEXT NOT NULL,\n source TEXT NOT NULL CHECK (source IN ('automatic', 'manual')),\n actor TEXT NOT NULL,\n result TEXT NOT NULL\n);\n";
|
|
13
|
-
export type { CheckoutCleanup } from "./contracts/storage.js";
|
|
13
|
+
export type { CheckoutCleanup, CheckoutIdle } from "./contracts/storage.js";
|
|
14
14
|
export declare const DEFAULT_CLEANUP: CheckoutCleanup;
|
|
15
15
|
export declare const CLEANUP_CHOICES: readonly {
|
|
16
16
|
value: CheckoutCleanup;
|
|
@@ -20,6 +20,31 @@ export declare const CLEANUP_CHOICES: readonly {
|
|
|
20
20
|
/** `finished` (or complete, cancelled), `2d`, `7d` (or week, 1w), `never` (or off); undefined when it's none of those. */
|
|
21
21
|
export declare function parseCleanup(text: string): CheckoutCleanup | undefined;
|
|
22
22
|
export declare function cleanupWords(cleanup: CheckoutCleanup): string;
|
|
23
|
+
/**
|
|
24
|
+
* v151: how long a task stays idle (no run, no person's act, no open lease) before its clean folder goes, even with its
|
|
25
|
+
* result waiting for review or the task unfinished (checkout-cleanup.ts). Saved rows read NULL: the default.
|
|
26
|
+
*/
|
|
27
|
+
export declare const V151_ADDED_COLUMNS: Readonly<Record<string, Readonly<Record<string, {
|
|
28
|
+
definition: string;
|
|
29
|
+
saved: string;
|
|
30
|
+
}>>>>;
|
|
31
|
+
export declare const DEFAULT_IDLE: CheckoutIdle;
|
|
32
|
+
export declare const IDLE_CHOICES: readonly {
|
|
33
|
+
value: CheckoutIdle;
|
|
34
|
+
label: string;
|
|
35
|
+
days: number | null;
|
|
36
|
+
}[];
|
|
37
|
+
/** `7`, `14d`, `30 days`, `never` (or off); undefined when it's none of those. */
|
|
38
|
+
export declare function parseIdle(text: string): CheckoutIdle | undefined;
|
|
39
|
+
/** After "A task's clean folder is removed ". */
|
|
40
|
+
export declare function idleWords(idle: CheckoutIdle): string;
|
|
41
|
+
/** What the next sweep's idle cleanup takes, for `toolroll storage` and Settings → Storage. The sweep's own line says when. */
|
|
42
|
+
export declare function idleCleanupWords(plan: {
|
|
43
|
+
cleanup: CheckoutCleanup;
|
|
44
|
+
idle: CheckoutIdle;
|
|
45
|
+
idleCount: number;
|
|
46
|
+
idleBytes: number;
|
|
47
|
+
}): string;
|
|
23
48
|
/** Bytes each path holds on disk: one `du` for them all (fast on a 300 MB checkout), a walk where it can't answer. */
|
|
24
49
|
export declare function diskBytes(paths: readonly string[]): Map<string, number>;
|
|
25
50
|
export type StorageLine = {
|
package/dist/storage.js
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Build checkouts and staged releases are the big ones; the worker removes a
|
|
5
5
|
* finished task's clean checkout as the checkout cleanup setting says
|
|
6
6
|
* (checkout-cleanup.ts), and the daily storage sweep (storage-sweep.ts) takes
|
|
7
|
-
* what slips through: stale test temp folders, leftover processes, extra
|
|
7
|
+
* idle tasks' clean checkouts and what slips through: stale test temp folders, leftover processes, extra
|
|
8
8
|
* staged runtimes and dependency installs unused for a week.
|
|
9
9
|
*/
|
|
10
10
|
import { execFile, spawnSync } from "node:child_process";
|
|
11
11
|
import { lstatSync, readdirSync } from "node:fs";
|
|
12
12
|
import { basename, dirname, join } from "node:path";
|
|
13
13
|
import { DEPS_FOLDER, sharedCopies } from "./shared-deps.js";
|
|
14
|
-
import { checkoutCleanupSchema } from "./contracts/storage.js";
|
|
14
|
+
import { checkoutCleanupSchema, checkoutIdleSchema } from "./contracts/storage.js";
|
|
15
15
|
/** Settings → Storage: when a finished task's clean checkout is removed. One row, or none (the default). */
|
|
16
16
|
export const CHECKOUT_CLEANUP_SCHEMA = `
|
|
17
17
|
CREATE TABLE IF NOT EXISTS checkout_cleanup_setting (
|
|
@@ -93,6 +93,43 @@ export function cleanupWords(cleanup) {
|
|
|
93
93
|
: cleanup === "never" ? "never (only when you clean up)"
|
|
94
94
|
: `${cleanup === "2d" ? "2 days" : "a week"} after its task is complete or cancelled`;
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* v151: how long a task stays idle (no run, no person's act, no open lease) before its clean folder goes, even with its
|
|
98
|
+
* result waiting for review or the task unfinished (checkout-cleanup.ts). Saved rows read NULL: the default.
|
|
99
|
+
*/
|
|
100
|
+
export const V151_ADDED_COLUMNS = Object.freeze({
|
|
101
|
+
checkout_cleanup_setting: { idle: { definition: "TEXT CHECK (idle IN ('7d', '14d', '30d', 'never'))", saved: "NULL" } },
|
|
102
|
+
});
|
|
103
|
+
export const DEFAULT_IDLE = "14d";
|
|
104
|
+
export const IDLE_CHOICES = [
|
|
105
|
+
{ value: "7d", label: "After 7 days idle", days: 7 },
|
|
106
|
+
{ value: "14d", label: "After 14 days idle", days: 14 },
|
|
107
|
+
{ value: "30d", label: "After 30 days idle", days: 30 },
|
|
108
|
+
{ value: "never", label: "Never", days: null },
|
|
109
|
+
];
|
|
110
|
+
/** `7`, `14d`, `30 days`, `never` (or off); undefined when it's none of those. */
|
|
111
|
+
export function parseIdle(text) {
|
|
112
|
+
const value = text.trim().toLowerCase().replace(/\s+/g, " ");
|
|
113
|
+
if (value === "off")
|
|
114
|
+
return "never";
|
|
115
|
+
const days = /^(\d+)( ?d| days?)?$/.exec(value)?.[1];
|
|
116
|
+
const parsed = checkoutIdleSchema.safeParse(days === undefined ? value : `${days}d`);
|
|
117
|
+
return parsed.success ? parsed.data : undefined;
|
|
118
|
+
}
|
|
119
|
+
/** After "A task's clean folder is removed ". */
|
|
120
|
+
export function idleWords(idle) {
|
|
121
|
+
const days = IDLE_CHOICES.find(one => one.value === idle).days;
|
|
122
|
+
return days === null ? "never for being idle" : `after ${days} days idle`;
|
|
123
|
+
}
|
|
124
|
+
/** What the next sweep's idle cleanup takes, for `toolroll storage` and Settings → Storage. The sweep's own line says when. */
|
|
125
|
+
export function idleCleanupWords(plan) {
|
|
126
|
+
if (plan.cleanup === "never" || plan.idle === "never")
|
|
127
|
+
return "Idle cleanup is off.";
|
|
128
|
+
const limit = `${idleWords(plan.idle)[0].toUpperCase()}${idleWords(plan.idle).slice(1)}`;
|
|
129
|
+
if (plan.idleCount === 0)
|
|
130
|
+
return `${limit}, a task's clean folder goes. None are due.`;
|
|
131
|
+
return `${limit}, a task's clean folder goes: the next sweep frees about ${bytesWords(plan.idleBytes)} (${plan.idleCount} folder${plan.idleCount === 1 ? "" : "s"}).`;
|
|
132
|
+
}
|
|
96
133
|
/** Bytes each path holds on disk: one `du` for them all (fast on a 300 MB checkout), a walk where it can't answer. */
|
|
97
134
|
export function diskBytes(paths) {
|
|
98
135
|
const sizes = new Map();
|
package/dist/store.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { type ProjectSandbox } from "./project-sandbox.js";
|
|
|
5
5
|
import type { FencePolicy } from "./agent-fence.js";
|
|
6
6
|
import { type NetworkProfile, type ProjectNetwork, type RunNetworkRecord } from "./egress.js";
|
|
7
7
|
import { type AcpLaunch } from "./acp-attest.js";
|
|
8
|
+
import { type CheckStamp, type StampReading } from "./check-stamp.js";
|
|
8
9
|
export { refArchived, taskArchived } from "./task-archive.js";
|
|
9
10
|
import { type ChatBinding } from "./chat-core.js";
|
|
10
11
|
import { ChatMessages, TELEGRAM_HOLD_REASONS, TELEGRAM_SKIPPED_ELSEWHERE, TELEGRAM_SKIPPED_OTHER_CHAT, TELEGRAM_SKIPPED_QUIET } from "./chat-messages.js";
|
|
@@ -16,6 +17,7 @@ import type { FlowCardChange, FlowCardFields } from "./contracts/flow-card.js";
|
|
|
16
17
|
import { type Actor } from "./actor.js";
|
|
17
18
|
import { type LiveActivityKind } from "./live.js";
|
|
18
19
|
import { type CredentialKind, type TokenPurpose } from "./api-tokens.js";
|
|
20
|
+
import { type ThisMachine } from "./machine-identity.js";
|
|
19
21
|
import { type CriterionMatrixRow, type CriterionJudgementWord } from "./proof.js";
|
|
20
22
|
import { type Authority, type LocalMode } from "./local-owner.js";
|
|
21
23
|
import { type ScopeAuthor, type ExecutionProfile, type UnattendedPermissionMode, type AcceptanceCriterion } from "./scope.js";
|
|
@@ -29,6 +31,7 @@ import type { Scope } from "./scope.js";
|
|
|
29
31
|
import type { QualityMode } from "./quality.js";
|
|
30
32
|
import type { ProgressSnapshot } from "./plan.js";
|
|
31
33
|
import { type CheckProgressSnapshot } from "./check-progress.js";
|
|
34
|
+
export { V153_ADDED_COLUMNS } from "./plain-schema.js";
|
|
32
35
|
import { type ReleaseCheckPurpose, type ReleaseTerms } from "./contracts/release-terms.js";
|
|
33
36
|
import { type ProjectAccess } from "./project-access.js";
|
|
34
37
|
import { type LedgerEntry } from "./action-ledger.js";
|
|
@@ -37,7 +40,7 @@ import { underCeiling, type OrgPolicy, type SavedPolicy } from "./policy.js";
|
|
|
37
40
|
import { type ReviewSwitch } from "./review-switch.js";
|
|
38
41
|
import { type Billing, type Budget, type BudgetAgent, type BudgetHold, type BudgetScope, type BudgetState, type SpendItem } from "./spend.js";
|
|
39
42
|
import { type RetentionKind, type RetentionPeriods } from "./retention.js";
|
|
40
|
-
import { type CheckoutCleanup } from "./storage.js";
|
|
43
|
+
import { type CheckoutCleanup, type CheckoutIdle } from "./storage.js";
|
|
41
44
|
import { type LedgerChainReport } from "./ledger-chain.js";
|
|
42
45
|
import { type ApprovalGate, type ApprovalRules, type ApproverKind, type Filer } from "./approval-policy.js";
|
|
43
46
|
import { type ReportedAmount } from "./reported-usage.js";
|
|
@@ -59,6 +62,15 @@ export declare const LEAD_SWEEP_SCHEMA = "\nCREATE TABLE IF NOT EXISTS lead_swee
|
|
|
59
62
|
export declare const LEAD_COMMITMENT_SCHEMA = "\nCREATE TABLE IF NOT EXISTS lead_commitment (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n owner TEXT NOT NULL,\n repo TEXT,\n thread INTEGER NOT NULL,\n turn INTEGER,\n channel TEXT NOT NULL DEFAULT 'chat',\n what TEXT NOT NULL,\n condition_json TEXT NOT NULL,\n check_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n state TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'done', 'cancelled', 'expired')),\n created_at TEXT NOT NULL,\n checked_at TEXT,\n closed_at TEXT,\n closed_by TEXT,\n outcome TEXT\n);\nCREATE INDEX IF NOT EXISTS lead_commitment_due ON lead_commitment (state, check_at);\nCREATE INDEX IF NOT EXISTS lead_commitment_owner ON lead_commitment (owner, state, id);\n";
|
|
60
63
|
/** What stops a finished run reading stopped (Store.stopQuiescenceFact). */
|
|
61
64
|
export type StopFactKind = "open" | "alive" | "elsewhere" | "unprovable" | "unknown" | "settling";
|
|
65
|
+
/** Why a finished run's stop is unproven where Toolroll's own process check (stop-proof.ts) can prove it: a run that
|
|
66
|
+
* started its agent with no process witness, a spawn witness with no pid, or a workspace note that can't be read. */
|
|
67
|
+
export type StopProofCause = "no-witness" | "incomplete-spawn" | "workspace-unreadable";
|
|
68
|
+
export type StopFact = {
|
|
69
|
+
run: number;
|
|
70
|
+
kind: StopFactKind;
|
|
71
|
+
problem: string;
|
|
72
|
+
cause?: StopProofCause;
|
|
73
|
+
};
|
|
62
74
|
export type TaskAct = "filed" | "approved" | "cancelled" | "completed" | "asked";
|
|
63
75
|
/** Store.stopQuiescenceFact, read safely: a deploy proves completion with this code over the INSTALLED runtime's store,
|
|
64
76
|
* which may predate the method. There the older stopQuiescenceProblem decides, and its words give the kind. */
|
|
@@ -234,7 +246,7 @@ export type SealedLedgerEntry = LedgerEntry & {
|
|
|
234
246
|
hash: string;
|
|
235
247
|
} | null;
|
|
236
248
|
};
|
|
237
|
-
export declare const SCHEMA_VERSION =
|
|
249
|
+
export declare const SCHEMA_VERSION = 154;
|
|
238
250
|
/** v118: the tables merged into `credential`, in the order they move (a person's API tokens keep their ids first). */
|
|
239
251
|
export declare const V118_MERGED_TABLES: Readonly<Record<string, CredentialKind>>;
|
|
240
252
|
/**
|
|
@@ -426,7 +438,7 @@ export declare const V147_ADDED_COLUMNS: Readonly<Record<string, Readonly<Record
|
|
|
426
438
|
}>>>>;
|
|
427
439
|
/** The v147 migration's steps after the epoch, in order: a test seam (OpenOptions.migrationStep) may stop after each. */
|
|
428
440
|
export declare const V147_STEPS: readonly ["epoch", "local-mode", "password-set", "web-session", "console-instance"];
|
|
429
|
-
export type MigrationStep = (typeof V147_STEPS)[number] | (typeof V148_STEPS)[number];
|
|
441
|
+
export type MigrationStep = (typeof V147_STEPS)[number] | (typeof V148_STEPS)[number] | (typeof V149_STEPS)[number] | (typeof V150_STEPS)[number] | (typeof V151_STEPS)[number] | (typeof V152_STEPS)[number] | (typeof V153_STEPS)[number] | (typeof V154_STEPS)[number];
|
|
430
442
|
/**
|
|
431
443
|
* v148 (docs/plans/results-routing.md): every table the results-routing arc uses, landed at once because a current
|
|
432
444
|
* store runs no DDL. Slice 1 writes run_cohort, route_record and models_generation; route_rule, route_exposure* and
|
|
@@ -458,6 +470,60 @@ export declare const V148_ADDED_COLUMNS: Readonly<Record<string, Readonly<Record
|
|
|
458
470
|
}>>>>;
|
|
459
471
|
/** The v148 migration's steps after v147's, in order (OpenOptions.migrationStep may stop after each). */
|
|
460
472
|
export declare const V148_STEPS: readonly ["results-tables", "exec-class", "revision-origin", "suggest-models"];
|
|
473
|
+
/**
|
|
474
|
+
* v149 (docs/plans/learning-loops.md): every table the learning-loops arc uses, landed at once because a current store
|
|
475
|
+
* runs no DDL. Slice 1 writes check_fact, check_result and learning_watch; the rest are written from later slices.
|
|
476
|
+
* Each table has one writer module (the migration aside), which release-auto's learning scan (eval-hooks.ts
|
|
477
|
+
* learningWriteProblem) holds a release to: check_fact and check_result → check-facts.ts; local_observation → flaky.ts;
|
|
478
|
+
* ci_flaky_observation and ci_pairing_rejected → flaky-ci.ts; learning_watch → flaky.ts and lesson-notes.ts;
|
|
479
|
+
* lesson_note and lesson_note_tally → lesson-notes.ts; memory_use → memory-use.ts; memory_tidy_proposal and
|
|
480
|
+
* decision_merge → memory-tidy.ts.
|
|
481
|
+
*
|
|
482
|
+
* Nothing here is ever read for authority: a check's outcome, a verdict and an approval never change because of it.
|
|
483
|
+
*
|
|
484
|
+
* Deletion follows today's semantics (runs are never deleted by ordinary work; removing a project keeps its results).
|
|
485
|
+
* The tables are keyed by repo path with no foreign key to `project`; their run keys are plain REFERENCES with no ON
|
|
486
|
+
* DELETE action. check_fact, learning_watch, lesson_note, lesson_note_tally, memory_use, memory_tidy_proposal and
|
|
487
|
+
* decision_merge are kept and never deleted (their triggers allow only the columns their one writer sets: a watch's
|
|
488
|
+
* `until`, a tally's counters, a proposal's decision, a merge's undo). check_result, local_observation,
|
|
489
|
+
* ci_flaky_observation and ci_pairing_rejected are pruned after 180 days by the storage sweep's own step (a later
|
|
490
|
+
* slice), the only DELETE on them; their rows never change. The whole-project deletion (project-delete.ts), which
|
|
491
|
+
* lifts every guard for its one transaction, takes them with the project as it takes everything else.
|
|
492
|
+
*/
|
|
493
|
+
export declare const V149_SCHEMA = "\nCREATE TABLE IF NOT EXISTS check_fact (\n run INTEGER PRIMARY KEY REFERENCES run(id),\n repo TEXT,\n task_ref INTEGER NOT NULL,\n head TEXT,\n tree TEXT,\n command_digest TEXT,\n access TEXT,\n harness_digest TEXT,\n lockfile TEXT,\n conditions_digest TEXT,\n conditions_class TEXT,\n purpose TEXT NOT NULL CHECK (purpose IN ('ordinary','release','nightly')),\n learn_state TEXT NOT NULL CHECK (learn_state IN ('recorded','not-recorded','not-asked')),\n learn_why TEXT,\n recorded_at TEXT NOT NULL,\n CHECK ((learn_state = 'not-recorded') = (learn_why IS NOT NULL)),\n CHECK ((conditions_digest IS NULL) = (conditions_class IS NULL)),\n CHECK (conditions_digest IS NULL OR tree IS NOT NULL)\n);\nCREATE INDEX IF NOT EXISTS check_fact_by_repo ON check_fact (repo, recorded_at);\nCREATE INDEX IF NOT EXISTS check_fact_by_tree ON check_fact (tree, conditions_digest);\nCREATE TABLE IF NOT EXISTS check_result (\n run INTEGER NOT NULL REFERENCES check_fact(run),\n identity TEXT NOT NULL CHECK (length(identity) BETWEEN 1 AND 2600),\n state TEXT NOT NULL CHECK (state IN ('failed','passed','skipped','passed-on-retry')),\n source TEXT NOT NULL CHECK (source IN ('receipt','report','log','learn')),\n recorded_at TEXT NOT NULL,\n PRIMARY KEY (run, identity, source)\n);\nCREATE INDEX IF NOT EXISTS check_result_by_identity ON check_result (identity, run);\nCREATE TABLE IF NOT EXISTS local_observation (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n repo TEXT NOT NULL,\n identity TEXT NOT NULL,\n failed_run INTEGER NOT NULL REFERENCES run(id),\n passed_run INTEGER NOT NULL REFERENCES run(id),\n tree TEXT NOT NULL,\n conditions_digest TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('regate','same-tree','in-check-retry')),\n observed_at TEXT NOT NULL,\n UNIQUE (identity, failed_run, passed_run),\n CHECK ((kind = 'in-check-retry') = (failed_run = passed_run))\n);\nCREATE INDEX IF NOT EXISTS local_observation_by_repo ON local_observation (repo, identity, observed_at);\nCREATE TABLE IF NOT EXISTS ci_flaky_observation (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n repo TEXT NOT NULL,\n provider TEXT NOT NULL CHECK (provider = 'github'),\n repository TEXT NOT NULL,\n workflow TEXT NOT NULL,\n lane_id TEXT NOT NULL,\n lane_name TEXT NOT NULL,\n workflow_run_id INTEGER NOT NULL CHECK (workflow_run_id >= 1),\n head_sha TEXT NOT NULL,\n failed_attempt INTEGER NOT NULL CHECK (failed_attempt >= 1),\n failed_job_id INTEGER NOT NULL,\n failed_conclusion TEXT NOT NULL,\n passed_attempt INTEGER NOT NULL,\n passed_job_id INTEGER NOT NULL,\n passed_conclusion TEXT NOT NULL,\n observed_at TEXT NOT NULL,\n UNIQUE (provider, repository, workflow_run_id, lane_id, failed_attempt, passed_attempt),\n CHECK (passed_attempt > failed_attempt)\n);\nCREATE INDEX IF NOT EXISTS ci_flaky_observation_by_repo ON ci_flaky_observation (repo, lane_id, observed_at);\nCREATE TABLE IF NOT EXISTS ci_pairing_rejected (\n provider TEXT NOT NULL CHECK (provider = 'github'),\n repository TEXT NOT NULL,\n workflow_run_id INTEGER NOT NULL CHECK (workflow_run_id >= 1),\n attempt INTEGER NOT NULL CHECK (attempt >= 1),\n lane_id TEXT,\n why TEXT NOT NULL,\n at TEXT NOT NULL,\n PRIMARY KEY (provider, repository, workflow_run_id, attempt, why)\n);\nCREATE TABLE IF NOT EXISTS learning_watch (\n repo TEXT NOT NULL,\n identity TEXT NOT NULL CHECK (length(identity) BETWEEN 1 AND 2600),\n reason TEXT NOT NULL CHECK (reason IN ('note','observation')),\n source_ref TEXT NOT NULL,\n since TEXT NOT NULL,\n until TEXT,\n PRIMARY KEY (repo, identity, reason, source_ref),\n CHECK (until IS NULL OR until >= since)\n);\nCREATE INDEX IF NOT EXISTS learning_watch_open ON learning_watch (repo, since) WHERE until IS NULL;\nCREATE TABLE IF NOT EXISTS lesson_note (\n proposal INTEGER PRIMARY KEY REFERENCES memory_proposal(id),\n repo TEXT NOT NULL,\n failed_run INTEGER NOT NULL REFERENCES run(id),\n passing_run INTEGER NOT NULL REFERENCES run(id),\n repair_chain INTEGER REFERENCES repair_chain(id),\n revision_origin TEXT CHECK (revision_origin IS NULL OR revision_origin IN ('person','automatic-review','flow','lead','machine')),\n identities_json TEXT NOT NULL,\n changed_paths_json TEXT NOT NULL,\n test_files_changed_json TEXT NOT NULL,\n facts_digest TEXT NOT NULL,\n created_at TEXT NOT NULL,\n CHECK (failed_run <> passing_run)\n);\nCREATE INDEX IF NOT EXISTS lesson_note_by_repo ON lesson_note (repo, created_at);\nCREATE TABLE IF NOT EXISTS lesson_note_tally (\n note INTEGER NOT NULL REFERENCES lesson_note(proposal),\n month TEXT NOT NULL CHECK (month GLOB '[0-9][0-9][0-9][0-9]-[0-1][0-9]'),\n executions INTEGER NOT NULL DEFAULT 0 CHECK (executions >= 0),\n failures INTEGER NOT NULL DEFAULT 0 CHECK (failures >= 0 AND failures <= executions),\n mixed_failures INTEGER NOT NULL DEFAULT 0 CHECK (mixed_failures >= 0),\n received_executions INTEGER NOT NULL DEFAULT 0 CHECK (received_executions >= 0 AND received_executions <= executions),\n received_failures INTEGER NOT NULL DEFAULT 0 CHECK (received_failures >= 0 AND received_failures <= received_executions AND received_failures <= failures),\n unreported_checks INTEGER NOT NULL DEFAULT 0 CHECK (unreported_checks >= 0),\n sources_json TEXT NOT NULL DEFAULT '[]',\n partial INTEGER NOT NULL DEFAULT 0 CHECK (partial IN (0,1)),\n PRIMARY KEY (note, month)\n);\nCREATE TABLE IF NOT EXISTS memory_use (\n run INTEGER NOT NULL REFERENCES run(id),\n repo TEXT,\n kind TEXT NOT NULL CHECK (kind IN ('lesson','reference','decision')),\n item TEXT NOT NULL,\n version INTEGER,\n phase TEXT NOT NULL,\n included_at TEXT,\n PRIMARY KEY (run, kind, item)\n);\nCREATE INDEX IF NOT EXISTS memory_use_by_item ON memory_use (repo, kind, item, run);\nCREATE TABLE IF NOT EXISTS memory_tidy_proposal (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n repo TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('retire','merge','contradiction','note-failing','restore','unmerge')),\n items_json TEXT NOT NULL,\n after_text TEXT,\n rationale TEXT NOT NULL,\n evidence_json TEXT NOT NULL,\n source TEXT NOT NULL CHECK (source IN ('usage','duplicate','model','note','person')),\n status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','accepted','rejected','stale')),\n created_at TEXT NOT NULL,\n decided_by TEXT,\n decided_proof TEXT,\n decided_at TEXT,\n CHECK ((status = 'pending') = (decided_at IS NULL)),\n CHECK (status IN ('accepted','rejected') OR (decided_by IS NULL AND decided_proof IS NULL)),\n CHECK (status NOT IN ('accepted','rejected') OR decided_by IS NOT NULL)\n);\nCREATE INDEX IF NOT EXISTS memory_tidy_proposal_pending ON memory_tidy_proposal (repo, status, kind);\nCREATE TABLE IF NOT EXISTS decision_merge (\n merge INTEGER NOT NULL,\n successor INTEGER NOT NULL REFERENCES project_decision(id),\n successor_revision INTEGER NOT NULL CHECK (successor_revision >= 1),\n predecessor INTEGER NOT NULL REFERENCES project_decision(id),\n predecessor_revision INTEGER NOT NULL CHECK (predecessor_revision >= 1),\n at TEXT NOT NULL,\n by TEXT NOT NULL,\n undone_at TEXT,\n undone_by TEXT,\n PRIMARY KEY (merge, predecessor),\n CHECK (successor <> predecessor),\n CHECK ((undone_at IS NULL) = (undone_by IS NULL))\n);\nCREATE INDEX IF NOT EXISTS decision_merge_by_successor ON decision_merge (successor);\nCREATE INDEX IF NOT EXISTS decision_merge_by_predecessor ON decision_merge (predecessor);\nCREATE TRIGGER IF NOT EXISTS check_fact_no_update BEFORE UPDATE ON check_fact BEGIN SELECT RAISE(ABORT,'check facts are recorded once'); END;\nCREATE TRIGGER IF NOT EXISTS check_fact_no_delete BEFORE DELETE ON check_fact BEGIN SELECT RAISE(ABORT,'check facts are kept'); END;\nCREATE TRIGGER IF NOT EXISTS check_result_no_update BEFORE UPDATE ON check_result BEGIN SELECT RAISE(ABORT,'check results are recorded once'); END;\nCREATE TRIGGER IF NOT EXISTS local_observation_no_update BEFORE UPDATE ON local_observation BEGIN SELECT RAISE(ABORT,'observations are recorded once'); END;\nCREATE TRIGGER IF NOT EXISTS ci_flaky_observation_no_update BEFORE UPDATE ON ci_flaky_observation BEGIN SELECT RAISE(ABORT,'observations are recorded once'); END;\nCREATE TRIGGER IF NOT EXISTS ci_pairing_rejected_no_update BEFORE UPDATE ON ci_pairing_rejected BEGIN SELECT RAISE(ABORT,'rejected pairings are recorded once'); END;\nCREATE TRIGGER IF NOT EXISTS learning_watch_only_ends BEFORE UPDATE ON learning_watch\n WHEN NEW.repo IS NOT OLD.repo OR NEW.identity IS NOT OLD.identity OR NEW.reason IS NOT OLD.reason OR NEW.source_ref IS NOT OLD.source_ref\n OR NEW.since IS NOT OLD.since OR OLD.until IS NOT NULL OR NEW.until IS NULL\n BEGIN SELECT RAISE(ABORT,'a tracked identity only ends, once'); END;\nCREATE TRIGGER IF NOT EXISTS learning_watch_no_delete BEFORE DELETE ON learning_watch BEGIN SELECT RAISE(ABORT,'tracked identities are kept'); END;\nCREATE TRIGGER IF NOT EXISTS lesson_note_no_update BEFORE UPDATE ON lesson_note BEGIN SELECT RAISE(ABORT,'lesson note facts are recorded once'); END;\nCREATE TRIGGER IF NOT EXISTS lesson_note_no_delete BEFORE DELETE ON lesson_note BEGIN SELECT RAISE(ABORT,'lesson notes are kept'); END;\nCREATE TRIGGER IF NOT EXISTS lesson_note_tally_only_counts BEFORE UPDATE ON lesson_note_tally\n WHEN NEW.note IS NOT OLD.note OR NEW.month IS NOT OLD.month OR NEW.executions < OLD.executions OR NEW.failures < OLD.failures\n OR NEW.mixed_failures < OLD.mixed_failures OR NEW.received_executions < OLD.received_executions OR NEW.received_failures < OLD.received_failures\n OR NEW.unreported_checks < OLD.unreported_checks OR NEW.partial < OLD.partial\n BEGIN SELECT RAISE(ABORT,'a tally only counts up'); END;\nCREATE TRIGGER IF NOT EXISTS lesson_note_tally_no_delete BEFORE DELETE ON lesson_note_tally BEGIN SELECT RAISE(ABORT,'tallies are never pruned'); END;\nCREATE TRIGGER IF NOT EXISTS memory_use_no_update BEFORE UPDATE ON memory_use BEGIN SELECT RAISE(ABORT,'memory use is recorded once'); END;\nCREATE TRIGGER IF NOT EXISTS memory_use_no_delete BEFORE DELETE ON memory_use BEGIN SELECT RAISE(ABORT,'memory use is kept'); END;\nCREATE TRIGGER IF NOT EXISTS memory_tidy_proposal_only_decides BEFORE UPDATE ON memory_tidy_proposal\n WHEN NEW.id IS NOT OLD.id OR NEW.repo IS NOT OLD.repo OR NEW.kind IS NOT OLD.kind OR NEW.items_json IS NOT OLD.items_json\n OR NEW.after_text IS NOT OLD.after_text OR NEW.rationale IS NOT OLD.rationale OR NEW.evidence_json IS NOT OLD.evidence_json\n OR NEW.source IS NOT OLD.source OR NEW.created_at IS NOT OLD.created_at OR OLD.status <> 'pending'\n BEGIN SELECT RAISE(ABORT,'a tidy-up proposal is decided once'); END;\nCREATE TRIGGER IF NOT EXISTS memory_tidy_proposal_no_delete BEFORE DELETE ON memory_tidy_proposal BEGIN SELECT RAISE(ABORT,'tidy-up proposals are kept'); END;\nCREATE TRIGGER IF NOT EXISTS decision_merge_only_undone BEFORE UPDATE ON decision_merge\n WHEN NEW.merge IS NOT OLD.merge OR NEW.successor IS NOT OLD.successor OR NEW.successor_revision IS NOT OLD.successor_revision\n OR NEW.predecessor IS NOT OLD.predecessor OR NEW.predecessor_revision IS NOT OLD.predecessor_revision OR NEW.at IS NOT OLD.at\n OR NEW.by IS NOT OLD.by OR OLD.undone_at IS NOT NULL\n BEGIN SELECT RAISE(ABORT,'a merge is undone once, never rewritten'); END;\nCREATE TRIGGER IF NOT EXISTS decision_merge_no_delete BEFORE DELETE ON decision_merge BEGIN SELECT RAISE(ABORT,'merges are kept'); END;\n";
|
|
494
|
+
/** The tables V149_SCHEMA adds, in the order a test drops them to make the v148 shape (dependents first). */
|
|
495
|
+
export declare const V149_TABLES: readonly ["check_result", "check_fact", "local_observation", "ci_flaky_observation", "ci_pairing_rejected", "learning_watch", "lesson_note_tally", "lesson_note", "memory_use", "memory_tidy_proposal", "decision_merge"];
|
|
496
|
+
/** The v149 tables a whole-project deletion clears by repo (the rest hang off these or a deleted run or decision). */
|
|
497
|
+
export declare const V149_REPO_TABLES: readonly ["check_fact", "local_observation", "ci_flaky_observation", "learning_watch", "lesson_note", "memory_use", "memory_tidy_proposal"];
|
|
498
|
+
/** The v149 migration's steps after v148's, in order (OpenOptions.migrationStep may stop after each). */
|
|
499
|
+
export declare const V149_STEPS: readonly ["learning-tables"];
|
|
500
|
+
/**
|
|
501
|
+
* v150 (machine-identity.ts): which computer a process witness belongs to, by the machine's stable id rather than its
|
|
502
|
+
* network hostname (which follows the network on a Mac with no HostName set). machine_host_alias records each
|
|
503
|
+
* hostname this machine read while it knew its own id, written only by a process on that machine, beside the id it
|
|
504
|
+
* read; a witness with no id (every saved one) is this machine's when its host is one of them. Never read for any
|
|
505
|
+
* other machine's id.
|
|
506
|
+
*/
|
|
507
|
+
export declare const V150_SCHEMA = "\nCREATE TABLE IF NOT EXISTS machine_host_alias (\n machine_id TEXT NOT NULL CHECK (length(machine_id) = 32),\n host TEXT NOT NULL CHECK (host <> ''),\n first_seen_at TEXT NOT NULL,\n PRIMARY KEY (machine_id, host)\n);\n";
|
|
508
|
+
/** The tables V150_SCHEMA adds. */
|
|
509
|
+
export declare const V150_TABLES: readonly ["machine_host_alias"];
|
|
510
|
+
/** v150: a process witness's machine id (saved witnesses read NULL: matched by host name, as before). */
|
|
511
|
+
export declare const V150_ADDED_COLUMNS: Readonly<Record<string, Readonly<Record<string, {
|
|
512
|
+
definition: string;
|
|
513
|
+
saved: string;
|
|
514
|
+
}>>>>;
|
|
515
|
+
/** The v150 migration's steps after v149's, in order (OpenOptions.migrationStep may stop after each). */
|
|
516
|
+
export declare const V150_STEPS: readonly ["machine-aliases", "witness-machine"];
|
|
517
|
+
/** The v151 migration's steps after v150's, in order (OpenOptions.migrationStep may stop after each). */
|
|
518
|
+
export declare const V151_STEPS: readonly ["checkout-idle"];
|
|
519
|
+
/** The v152 migration's steps after v151's, in order (OpenOptions.migrationStep may stop after each). */
|
|
520
|
+
export declare const V152_STEPS: readonly ["code-map-tables", "code-map-switch", "code-map-watermark"];
|
|
521
|
+
/** v153 (plain-toolroll.md Phase 2): the tables each slice owns. */
|
|
522
|
+
export declare const V153_SCHEMA: string;
|
|
523
|
+
/** The v153 migration's steps after v152's, in order (OpenOptions.migrationStep may stop after each). */
|
|
524
|
+
export declare const V153_STEPS: readonly ["plain-tables", "plain-columns"];
|
|
525
|
+
/** The v154 migration's steps after v153's, in order (OpenOptions.migrationStep may stop after each). */
|
|
526
|
+
export declare const V154_STEPS: readonly ["check-stamps"];
|
|
461
527
|
/**
|
|
462
528
|
* v135: one approval per release (docs/plans/release-once.md). `release_authority` is the single source of truth for a
|
|
463
529
|
* release a person approved: one row per generation, changed only by compare-and-swap on `rev`, with a lease whose
|
|
@@ -6873,17 +6939,14 @@ export declare class Store {
|
|
|
6873
6939
|
* what kind of answer it is (needs-you.ts reads it): `alive` while
|
|
6874
6940
|
* something of the run may still be running, `elsewhere` when only
|
|
6875
6941
|
* another computer can tell, `unprovable` when nothing is known to run
|
|
6876
|
-
* but its exit was never recorded
|
|
6877
|
-
*
|
|
6878
|
-
*
|
|
6879
|
-
*
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
} | null;
|
|
6885
|
-
/** `run settle` recorded an approver's word that a run whose workspace
|
|
6886
|
-
* note couldn't be read has stopped. */
|
|
6942
|
+
* but its exit was never recorded (Toolroll's own look, stop-proof.ts,
|
|
6943
|
+
* settles it), `unknown` when this computer can't check, or that look
|
|
6944
|
+
* was blocked. `settling` already meets the automatic reconciliation
|
|
6945
|
+
* proof. Nobody is ever asked to confirm a build stopped. `cause` names
|
|
6946
|
+
* what stop-proof.ts can prove. */
|
|
6947
|
+
stopQuiescenceFact(runId: number): StopFact | null;
|
|
6948
|
+
/** A run whose workspace note couldn't be read was proven free: by Toolroll's own look (stop-proof.ts), or, in
|
|
6949
|
+
* ledgers from before it, by an approver's recorded word (still read, never written now). */
|
|
6887
6950
|
private workspaceConfirmedByApprover;
|
|
6888
6951
|
reserveRunProcess(runId: number, now: Date, group?: boolean): number;
|
|
6889
6952
|
/** The run's process witnesses not yet proved exited — after first saving whatever exit evidence is available. */
|
|
@@ -6915,29 +6978,12 @@ export declare class Store {
|
|
|
6915
6978
|
* here, every other witness of the run has exited and none of the run's
|
|
6916
6979
|
* process groups is alive, it settles as never started, with a ledger
|
|
6917
6980
|
* entry. A sole pid-less witness has no group to prove gone and stays for
|
|
6918
|
-
*
|
|
6981
|
+
* Toolroll's own look (stop-proof.ts). Native witnesses keep their OS-only road. */
|
|
6919
6982
|
settleUnspawnedWitnesses(now: Date, onlyRun?: number): number;
|
|
6920
6983
|
/** The existing automatic settlement proof, shared with its read-only
|
|
6921
6984
|
* status. Unknown-only, foreign, native and still-running custody keep
|
|
6922
6985
|
* their fences; only an observed single-process exit avoids a new probe. */
|
|
6923
6986
|
private settleableUnspawnedWitnesses;
|
|
6924
|
-
/** `run settle` (an approver's last resort): every witness of a finished
|
|
6925
|
-
* run that cannot be proven either way is recorded settled under the
|
|
6926
|
-
* approver's reason, in the ledger. Refuses while anything of the run is
|
|
6927
|
-
* alive or could be checked only from another host. Never signals. */
|
|
6928
|
-
settleRunWitnessesByApprover(args: {
|
|
6929
|
-
runId: number;
|
|
6930
|
-
by: string;
|
|
6931
|
-
why: string;
|
|
6932
|
-
}, now: Date): {
|
|
6933
|
-
ok: true;
|
|
6934
|
-
witnesses: number[];
|
|
6935
|
-
repeated: boolean;
|
|
6936
|
-
} | {
|
|
6937
|
-
ok: false;
|
|
6938
|
-
reason: "unknown-run" | "still-running" | "alive";
|
|
6939
|
-
detail: string;
|
|
6940
|
-
};
|
|
6941
6987
|
recordRunProcess(runId: number, pid: number, now: Date, group?: boolean, witness?: number): void;
|
|
6942
6988
|
/** The native OS object a witnessed spawn ran inside (v53) — recorded
|
|
6943
6989
|
* with the spawn, before the target can execute. */
|
|
@@ -7409,7 +7455,8 @@ export declare class Store {
|
|
|
7409
7455
|
stampRunCheckAccess(runId: number, level: CheckAccess, network?: NetworkProfile | null): void;
|
|
7410
7456
|
/** The network a run's sign-ins checks ran under (null: none sealed; such a run's later checks run sandboxed). */
|
|
7411
7457
|
runCheckNetwork(runId: number): NetworkProfile | null;
|
|
7412
|
-
/** The level a run
|
|
7458
|
+
/** The level a later check of this run may run at, at most: missing or unreadable reads as sandboxed, the narrowest.
|
|
7459
|
+
* Never an account of how its checks DID run: that is runCheckStamp (check-stamp.ts). */
|
|
7413
7460
|
runCheckAccess(runId: number): CheckAccess;
|
|
7414
7461
|
/** A project's check access changed: saved, and in the ledger as before → after. `may` is what the caller proved:
|
|
7415
7462
|
* "widen" only after an instance operator's password typed now; anything else may only narrow. The level is read again
|
|
@@ -8275,6 +8322,12 @@ export type ReleaseProgress = {
|
|
|
8275
8322
|
message: string;
|
|
8276
8323
|
at: string;
|
|
8277
8324
|
} | null;
|
|
8325
|
+
/** The release's task moved on since its last recorded failure: this build started after it and is running now, so
|
|
8326
|
+
* the release isn't stopped there, even though `toolroll release` hasn't recorded a step since. */
|
|
8327
|
+
building: {
|
|
8328
|
+
run: number;
|
|
8329
|
+
startedAt: string;
|
|
8330
|
+
} | null;
|
|
8278
8331
|
};
|
|
8279
8332
|
/** What a release coordinator says about one step. */
|
|
8280
8333
|
export type ReleaseStepEntry = {
|
|
@@ -8294,7 +8347,8 @@ export type ReleaseStepEntry = {
|
|
|
8294
8347
|
*/
|
|
8295
8348
|
export declare function recordReleaseStep(store: Store, entry: ReleaseStepEntry): void;
|
|
8296
8349
|
/** A release's steps, for the release task: the newest tag recorded for it, its steps in the order they ran, and the
|
|
8297
|
-
* step it stopped at when the last thing recorded was a failure
|
|
8350
|
+
* step it stopped at when the last thing recorded was a failure and no build of the task has started since. Null: no
|
|
8351
|
+
* step recorded. */
|
|
8298
8352
|
export declare function releaseProgressFor(store: Store, taskId: string): ReleaseProgress | null;
|
|
8299
8353
|
/** The release task whose steps were recorded most recently (v146), or null when none was. */
|
|
8300
8354
|
export declare function latestReleaseStepTask(store: Store): string | null;
|
|
@@ -8400,3 +8454,63 @@ export declare function recordLaptopPort(store: Store, port: number, now: Date):
|
|
|
8400
8454
|
* results-routing rows go (route-store.ts forgetProjectRoutes). One of the routing scan's named phase_* writers
|
|
8401
8455
|
* (route-hooks.ts). How many rows went. */
|
|
8402
8456
|
export declare function forgetProjectModels(store: Store, repo: string, now: Date): number;
|
|
8457
|
+
/** The ledger words of Toolroll's own stop proof. Nobody is asked to vouch that a build stopped: Toolroll looks at
|
|
8458
|
+
* this computer's processes itself, and a person's older recorded word (`run settle` before this) is still read. */
|
|
8459
|
+
export declare const STOP_PROOF_SETTLED = "run stop proven automatically";
|
|
8460
|
+
export declare const STOP_PROOF_BLOCKED = "automatic stop check blocked";
|
|
8461
|
+
export declare const STOP_PROOF_WORKSPACE_FREE = "workspace proven free automatically";
|
|
8462
|
+
/** Why Toolroll's own stop check is blocked for a run, in words that follow "run #N " (the stop fact's problem), or
|
|
8463
|
+
* null when its newest word is not a block (never checked, or proven since). */
|
|
8464
|
+
export declare function stopProofVerdictOf(store: Store, runId: number): string | null;
|
|
8465
|
+
/** Record that Toolroll's own stop check could not prove a run stopped (`words` follow "run #N "; `detail` is the
|
|
8466
|
+
* evidence). The same block twice in a row is recorded once. True when recorded. */
|
|
8467
|
+
export declare function recordStopProofBlocked(store: Store, runId: number, words: string, detail: string, now: Date): boolean;
|
|
8468
|
+
/**
|
|
8469
|
+
* Settle a finished run's unproven stop on Toolroll's own observation of this computer (stop-proof.ts): the caller
|
|
8470
|
+
* looked at every process here and found none of the run's. Applies only while the run's stop is still unproven for
|
|
8471
|
+
* exactly `cause` (re-read in this transaction): a pid-less spawn witness is recorded ended, a run with no witness gets
|
|
8472
|
+
* one ended witness, an unreadable workspace note is recorded proven free. The evidence goes in the ledger. Never
|
|
8473
|
+
* signals. True when this call settled it.
|
|
8474
|
+
*/
|
|
8475
|
+
export declare function settleRunStopByObservation(store: Store, args: {
|
|
8476
|
+
runId: number;
|
|
8477
|
+
cause: StopProofCause;
|
|
8478
|
+
evidence: string;
|
|
8479
|
+
}, now: Date): boolean;
|
|
8480
|
+
/**
|
|
8481
|
+
* This machine as the store knows it (v150, machine-identity.ts): its stable id and every name it is known by, the
|
|
8482
|
+
* hostnames recorded beside its own id included. Read fresh each time, so a name recorded by another process on this
|
|
8483
|
+
* machine counts at once.
|
|
8484
|
+
*/
|
|
8485
|
+
export declare function storeMachine(db: Database): ThisMachine;
|
|
8486
|
+
/** Load this machine's recorded names for the checks that hold no store; a store that can't read them loads none. */
|
|
8487
|
+
export declare function rememberStoredHostAliases(db: Database): void;
|
|
8488
|
+
/** Record the names this machine is known by right now beside its own id, read here at this moment (never a name a
|
|
8489
|
+
* witness, a note or another computer supplied). Nothing when this machine's id is unknown. */
|
|
8490
|
+
export declare function recordMachineHostAliases(db: Database, now: Date): void;
|
|
8491
|
+
/** Whether a run_process row is this machine's (machine-identity.ts isThisMachine). */
|
|
8492
|
+
export declare function witnessIsLocal(row: Record<string, unknown>, here: ThisMachine): boolean;
|
|
8493
|
+
/** The same rule as witnessIsLocal, as SQL over run_process (optionally aliased): its id is ours, or it has none and
|
|
8494
|
+
* its host is one of our names. With our id unknown, `machine_id = NULL` matches nothing: an id-bearing witness is
|
|
8495
|
+
* never taken for ours. */
|
|
8496
|
+
export declare function localWitnessSql(db: Database, alias?: string): {
|
|
8497
|
+
sql: string;
|
|
8498
|
+
params: (string | null)[];
|
|
8499
|
+
};
|
|
8500
|
+
/** Whether this database has v150's run_process.machine_id. An update settles leftover records on the database it is
|
|
8501
|
+
* about to back up, still at the older schema (toolroll-update.ts drain), so no query it reaches may assume the column:
|
|
8502
|
+
* there every witness has no id, and the host-name rule above is the whole rule. */
|
|
8503
|
+
export declare function witnessesCarryMachine(db: Database): boolean;
|
|
8504
|
+
/** Settings → Storage: how long a task stays idle before its clean folder goes (the default until someone chooses). */
|
|
8505
|
+
export declare function checkoutIdle(store: Store): CheckoutIdle;
|
|
8506
|
+
/** Choose how long a task stays idle before its clean folder goes; the ledger keeps before → after. */
|
|
8507
|
+
export declare function setCheckoutIdle(store: Store, idle: CheckoutIdle, by: string, now: Date): CheckoutIdle;
|
|
8508
|
+
/** A check launch's execution stamp (check-stamp.ts), written by the code that launched it. One row per distinct launch. */
|
|
8509
|
+
export declare function recordCheckStamp(store: Store, runId: number, stamp: CheckStamp, now: Date): void;
|
|
8510
|
+
/** How a run's checks actually ran, by every launch it stamped: `unknown` when none is there or one can't be read. */
|
|
8511
|
+
export declare function runCheckStamp(store: Store, runId: number): StampReading;
|
|
8512
|
+
/** The newest run of a task whose checks ran (it saved a check log), and how they ran; null when none has. */
|
|
8513
|
+
export declare function taskCheckStamp(store: Store, repo: string, taskId: string): {
|
|
8514
|
+
runId: number;
|
|
8515
|
+
reading: StampReading;
|
|
8516
|
+
} | null;
|