harnery 0.36.0 → 0.37.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/commander.js +4 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +87 -46
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +26 -1
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +11 -0
- package/dist/commands/diagnostics.d.ts +4 -0
- package/dist/commands/diagnostics.d.ts.map +1 -0
- package/dist/commands/diagnostics.js +229 -0
- package/dist/commands/files.d.ts +12 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -1
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +4 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +71 -2
- package/dist/commands/qa-run.d.ts +4 -0
- package/dist/commands/qa-run.d.ts.map +1 -0
- package/dist/commands/qa-run.js +141 -0
- package/dist/commands/resources.d.ts +4 -0
- package/dist/commands/resources.d.ts.map +1 -0
- package/dist/commands/resources.js +29 -0
- package/dist/commands/supervisor.d.ts +4 -0
- package/dist/commands/supervisor.d.ts.map +1 -0
- package/dist/commands/supervisor.js +101 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +17 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +4 -0
- package/dist/core/agents/cli.js +7 -3
- package/dist/core/agents/health.d.ts +17 -0
- package/dist/core/agents/health.d.ts.map +1 -0
- package/dist/core/agents/health.js +109 -0
- package/dist/core/agents/mailbox.d.ts +92 -0
- package/dist/core/agents/mailbox.d.ts.map +1 -0
- package/dist/core/agents/mailbox.js +325 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts +44 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts.map +1 -0
- package/dist/core/agents/reconcile-coordination-v3.js +58 -0
- package/dist/core/agents/render/prompt-context.d.ts +5 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +34 -13
- package/dist/core/agents/render/session-context.d.ts +8 -0
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +34 -3
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +50 -1
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +6 -10
- package/dist/core/agents/session-finalizer-v3.js +4 -1
- package/dist/core/artifacts/index.d.ts +26 -1
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +146 -6
- package/dist/core/config.d.ts +12 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +43 -0
- package/dist/core/diagnostics/advice.d.ts +9 -0
- package/dist/core/diagnostics/advice.d.ts.map +1 -0
- package/dist/core/diagnostics/advice.js +112 -0
- package/dist/core/diagnostics/bundle.d.ts +35 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -0
- package/dist/core/diagnostics/bundle.js +874 -0
- package/dist/core/diagnostics/comparison.d.ts +5 -0
- package/dist/core/diagnostics/comparison.d.ts.map +1 -0
- package/dist/core/diagnostics/comparison.js +444 -0
- package/dist/core/diagnostics/contract.d.ts +245 -0
- package/dist/core/diagnostics/contract.d.ts.map +1 -0
- package/dist/core/diagnostics/contract.js +18 -0
- package/dist/core/diagnostics/identity.d.ts +3 -0
- package/dist/core/diagnostics/identity.d.ts.map +1 -0
- package/dist/core/diagnostics/identity.js +10 -0
- package/dist/core/diagnostics/index.d.ts +8 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -0
- package/dist/core/diagnostics/index.js +7 -0
- package/dist/core/diagnostics/replay.d.ts +8 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -0
- package/dist/core/diagnostics/replay.js +213 -0
- package/dist/core/diagnostics/sanitize.d.ts +9 -0
- package/dist/core/diagnostics/sanitize.d.ts.map +1 -0
- package/dist/core/diagnostics/sanitize.js +84 -0
- package/dist/core/events/legacy-storage/compression.d.ts +13 -0
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/compression.js +107 -0
- package/dist/core/events/legacy-storage/index.d.ts +1 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/index.js +1 -0
- package/dist/core/events/v3/archive-retention.d.ts +33 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -0
- package/dist/core/events/v3/archive-retention.js +195 -0
- package/dist/core/events/v3/capabilities.d.ts +1 -1
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +1 -0
- package/dist/core/events/v3/index.d.ts +1 -0
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +1 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +13 -2
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +1 -0
- package/dist/core/events/v3/producers/recorder.d.ts +16 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +88 -1
- package/dist/core/hooks/adapter/output.d.ts +8 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +11 -1
- package/dist/core/hooks/cli.js +183 -192
- package/dist/core/hooks/health.d.ts +59 -0
- package/dist/core/hooks/health.d.ts.map +1 -0
- package/dist/core/hooks/health.js +84 -0
- package/dist/core/resources/contract.d.ts +90 -0
- package/dist/core/resources/contract.d.ts.map +1 -0
- package/dist/core/resources/contract.js +2 -0
- package/dist/core/resources/index.d.ts +6 -0
- package/dist/core/resources/index.d.ts.map +1 -0
- package/dist/core/resources/index.js +5 -0
- package/dist/core/resources/sampler.d.ts +27 -0
- package/dist/core/resources/sampler.d.ts.map +1 -0
- package/dist/core/resources/sampler.js +357 -0
- package/dist/core/resources/service-status.d.ts +3 -0
- package/dist/core/resources/service-status.d.ts.map +1 -0
- package/dist/core/resources/service-status.js +48 -0
- package/dist/core/resources/service.d.ts +26 -0
- package/dist/core/resources/service.d.ts.map +1 -0
- package/dist/core/resources/service.js +292 -0
- package/dist/core/resources/storage.d.ts +13 -0
- package/dist/core/resources/storage.d.ts.map +1 -0
- package/dist/core/resources/storage.js +30 -0
- package/dist/core/storage/atomic-json.d.ts +3 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -0
- package/dist/core/storage/atomic-json.js +15 -0
- package/dist/core/storage/builtins.d.ts.map +1 -1
- package/dist/core/storage/builtins.js +45 -6
- package/dist/core/storage/logger.d.ts +2 -0
- package/dist/core/storage/logger.d.ts.map +1 -1
- package/dist/core/storage/logger.js +2 -0
- package/dist/core/storage/query.d.ts +14 -0
- package/dist/core/storage/query.d.ts.map +1 -1
- package/dist/core/storage/query.js +51 -0
- package/dist/core/supervisor/activity.d.ts +4 -0
- package/dist/core/supervisor/activity.d.ts.map +1 -0
- package/dist/core/supervisor/activity.js +141 -0
- package/dist/core/supervisor/contract.d.ts +268 -0
- package/dist/core/supervisor/contract.d.ts.map +1 -0
- package/dist/core/supervisor/contract.js +35 -0
- package/dist/core/supervisor/explanations.d.ts +4 -0
- package/dist/core/supervisor/explanations.d.ts.map +1 -0
- package/dist/core/supervisor/explanations.js +71 -0
- package/dist/core/supervisor/findings.d.ts +20 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -0
- package/dist/core/supervisor/findings.js +399 -0
- package/dist/core/supervisor/history.d.ts +9 -0
- package/dist/core/supervisor/history.d.ts.map +1 -0
- package/dist/core/supervisor/history.js +46 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts +14 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-alerts.js +70 -0
- package/dist/core/supervisor/hook-health-storage.d.ts +5 -0
- package/dist/core/supervisor/hook-health-storage.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-storage.js +24 -0
- package/dist/core/supervisor/hook-health.d.ts +72 -0
- package/dist/core/supervisor/hook-health.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health.js +203 -0
- package/dist/core/supervisor/hooks.d.ts +10 -0
- package/dist/core/supervisor/hooks.d.ts.map +1 -0
- package/dist/core/supervisor/hooks.js +28 -0
- package/dist/core/supervisor/index.d.ts +15 -0
- package/dist/core/supervisor/index.d.ts.map +1 -0
- package/dist/core/supervisor/index.js +14 -0
- package/dist/core/supervisor/log-feed.d.ts +9 -0
- package/dist/core/supervisor/log-feed.d.ts.map +1 -0
- package/dist/core/supervisor/log-feed.js +103 -0
- package/dist/core/supervisor/service.d.ts +29 -0
- package/dist/core/supervisor/service.d.ts.map +1 -0
- package/dist/core/supervisor/service.js +450 -0
- package/dist/core/supervisor/services.d.ts +11 -0
- package/dist/core/supervisor/services.d.ts.map +1 -0
- package/dist/core/supervisor/services.js +155 -0
- package/dist/core/supervisor/status.d.ts +3 -0
- package/dist/core/supervisor/status.d.ts.map +1 -0
- package/dist/core/supervisor/status.js +48 -0
- package/dist/core/supervisor/storage.d.ts +30 -0
- package/dist/core/supervisor/storage.d.ts.map +1 -0
- package/dist/core/supervisor/storage.js +73 -0
- package/dist/core/supervisor/timeline.d.ts +3 -0
- package/dist/core/supervisor/timeline.d.ts.map +1 -0
- package/dist/core/supervisor/timeline.js +87 -0
- package/dist/core/workflow/admission.d.ts +23 -0
- package/dist/core/workflow/admission.d.ts.map +1 -0
- package/dist/core/workflow/admission.js +136 -0
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +77 -2
- package/dist/core/workflow/index.d.ts +3 -2
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -1
- package/dist/core/workflow/proof.d.ts +2 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +39 -1
- package/dist/core/workflow/run-state.d.ts +3 -2
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +8 -1
- package/dist/core/workflow/types.d.ts +33 -1
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +2 -1
- package/dist/lib/browser/client.d.ts +5 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +1 -0
- package/dist/lib/browser/index.d.ts +2 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +173 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -0
- package/dist/lib/browser/qa-run-contracts.js +226 -0
- package/dist/lib/browser/qa-run.d.ts +51 -0
- package/dist/lib/browser/qa-run.d.ts.map +1 -0
- package/dist/lib/browser/qa-run.js +684 -0
- package/dist/lib/coord-root-id.d.ts +9 -0
- package/dist/lib/coord-root-id.d.ts.map +1 -0
- package/dist/lib/coord-root-id.js +17 -0
- package/dist/lib/instructions/apply.d.ts +3 -1
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +74 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +6 -0
- package/package.json +12 -1
- package/src/commander.ts +26 -0
- package/src/commands/agents.ts +102 -49
- package/src/commands/artifacts.ts +40 -2
- package/src/commands/browse.ts +15 -0
- package/src/commands/diagnostics.ts +271 -0
- package/src/commands/files.ts +102 -2
- package/src/commands/governor.ts +8 -0
- package/src/commands/ledger-v3.ts +82 -0
- package/src/commands/qa-run.ts +184 -0
- package/src/commands/resources.ts +38 -0
- package/src/commands/supervisor.ts +141 -0
- package/src/commands/web.ts +19 -0
- package/src/commands/workflow.ts +8 -0
- package/src/core/agents/cli.ts +7 -3
- package/src/core/agents/health.ts +142 -0
- package/src/core/agents/mailbox.ts +373 -0
- package/src/core/agents/reconcile-coordination-v3.ts +77 -0
- package/src/core/agents/render/prompt-context.ts +42 -12
- package/src/core/agents/render/session-context.ts +37 -3
- package/src/core/agents/rules/commit-conflict.ts +58 -1
- package/src/core/agents/rules/stop-hook.ts +6 -12
- package/src/core/agents/session-finalizer-v3.ts +4 -1
- package/src/core/artifacts/index.ts +196 -10
- package/src/core/config.ts +111 -2
- package/src/core/diagnostics/advice.ts +147 -0
- package/src/core/diagnostics/bundle.ts +1142 -0
- package/src/core/diagnostics/comparison.ts +565 -0
- package/src/core/diagnostics/contract.ts +311 -0
- package/src/core/diagnostics/identity.ts +11 -0
- package/src/core/diagnostics/index.ts +7 -0
- package/src/core/diagnostics/replay.ts +314 -0
- package/src/core/diagnostics/sanitize.ts +97 -0
- package/src/core/events/legacy-storage/compression.ts +130 -0
- package/src/core/events/legacy-storage/index.ts +1 -0
- package/src/core/events/v3/archive-retention.ts +251 -0
- package/src/core/events/v3/capabilities.ts +2 -0
- package/src/core/events/v3/index.ts +9 -0
- package/src/core/events/v3/live-routing.ts +1 -0
- package/src/core/events/v3/producers/hook-base.ts +14 -2
- package/src/core/events/v3/producers/intake.ts +1 -0
- package/src/core/events/v3/producers/recorder.ts +110 -1
- package/src/core/hooks/adapter/output.ts +12 -1
- package/src/core/hooks/cli.ts +192 -215
- package/src/core/hooks/health.ts +146 -0
- package/src/core/resources/contract.ts +98 -0
- package/src/core/resources/index.ts +5 -0
- package/src/core/resources/sampler.ts +458 -0
- package/src/core/resources/service-status.ts +62 -0
- package/src/core/resources/service.ts +337 -0
- package/src/core/resources/storage.ts +44 -0
- package/src/core/storage/atomic-json.ts +15 -0
- package/src/core/storage/builtins.ts +62 -6
- package/src/core/storage/logger.ts +2 -0
- package/src/core/storage/query.ts +58 -0
- package/src/core/supervisor/activity.ts +193 -0
- package/src/core/supervisor/contract.ts +312 -0
- package/src/core/supervisor/explanations.ts +104 -0
- package/src/core/supervisor/findings.ts +788 -0
- package/src/core/supervisor/history.ts +61 -0
- package/src/core/supervisor/hook-health-alerts.ts +108 -0
- package/src/core/supervisor/hook-health-storage.ts +25 -0
- package/src/core/supervisor/hook-health.ts +301 -0
- package/src/core/supervisor/hooks.ts +35 -0
- package/src/core/supervisor/index.ts +14 -0
- package/src/core/supervisor/log-feed.ts +131 -0
- package/src/core/supervisor/service.ts +511 -0
- package/src/core/supervisor/services.ts +203 -0
- package/src/core/supervisor/status.ts +59 -0
- package/src/core/supervisor/storage.ts +126 -0
- package/src/core/supervisor/timeline.ts +133 -0
- package/src/core/workflow/admission.ts +215 -0
- package/src/core/workflow/engine.ts +93 -1
- package/src/core/workflow/index.ts +10 -0
- package/src/core/workflow/proof.ts +54 -1
- package/src/core/workflow/run-state.ts +13 -1
- package/src/core/workflow/types.ts +39 -1
- package/src/lib/browser/client.ts +6 -0
- package/src/lib/browser/index.ts +29 -0
- package/src/lib/browser/qa-run-contracts.ts +380 -0
- package/src/lib/browser/qa-run.ts +784 -0
- package/src/lib/coord-root-id.ts +23 -0
- package/src/lib/instructions/apply.ts +81 -2
- package/src/lib/instructions/templates.ts +6 -0
|
@@ -24,6 +24,7 @@ import { appendFileSync, existsSync } from "node:fs";
|
|
|
24
24
|
import { basename, dirname, join } from "node:path";
|
|
25
25
|
import { coordFreshnessSeconds } from "../../config.js";
|
|
26
26
|
import { resolveOwner } from "../../hooks/resolve/owner.js";
|
|
27
|
+
import { recordLiveClaimChangeV3 } from "../live-authority-v3.js";
|
|
27
28
|
import { readLiveCoordinationRows } from "../state/live-coordination-view.js";
|
|
28
29
|
import { instanceHasLivePid } from "../state/pidmap.js";
|
|
29
30
|
export function evaluateCommit(coordRoot, req) {
|
|
@@ -120,6 +121,14 @@ export function evaluateCommit(coordRoot, req) {
|
|
|
120
121
|
suppressed_self_attribution: true,
|
|
121
122
|
};
|
|
122
123
|
}
|
|
124
|
+
// A blocked commit proves this session has work in every staged path, even
|
|
125
|
+
// when the edit hook never acquired a claim (for example, a shell edit made
|
|
126
|
+
// just before another session claimed the same file). Keep those paths on
|
|
127
|
+
// the blocked session's durable claim set. The original holder's later
|
|
128
|
+
// commit will then see the overlap instead of silently sweeping this
|
|
129
|
+
// session's working-tree hunks. A successful later commit releases clean
|
|
130
|
+
// paths through the existing post-commit hook.
|
|
131
|
+
retainBlockedStagedPaths(coordRoot, me, mySession, req.staged_paths, peers);
|
|
123
132
|
return {
|
|
124
133
|
allow: false,
|
|
125
134
|
exit_code: 1,
|
|
@@ -132,6 +141,37 @@ export function evaluateCommit(coordRoot, req) {
|
|
|
132
141
|
" active agents:",
|
|
133
142
|
};
|
|
134
143
|
}
|
|
144
|
+
function retainBlockedStagedPaths(coordRoot, instanceId, sessionId, stagedPaths, peers) {
|
|
145
|
+
if (instanceId === "__unattributed__")
|
|
146
|
+
return;
|
|
147
|
+
const self = peers.find((peer) => peer.instance_id === instanceId);
|
|
148
|
+
if (!self)
|
|
149
|
+
return;
|
|
150
|
+
for (const path of stagedPaths) {
|
|
151
|
+
try {
|
|
152
|
+
recordLiveClaimChangeV3({
|
|
153
|
+
coordRoot,
|
|
154
|
+
owner: instanceId,
|
|
155
|
+
nativeSessionId: self.session_id ?? sessionId,
|
|
156
|
+
adapter: adapterFromPlatform(self.platform),
|
|
157
|
+
operation: "acquired",
|
|
158
|
+
path,
|
|
159
|
+
access: "write",
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// The commit is already blocked. Coordination remains fail-open for
|
|
164
|
+
// authority-write failures so a damaged cache cannot brick Git.
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function adapterFromPlatform(platform) {
|
|
169
|
+
if (platform === "cursor")
|
|
170
|
+
return "cursor";
|
|
171
|
+
if (platform === "codex")
|
|
172
|
+
return "codex";
|
|
173
|
+
return "claude-code";
|
|
174
|
+
}
|
|
135
175
|
function findOverlap(staged, files, coordRoot, stagedIsGitlink) {
|
|
136
176
|
for (const claimed of files) {
|
|
137
177
|
if (claimed === staged)
|
|
@@ -188,13 +228,22 @@ function isGitlinkInIndex(coordRoot, path) {
|
|
|
188
228
|
return result.stdout.trim().startsWith("160000 ");
|
|
189
229
|
}
|
|
190
230
|
function isHolderSelfAttributed(coordRoot, holderId, stagedSet, peers) {
|
|
231
|
+
const holder = peers.find((p) => p.instance_id === holderId);
|
|
232
|
+
// Windows-hosted Codex sessions cross a process boundary into WSL, so they
|
|
233
|
+
// deliberately have no usable PID anchor. Their canonical V3 session row is
|
|
234
|
+
// the foreign-identity evidence instead. Treating that row as a transient
|
|
235
|
+
// self identity would suppress the symmetric claim retained after a blocked
|
|
236
|
+
// commit and reopen the working-tree sweep this guard is meant to stop.
|
|
237
|
+
if (holder?.platform === "codex" && holder.session_id) {
|
|
238
|
+
debugGate(coordRoot, { holder: holderId, gate: "B", reason: "canonical_codex_session" });
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
191
241
|
// Gate B (cheaper): live foreign pid-map entry blocks self-attribution.
|
|
192
242
|
if (holderHasLiveForeignPid(coordRoot, holderId)) {
|
|
193
243
|
debugGate(coordRoot, { holder: holderId, gate: "B", reason: "live_pid_anchor" });
|
|
194
244
|
return false;
|
|
195
245
|
}
|
|
196
246
|
// Gate A: every held path is either in the staged set or already clean in HEAD.
|
|
197
|
-
const holder = peers.find((p) => p.instance_id === holderId);
|
|
198
247
|
if (!holder) {
|
|
199
248
|
debugGate(coordRoot, { holder: holderId, gate: "A", reason: "holder_not_found" });
|
|
200
249
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stop-hook.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/rules/stop-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAM3D,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAInE,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,aAAa,CA6BvF;AAED,oFAAoF;AACpF,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,SAAS,OAAO,EAAE,GACzB,aAAa,
|
|
1
|
+
{"version":3,"file":"stop-hook.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/rules/stop-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAM3D,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAInE,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,aAAa,CA6BvF;AAED,oFAAoF;AACpF,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,SAAS,OAAO,EAAE,GACzB,aAAa,CAiIf"}
|
|
@@ -91,17 +91,13 @@ export function evaluateStopHookV3Events(coordRoot, req, events) {
|
|
|
91
91
|
.map((event) => observedBoolean(event.payload.ritual?.status_box_present_strict))
|
|
92
92
|
.filter((value) => value !== undefined);
|
|
93
93
|
const currentStrictBox = claudeContinuation ? req.status_box_present_strict : undefined;
|
|
94
|
-
if (
|
|
94
|
+
if (latestBox === undefined && currentStrictBox === undefined) {
|
|
95
95
|
return evidenceUnavailable("turn.completed has no observed V3 assistant-text status-box result; Stop remains fail-open");
|
|
96
96
|
}
|
|
97
|
-
const ackPresent =
|
|
98
|
-
?
|
|
99
|
-
:
|
|
100
|
-
|
|
101
|
-
: latestBox === true;
|
|
102
|
-
const ackBlock = req.adapter === "cursor"
|
|
103
|
-
? () => rule13Block(coordRoot, req.session_id)
|
|
104
|
-
: () => rule23Block(coordRoot, req.session_id);
|
|
97
|
+
const ackPresent = claudeContinuation
|
|
98
|
+
? strictBoxObservations.includes(true) || currentStrictBox === true
|
|
99
|
+
: latestBox === true;
|
|
100
|
+
const ackBlock = () => rule23Block(coordRoot, req.session_id);
|
|
105
101
|
// Pure prose turns keep the human-visible acknowledgement but do not require
|
|
106
102
|
// task or final-status mutations. This preserves the pre-V3 policy exactly.
|
|
107
103
|
if (!usedTool) {
|
|
@@ -260,7 +256,7 @@ function sessionIdSuffix(sessionId) {
|
|
|
260
256
|
* The verdict keeps the first failure's rule id, so the `blocked_rule`
|
|
261
257
|
* telemetry and the adapter's `rule=` stderr contract are unchanged; the
|
|
262
258
|
* reason enumerates the rest so a single continuation can repair all of them.
|
|
263
|
-
*
|
|
259
|
+
* Duplicate rules are folded so one continuation repairs every missing signal.
|
|
264
260
|
*/
|
|
265
261
|
function mergeStopBlocks(blocks) {
|
|
266
262
|
let primary;
|
|
@@ -450,7 +450,10 @@ function observeCascades(coordRoot, route, records, events, lastByGeneration, no
|
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
452
|
if (event.event_type === "lifecycle.sweep_observed" &&
|
|
453
|
-
|
|
453
|
+
// stale-sweep.ts emits the observation as `stale_heartbeat`; the
|
|
454
|
+
// finalization request it produces is the one named `stale_sweep`.
|
|
455
|
+
// Matching the request name here made this branch unreachable.
|
|
456
|
+
event.payload.observation === "stale_heartbeat") {
|
|
454
457
|
const record = records.find(({ state }) => !state.terminal && state.instance_id === event.payload.subject_instance_id);
|
|
455
458
|
const last = record ? lastByGeneration.get(record.state.generation_id) : undefined;
|
|
456
459
|
if (!record?.state.last_event_id || !last)
|
|
@@ -28,8 +28,9 @@ export interface ArtifactManifestV1 {
|
|
|
28
28
|
};
|
|
29
29
|
released_at?: string;
|
|
30
30
|
released_by?: ArtifactActor;
|
|
31
|
+
oversize_acknowledged?: boolean;
|
|
31
32
|
}
|
|
32
|
-
export type ArtifactClassification = "managed-active" | "managed-current" | "managed-expired" | "managed-tracked" | "invalid-manifest" | "unmanaged" | "symlink" | "unknown";
|
|
33
|
+
export type ArtifactClassification = "managed-active" | "managed-current" | "managed-expired" | "managed-oversize" | "managed-over-budget" | "managed-tracked" | "invalid-manifest" | "unmanaged" | "symlink" | "unknown";
|
|
33
34
|
export interface ArtifactInventoryEntry {
|
|
34
35
|
name: string;
|
|
35
36
|
path: string;
|
|
@@ -44,6 +45,7 @@ export interface ArtifactInventoryEntry {
|
|
|
44
45
|
last_modified_at: string | null;
|
|
45
46
|
expires_at: string | null;
|
|
46
47
|
owner_instance_id: string | null;
|
|
48
|
+
oversize_acknowledged: boolean;
|
|
47
49
|
}
|
|
48
50
|
export interface ArtifactCreateInput {
|
|
49
51
|
slug: string;
|
|
@@ -52,11 +54,25 @@ export interface ArtifactCreateInput {
|
|
|
52
54
|
actor?: ArtifactActor;
|
|
53
55
|
now?: Date;
|
|
54
56
|
id?: string;
|
|
57
|
+
big?: boolean;
|
|
55
58
|
}
|
|
56
59
|
export interface ArtifactMutationInput {
|
|
57
60
|
actor?: ArtifactActor;
|
|
58
61
|
now?: Date;
|
|
59
62
|
}
|
|
63
|
+
export interface ArtifactAdoptionResult {
|
|
64
|
+
candidates: Array<{
|
|
65
|
+
path: string;
|
|
66
|
+
name: string;
|
|
67
|
+
bytes: number;
|
|
68
|
+
kind: "file" | "directory";
|
|
69
|
+
}>;
|
|
70
|
+
candidate_bytes: number;
|
|
71
|
+
requires_big: boolean;
|
|
72
|
+
adopted_artifact_id: string | null;
|
|
73
|
+
adopted_path: string | null;
|
|
74
|
+
adopted_directories: number;
|
|
75
|
+
}
|
|
60
76
|
export declare function artifactsRoot(repoRoot: string): string;
|
|
61
77
|
/** Public config-aware default for embedding hosts that create artifact units. */
|
|
62
78
|
export declare function configuredArtifactRetentionDays(repoRoot: string): number;
|
|
@@ -77,6 +93,15 @@ export declare function showArtifact(repoRoot: string, ref: string, opts?: {
|
|
|
77
93
|
};
|
|
78
94
|
export declare function renewArtifact(repoRoot: string, ref: string, days: number, reason: string, input?: ArtifactMutationInput): ArtifactManifestV1;
|
|
79
95
|
export declare function releaseArtifact(repoRoot: string, ref: string, input?: ArtifactMutationInput): ArtifactManifestV1;
|
|
96
|
+
/** Adopt untracked loose files and legacy directories without changing directory paths. */
|
|
97
|
+
export declare function adoptUnmanagedArtifactFiles(repoRoot: string, input: {
|
|
98
|
+
yes?: boolean;
|
|
99
|
+
big?: boolean;
|
|
100
|
+
purpose: string;
|
|
101
|
+
retentionDays: number;
|
|
102
|
+
actor?: ArtifactActor;
|
|
103
|
+
now?: Date;
|
|
104
|
+
}): ArtifactAdoptionResult;
|
|
80
105
|
export declare function cleanArtifacts(repoRoot: string, opts?: {
|
|
81
106
|
yes?: boolean;
|
|
82
107
|
now?: Date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/artifacts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/artifacts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ import { randomUUID } from "node:crypto";
|
|
|
12
12
|
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync, } from "node:fs";
|
|
13
13
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
14
14
|
import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.js";
|
|
15
|
-
import { artifactAutoCleanEnabled, artifactAutoCleanIntervalHours, artifactDefaultRetentionDays, } from "../config.js";
|
|
15
|
+
import { artifactAutoCleanEnabled, artifactAutoCleanIntervalHours, artifactDefaultRetentionDays, artifactMaxBytes, artifactMaxUnitBytes, } from "../config.js";
|
|
16
16
|
import { ARTIFACT_MANIFEST, ARTIFACT_SCHEMA_VERSION, ARTIFACTS_DIR } from "./constants.js";
|
|
17
17
|
export { ARTIFACT_MANIFEST, ARTIFACT_SCHEMA_VERSION, ARTIFACTS_DIR } from "./constants.js";
|
|
18
18
|
export function artifactsRoot(repoRoot) {
|
|
@@ -51,6 +51,7 @@ export function createArtifact(repoRoot, input) {
|
|
|
51
51
|
retention: {
|
|
52
52
|
expires_at: addDays(now, retentionDays).toISOString(),
|
|
53
53
|
},
|
|
54
|
+
...(input.big ? { oversize_acknowledged: true } : {}),
|
|
54
55
|
};
|
|
55
56
|
atomicWriteManifest(path, manifest);
|
|
56
57
|
return { path, manifest };
|
|
@@ -75,11 +76,13 @@ export function inventoryArtifacts(repoRoot, opts = {}) {
|
|
|
75
76
|
for (const name of names) {
|
|
76
77
|
rows.push(classifyArtifactPath(repoRoot, join(root, name), now, freshnessSeconds));
|
|
77
78
|
}
|
|
78
|
-
return rows;
|
|
79
|
+
return applyArtifactBudgets(repoRoot, rows);
|
|
79
80
|
}
|
|
80
81
|
export function showArtifact(repoRoot, ref, opts = {}) {
|
|
81
82
|
const path = resolveArtifactRef(repoRoot, ref);
|
|
82
|
-
const entry =
|
|
83
|
+
const entry = inventoryArtifacts(repoRoot, opts).find((row) => row.path === path);
|
|
84
|
+
if (!entry)
|
|
85
|
+
throw new Error(`artifact "${ref}" was not found`);
|
|
83
86
|
const parsed = readManifest(path);
|
|
84
87
|
if (!parsed.ok)
|
|
85
88
|
throw new Error(parsed.reason);
|
|
@@ -122,6 +125,98 @@ export function releaseArtifact(repoRoot, ref, input = {}) {
|
|
|
122
125
|
atomicWriteManifest(path, manifest);
|
|
123
126
|
return manifest;
|
|
124
127
|
}
|
|
128
|
+
/** Adopt untracked loose files and legacy directories without changing directory paths. */
|
|
129
|
+
export function adoptUnmanagedArtifactFiles(repoRoot, input) {
|
|
130
|
+
const now = input.now ?? new Date();
|
|
131
|
+
const candidates = [];
|
|
132
|
+
for (const row of inventoryArtifacts(repoRoot, { now })) {
|
|
133
|
+
if (row.classification !== "unmanaged")
|
|
134
|
+
continue;
|
|
135
|
+
try {
|
|
136
|
+
const stat = lstatSync(row.path);
|
|
137
|
+
if (stat.isSymbolicLink() || containsTrackedPath(repoRoot, row.path))
|
|
138
|
+
continue;
|
|
139
|
+
if (stat.isFile()) {
|
|
140
|
+
candidates.push({ path: row.path, name: row.name, bytes: stat.size, kind: "file" });
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (stat.isDirectory() && !existsSync(join(row.path, ARTIFACT_MANIFEST))) {
|
|
144
|
+
const bytes = safeTreeSize(row.path);
|
|
145
|
+
if (bytes !== null && normalizeSlug(row.name)) {
|
|
146
|
+
candidates.push({ path: row.path, name: row.name, bytes, kind: "directory" });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// A racing or unreadable entry stays unmanaged.
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const candidateBytes = candidates.reduce((sum, row) => sum + row.bytes, 0);
|
|
155
|
+
const fileBytes = candidates.reduce((sum, row) => sum + (row.kind === "file" ? row.bytes : 0), 0);
|
|
156
|
+
const maxUnitBytes = artifactMaxUnitBytes(repoRoot);
|
|
157
|
+
const requiresBig = fileBytes > maxUnitBytes ||
|
|
158
|
+
candidates.some((row) => row.kind === "directory" && row.bytes > maxUnitBytes);
|
|
159
|
+
const preview = {
|
|
160
|
+
candidates,
|
|
161
|
+
candidate_bytes: candidateBytes,
|
|
162
|
+
requires_big: requiresBig,
|
|
163
|
+
adopted_artifact_id: null,
|
|
164
|
+
adopted_path: null,
|
|
165
|
+
adopted_directories: 0,
|
|
166
|
+
};
|
|
167
|
+
if (!input.yes || candidates.length === 0)
|
|
168
|
+
return preview;
|
|
169
|
+
if (requiresBig && !input.big) {
|
|
170
|
+
throw new Error("unmanaged adoption exceeds the per-bundle ceiling; repeat with --big");
|
|
171
|
+
}
|
|
172
|
+
// Revalidate every exact source before creating a destination. A changed,
|
|
173
|
+
// tracked, linked, or non-regular entry aborts the whole adoption.
|
|
174
|
+
for (const candidate of candidates) {
|
|
175
|
+
const stat = lstatSync(candidate.path);
|
|
176
|
+
const bytes = stat.isDirectory() ? safeTreeSize(candidate.path) : stat.size;
|
|
177
|
+
if (stat.isSymbolicLink() ||
|
|
178
|
+
bytes !== candidate.bytes ||
|
|
179
|
+
containsTrackedPath(repoRoot, candidate.path)) {
|
|
180
|
+
throw new Error(`unmanaged entry changed before adoption: ${candidate.name}`);
|
|
181
|
+
}
|
|
182
|
+
if (candidate.kind === "file" ? !stat.isFile() : !stat.isDirectory()) {
|
|
183
|
+
throw new Error(`unmanaged entry changed before adoption: ${candidate.name}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const files = candidates.filter((candidate) => candidate.kind === "file");
|
|
187
|
+
const created = files.length
|
|
188
|
+
? createArtifact(repoRoot, {
|
|
189
|
+
slug: "adopted-unmanaged",
|
|
190
|
+
purpose: input.purpose,
|
|
191
|
+
retentionDays: input.retentionDays,
|
|
192
|
+
actor: input.actor,
|
|
193
|
+
now,
|
|
194
|
+
big: input.big,
|
|
195
|
+
})
|
|
196
|
+
: null;
|
|
197
|
+
for (const candidate of files)
|
|
198
|
+
renameSync(candidate.path, join(created.path, candidate.name));
|
|
199
|
+
const retentionDays = positiveDays(input.retentionDays);
|
|
200
|
+
const directories = candidates.filter((candidate) => candidate.kind === "directory");
|
|
201
|
+
for (const candidate of directories) {
|
|
202
|
+
atomicWriteManifest(candidate.path, {
|
|
203
|
+
schema_version: ARTIFACT_SCHEMA_VERSION,
|
|
204
|
+
artifact_id: randomUUID(),
|
|
205
|
+
slug: normalizeSlug(candidate.name),
|
|
206
|
+
purpose: `${input.purpose}: ${candidate.name}`,
|
|
207
|
+
created_at: now.toISOString(),
|
|
208
|
+
created_by: input.actor,
|
|
209
|
+
retention: { expires_at: addDays(now, retentionDays).toISOString() },
|
|
210
|
+
...(input.big ? { oversize_acknowledged: true } : {}),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
...preview,
|
|
215
|
+
adopted_artifact_id: created?.manifest.artifact_id ?? null,
|
|
216
|
+
adopted_path: created?.path ?? null,
|
|
217
|
+
adopted_directories: directories.length,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
125
220
|
export function cleanArtifacts(repoRoot, opts = {}) {
|
|
126
221
|
const now = opts.now ?? new Date();
|
|
127
222
|
const freshnessSeconds = opts.freshnessSeconds ?? 600;
|
|
@@ -129,13 +224,21 @@ export function cleanArtifacts(repoRoot, opts = {}) {
|
|
|
129
224
|
if (!opts.yes)
|
|
130
225
|
return rows;
|
|
131
226
|
return rows.map((entry) => {
|
|
132
|
-
if (entry.
|
|
227
|
+
if (entry.action !== "would-delete")
|
|
133
228
|
return entry;
|
|
134
229
|
// Reclassify immediately before removal. A renewal, release-state change,
|
|
135
230
|
// heartbeat, symlink swap, or tracked file added since inventory must win.
|
|
136
|
-
const current =
|
|
137
|
-
if (current
|
|
231
|
+
const current = inventoryArtifacts(repoRoot, { now, freshnessSeconds }).find((row) => row.path === entry.path);
|
|
232
|
+
if (!current) {
|
|
233
|
+
return { ...entry, classification: "unknown", reason: "entry disappeared", action: "keep" };
|
|
234
|
+
}
|
|
235
|
+
if (current.action !== "would-delete" ||
|
|
236
|
+
current.artifact_id !== entry.artifact_id ||
|
|
237
|
+
current.bytes !== entry.bytes ||
|
|
238
|
+
current.last_modified_at !== entry.last_modified_at ||
|
|
239
|
+
current.expires_at !== entry.expires_at) {
|
|
138
240
|
return current;
|
|
241
|
+
}
|
|
139
242
|
try {
|
|
140
243
|
const top = lstatSync(current.path);
|
|
141
244
|
if (!top.isDirectory() || top.isSymbolicLink()) {
|
|
@@ -264,6 +367,7 @@ function classifyArtifactPath(repoRoot, path, now, freshnessSeconds) {
|
|
|
264
367
|
last_modified_at: new Date(effectiveLastModifiedMs).toISOString(),
|
|
265
368
|
expires_at: effectiveExpiresAt,
|
|
266
369
|
owner_instance_id: manifest.created_by?.instance_id ?? null,
|
|
370
|
+
oversize_acknowledged: manifest.oversize_acknowledged === true,
|
|
267
371
|
});
|
|
268
372
|
if (base.bytes === null || lastModifiedMs === null) {
|
|
269
373
|
return {
|
|
@@ -309,6 +413,38 @@ function classifyArtifactPath(repoRoot, path, now, freshnessSeconds) {
|
|
|
309
413
|
action: "would-delete",
|
|
310
414
|
};
|
|
311
415
|
}
|
|
416
|
+
function applyArtifactBudgets(repoRoot, inputRows) {
|
|
417
|
+
const maxUnitBytes = artifactMaxUnitBytes(repoRoot);
|
|
418
|
+
const maxBytes = artifactMaxBytes(repoRoot);
|
|
419
|
+
const rows = inputRows.map((row) => ({ ...row }));
|
|
420
|
+
for (const row of rows) {
|
|
421
|
+
if (row.classification === "managed-current" &&
|
|
422
|
+
row.bytes !== null &&
|
|
423
|
+
row.bytes > maxUnitBytes &&
|
|
424
|
+
!row.oversize_acknowledged) {
|
|
425
|
+
row.classification = "managed-oversize";
|
|
426
|
+
row.reason = `bundle uses ${row.bytes} bytes, above the ${maxUnitBytes}-byte ceiling without --big`;
|
|
427
|
+
row.action = "would-delete";
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
const managedBytes = rows.reduce((sum, row) => sum + (row.artifact_id && row.bytes !== null ? row.bytes : 0), 0);
|
|
431
|
+
let retainedBytes = managedBytes -
|
|
432
|
+
rows.reduce((sum, row) => sum + (row.action === "would-delete" && row.bytes !== null ? row.bytes : 0), 0);
|
|
433
|
+
if (retainedBytes <= maxBytes)
|
|
434
|
+
return rows;
|
|
435
|
+
const candidates = rows
|
|
436
|
+
.filter((row) => row.classification === "managed-current" && row.action === "keep" && row.bytes !== null)
|
|
437
|
+
.sort((left, right) => `${left.expires_at ?? ""}\0${left.created_at ?? ""}\0${left.name}`.localeCompare(`${right.expires_at ?? ""}\0${right.created_at ?? ""}\0${right.name}`));
|
|
438
|
+
for (const row of candidates) {
|
|
439
|
+
if (retainedBytes <= maxBytes)
|
|
440
|
+
break;
|
|
441
|
+
row.classification = "managed-over-budget";
|
|
442
|
+
row.reason = `repository artifact budget is ${maxBytes} bytes; earliest-expiring inactive bundles are removed first`;
|
|
443
|
+
row.action = "would-delete";
|
|
444
|
+
retainedBytes -= row.bytes ?? 0;
|
|
445
|
+
}
|
|
446
|
+
return rows;
|
|
447
|
+
}
|
|
312
448
|
function readManifest(path) {
|
|
313
449
|
const manifestPath = join(path, ARTIFACT_MANIFEST);
|
|
314
450
|
if (!existsSync(manifestPath)) {
|
|
@@ -357,6 +493,9 @@ function readManifest(path) {
|
|
|
357
493
|
if (m.released_by !== undefined && !validActor(m.released_by)) {
|
|
358
494
|
return { ok: false, reason: "invalid released_by" };
|
|
359
495
|
}
|
|
496
|
+
if (m.oversize_acknowledged !== undefined && typeof m.oversize_acknowledged !== "boolean") {
|
|
497
|
+
return { ok: false, reason: "invalid oversize_acknowledged" };
|
|
498
|
+
}
|
|
360
499
|
return { ok: true, manifest: m };
|
|
361
500
|
}
|
|
362
501
|
function atomicWriteManifest(path, manifest) {
|
|
@@ -460,6 +599,7 @@ function rowFor(path, name, repoRoot, classification, reason, bytes = safeTreeSi
|
|
|
460
599
|
last_modified_at: null,
|
|
461
600
|
expires_at: null,
|
|
462
601
|
owner_instance_id: null,
|
|
602
|
+
oversize_acknowledged: false,
|
|
463
603
|
};
|
|
464
604
|
}
|
|
465
605
|
function normalizeSlug(value) {
|
package/dist/core/config.d.ts
CHANGED
|
@@ -185,6 +185,14 @@ export declare function coordFreshnessSeconds(coordRoot?: string | null): number
|
|
|
185
185
|
* `0` (or a negative value) disables automatic rotation.
|
|
186
186
|
*/
|
|
187
187
|
export declare function eventLedgerRotateActiveBytes(coordRoot?: string | null): number;
|
|
188
|
+
export interface EventLedgerArchivePolicy {
|
|
189
|
+
maxBytes: number;
|
|
190
|
+
maxAgeDays: number;
|
|
191
|
+
keepMin: number;
|
|
192
|
+
autoClean: boolean;
|
|
193
|
+
}
|
|
194
|
+
/** Bounded retention for closed V3 epochs under `ledgers/v3-archives`. */
|
|
195
|
+
export declare function eventLedgerArchivePolicy(coordRoot?: string | null): EventLedgerArchivePolicy;
|
|
188
196
|
/**
|
|
189
197
|
* Resolve the standalone dashboard port.
|
|
190
198
|
*
|
|
@@ -200,6 +208,10 @@ export declare function sessionFinalizationConfig(coordRoot?: string | null): Se
|
|
|
200
208
|
* `artifacts.default_retention_days` -> 3 days.
|
|
201
209
|
*/
|
|
202
210
|
export declare function artifactDefaultRetentionDays(coordRoot?: string | null): number;
|
|
211
|
+
/** Soft repository budget for managed working artifacts. */
|
|
212
|
+
export declare function artifactMaxBytes(coordRoot?: string | null): number;
|
|
213
|
+
/** Size at which one bundle requires an explicit `artifacts create --big` acknowledgement. */
|
|
214
|
+
export declare function artifactMaxUnitBytes(coordRoot?: string | null): number;
|
|
203
215
|
/**
|
|
204
216
|
* Whether the daily SessionStart sweep of expired artifact workspaces runs.
|
|
205
217
|
* Precedence: `HARNERY_ARTIFACT_AUTO_CLEAN` (0/false disables) ->
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAUH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,wCAAwC,EAAE,MAAM,gCAAgC,CAAC;AAE1F,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,yFAAyF;AACzF,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,2EAA2E;AAC3E,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,MAAM,WAAW,yBAAyB;IACxC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,eAAO,MAAM,mCAAmC,EAAE,yBAMjD,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,4BAA4B,CAAC;CAC3C;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
package/dist/core/config.js
CHANGED
|
@@ -473,6 +473,20 @@ export function eventLedgerRotateActiveBytes(coordRoot) {
|
|
|
473
473
|
const root = coordRoot ?? findCoordRoot();
|
|
474
474
|
return resolveEventLedgerRotateActiveBytesV3(root);
|
|
475
475
|
}
|
|
476
|
+
const DEFAULT_EVENT_ARCHIVE_MAX_BYTES = 1024 * 1024 * 1024;
|
|
477
|
+
const DEFAULT_EVENT_ARCHIVE_MAX_AGE_DAYS = 7;
|
|
478
|
+
const DEFAULT_EVENT_ARCHIVE_KEEP_MIN = 2;
|
|
479
|
+
/** Bounded retention for closed V3 epochs under `ledgers/v3-archives`. */
|
|
480
|
+
export function eventLedgerArchivePolicy(coordRoot) {
|
|
481
|
+
const root = coordRoot ?? findCoordRoot();
|
|
482
|
+
const configured = root ? readConfig(root).events : undefined;
|
|
483
|
+
return {
|
|
484
|
+
maxBytes: integerSetting(coordEnv("EVENT_V3_ARCHIVE_MAX_BYTES"), configured?.archive_max_bytes, 64 * 1024 * 1024, 1024 * 1024 * 1024 * 1024, DEFAULT_EVENT_ARCHIVE_MAX_BYTES),
|
|
485
|
+
maxAgeDays: integerSetting(coordEnv("EVENT_V3_ARCHIVE_MAX_AGE_DAYS"), configured?.archive_max_age_days, 1, 3650, DEFAULT_EVENT_ARCHIVE_MAX_AGE_DAYS),
|
|
486
|
+
keepMin: integerSetting(coordEnv("EVENT_V3_ARCHIVE_KEEP_MIN"), configured?.archive_keep_min, 1, 1000, DEFAULT_EVENT_ARCHIVE_KEEP_MIN),
|
|
487
|
+
autoClean: booleanSetting(coordEnv("EVENT_V3_ARCHIVE_AUTO_CLEAN"), configured?.archive_auto_clean, true),
|
|
488
|
+
};
|
|
489
|
+
}
|
|
476
490
|
function parseWebPort(value, source) {
|
|
477
491
|
const port = typeof value === "number" ? value : Number(value);
|
|
478
492
|
if (!Number.isInteger(port) || port < 1024 || port > 65535) {
|
|
@@ -540,6 +554,18 @@ export function artifactDefaultRetentionDays(coordRoot) {
|
|
|
540
554
|
? configured
|
|
541
555
|
: 3;
|
|
542
556
|
}
|
|
557
|
+
const DEFAULT_ARTIFACT_MAX_BYTES = 20 * 1024 * 1024 * 1024;
|
|
558
|
+
const DEFAULT_ARTIFACT_MAX_UNIT_BYTES = 1024 * 1024 * 1024;
|
|
559
|
+
/** Soft repository budget for managed working artifacts. */
|
|
560
|
+
export function artifactMaxBytes(coordRoot) {
|
|
561
|
+
const root = coordRoot ?? findCoordRoot();
|
|
562
|
+
return integerSetting(coordEnv("ARTIFACT_MAX_BYTES"), root ? readConfig(root).artifacts?.max_bytes : undefined, 64 * 1024 * 1024, 1024 * 1024 * 1024 * 1024, DEFAULT_ARTIFACT_MAX_BYTES);
|
|
563
|
+
}
|
|
564
|
+
/** Size at which one bundle requires an explicit `artifacts create --big` acknowledgement. */
|
|
565
|
+
export function artifactMaxUnitBytes(coordRoot) {
|
|
566
|
+
const root = coordRoot ?? findCoordRoot();
|
|
567
|
+
return integerSetting(coordEnv("ARTIFACT_MAX_UNIT_BYTES"), root ? readConfig(root).artifacts?.max_unit_bytes : undefined, 16 * 1024 * 1024, 1024 * 1024 * 1024 * 1024, DEFAULT_ARTIFACT_MAX_UNIT_BYTES);
|
|
568
|
+
}
|
|
543
569
|
/**
|
|
544
570
|
* Whether the daily SessionStart sweep of expired artifact workspaces runs.
|
|
545
571
|
* Precedence: `HARNERY_ARTIFACT_AUTO_CLEAN` (0/false disables) ->
|
|
@@ -571,6 +597,23 @@ export function artifactAutoCleanIntervalHours() {
|
|
|
571
597
|
}
|
|
572
598
|
return 24;
|
|
573
599
|
}
|
|
600
|
+
function integerSetting(envValue, configured, minimum, maximum, fallback) {
|
|
601
|
+
for (const value of [envValue, configured]) {
|
|
602
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
603
|
+
if (Number.isSafeInteger(parsed) && parsed >= minimum && parsed <= maximum)
|
|
604
|
+
return parsed;
|
|
605
|
+
}
|
|
606
|
+
return fallback;
|
|
607
|
+
}
|
|
608
|
+
function booleanSetting(envValue, configured, fallback) {
|
|
609
|
+
if (envValue !== undefined) {
|
|
610
|
+
if (envValue === "1" || envValue.toLowerCase() === "true")
|
|
611
|
+
return true;
|
|
612
|
+
if (envValue === "0" || envValue.toLowerCase() === "false")
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
return typeof configured === "boolean" ? configured : fallback;
|
|
616
|
+
}
|
|
574
617
|
/**
|
|
575
618
|
* `harn backup` (restic) defaults. Per field, precedence is env → config → built-in:
|
|
576
619
|
* repo: `HARNERY_RESTIC_REPO` → `backup.repo` → `~/.cache/harnery/restic-repo`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SupervisorCapability, SupervisorFinding } from "../supervisor/contract.js";
|
|
2
|
+
import { type DiagnosticAdvice } from "./contract.js";
|
|
3
|
+
export interface BuildDiagnosticAdviceInput {
|
|
4
|
+
findings: readonly SupervisorFinding[];
|
|
5
|
+
sourceCapability: SupervisorCapability;
|
|
6
|
+
evaluatedAt: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function buildDiagnosticAdvice(input: BuildDiagnosticAdviceInput): DiagnosticAdvice;
|
|
9
|
+
//# sourceMappingURL=advice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advice.d.ts","sourceRoot":"","sources":["../../../src/core/diagnostics/advice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAGL,KAAK,gBAAgB,EAGtB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,gBAAgB,EAAE,oBAAoB,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;CACrB;AAQD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,gBAAgB,CA4CzF"}
|