opencode-swarm 7.152.1 → 7.153.1
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/.opencode/skills/swarm-pr-review/SKILL.md +10 -10
- package/dist/background/pending-delegations.d.ts +7 -0
- package/dist/cli/{capability-probe-va4kk8vg.js → capability-probe-5wa7mcp6.js} +3 -2
- package/dist/cli/{config-doctor-bbqmye7a.js → config-doctor-ze21qs6b.js} +3 -3
- package/dist/cli/{core-fh4e6ex0.js → core-qdmhh1kx.js} +2 -2
- package/dist/cli/{curation-policy-nem98yc9.js → curation-policy-twa6agf8.js} +7 -7
- package/dist/cli/{curator-909s9dvs.js → curator-hxb3wsxr.js} +32 -33
- package/dist/cli/curator-llm-factory-s8atmc2n.js +64 -0
- package/dist/cli/{evidence-summary-service-kqw4y0yr.js → evidence-summary-service-wzzym9r7.js} +15 -15
- package/dist/cli/{gate-evidence-ycts62pj.js → gate-evidence-f71dn9vv.js} +8 -8
- package/dist/cli/guardrail-explain-5kzeem4m.js +65 -0
- package/dist/cli/{guardrail-log-e1tmdxxa.js → guardrail-log-38jnajpa.js} +6 -6
- package/dist/cli/{guardrail-reset-gdnaxxvb.js → guardrail-reset-wzvtmpn2.js} +32 -33
- package/dist/cli/{hive-promoter-d0xydg6r.js → hive-promoter-55qcqgfx.js} +32 -33
- package/dist/cli/{index-x6803sxh.js → index-0tyc8kdg.js} +2 -2
- package/dist/cli/{index-z8s2asdk.js → index-0tzv5zg2.js} +22 -150
- package/dist/cli/{index-3djxegsc.js → index-1akn19mp.js} +1 -1
- package/dist/cli/{index-q77e475x.js → index-1dtshrzg.js} +5 -5
- package/dist/cli/{index-73pmnsjg.js → index-1gzdnjg9.js} +2 -2
- package/dist/cli/{index-4tvvh7pn.js → index-23rneydq.js} +36 -35
- package/dist/cli/{index-z4bg1hv8.js → index-2mqmvxac.js} +9 -2
- package/dist/cli/index-3cegckkq.js +239 -0
- package/dist/cli/{index-pvrap7xg.js → index-3ttktt56.js} +1 -1
- package/dist/cli/{index-85gkedsf.js → index-4fwbbad3.js} +521 -15
- package/dist/cli/{index-qqrdmaxq.js → index-4g0g3dqz.js} +2 -2
- package/dist/cli/{index-44xdtqz8.js → index-4pjkdcgc.js} +1 -1
- package/dist/cli/{index-29vd7v3e.js → index-6vgb5fyb.js} +1 -1
- package/dist/cli/{index-sg2sx2q7.js → index-6ybjrqf7.js} +13095 -9360
- package/dist/cli/{index-txbd25bc.js → index-891g7hbf.js} +1 -1
- package/dist/cli/{index-02ajc6d1.js → index-8v9sj4aq.js} +2 -2
- package/dist/cli/{index-z9fyd0d6.js → index-9v8d3c0k.js} +450 -48
- package/dist/cli/{index-26vyr198.js → index-af0cqe6n.js} +16 -16
- package/dist/cli/{index-ryecg2st.js → index-ajkxx2k6.js} +3 -3
- package/dist/cli/{index-k3d919yf.js → index-gn26q90p.js} +85 -24
- package/dist/cli/{index-0tfgn5x0.js → index-k10qtq71.js} +9 -9
- package/dist/cli/{index-xyfdmrv7.js → index-mb7b1gye.js} +3 -3
- package/dist/cli/{index-0q2mjxp2.js → index-meg33yyv.js} +1 -1
- package/dist/cli/{index-cpg98bh1.js → index-myt57pht.js} +1 -1
- package/dist/cli/{index-2e1294d1.js → index-n5pxkera.js} +16 -10
- package/dist/cli/{index-n0vc5b5t.js → index-n823qsae.js} +16 -7
- package/dist/cli/{index-6zkm4p7p.js → index-pk1gbqmq.js} +1 -1
- package/dist/cli/{index-nd8tkb3g.js → index-smqsp8hs.js} +5 -5
- package/dist/cli/{index-7fh82sm1.js → index-td0jz8xe.js} +6 -6
- package/dist/cli/{index-dn6yt0xg.js → index-tdzbm974.js} +7 -7
- package/dist/cli/{index-rq6aetkv.js → index-v689bmr2.js} +4 -4
- package/dist/cli/{index-79g6edht.js → index-x3y6zhgj.js} +1 -1
- package/dist/cli/{index-aw492hpn.js → index-x8vw6ap1.js} +58 -41
- package/dist/cli/{index-96m8ckpq.js → index-xkjrg9k4.js} +4 -4
- package/dist/cli/{index-mken64yj.js → index-zppxpc3y.js} +2 -2
- package/dist/cli/index.js +32 -33
- package/dist/cli/{knowledge-escalator-4egcr928.js → knowledge-escalator-w05ztgvk.js} +13 -13
- package/dist/cli/{knowledge-events-kdyv4jzn.js → knowledge-events-pwm9jc0m.js} +11 -11
- package/dist/cli/{knowledge-link-h8cwj7af.js → knowledge-link-ge0rddxw.js} +6 -6
- package/dist/cli/{knowledge-store-dq3cvg53.js → knowledge-store-4xv65tj2.js} +7 -7
- package/dist/cli/{knowledge-validator-4bhtden9.js → knowledge-validator-0ttfsca7.js} +9 -9
- package/dist/cli/{model-preflight-7ea00h34.js → model-preflight-b95w8wxy.js} +1 -1
- package/dist/cli/{pending-delegations-a2nmssr1.js → pending-delegations-nk78wx7h.js} +4 -4
- package/dist/cli/{pr-subscriptions-7879nq5k.js → pr-subscriptions-dq1f61ye.js} +4 -4
- package/dist/cli/{runner-w81n9js3.js → runner-n50w1y4w.js} +7 -7
- package/dist/cli/{scan-cursor-2eezv81a.js → scan-cursor-b6n15w8d.js} +8 -8
- package/dist/cli/{schema-v4qcqhek.js → schema-jkbfwqr2.js} +2 -2
- package/dist/cli/{scope-persistence-y2r227r0.js → scope-persistence-5xt2m5ep.js} +10 -10
- package/dist/cli/{skill-generator-hhzxvb3h.js → skill-generator-3keadpf7.js} +15 -15
- package/dist/cli/{telemetry-52pw5xac.js → telemetry-hh1j99za.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-p31zm5k0.js → worktree-collision-ownership-4drcjymy.js} +15 -10
- package/dist/cli/{worktree-isolation-ve338ez6.js → worktree-isolation-1ymaxn4h.js} +32 -33
- package/dist/commands/approve-write.d.ts +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/lanes.d.ts +25 -0
- package/dist/commands/registry.d.ts +7 -0
- package/dist/config/schema.d.ts +39 -4
- package/dist/consensus/contracts.d.ts +14 -0
- package/dist/consensus/corpus.d.ts +16 -0
- package/dist/hooks/delegation-gate/worktree-isolation.d.ts +50 -3
- package/dist/hooks/delegation-gate/worktree-provisioning-owner.d.ts +40 -2
- package/dist/hooks/delegation-gate/worktree-recovery-authority.d.ts +201 -0
- package/dist/hooks/full-auto-permission.d.ts +7 -0
- package/dist/hooks/guardrails/index.d.ts +2 -1
- package/dist/hooks/guardrails/tool-before.d.ts +4 -0
- package/dist/hooks/init-orphan-recovery.d.ts +5 -1
- package/dist/hooks/pr-workflow-gate.d.ts +12 -0
- package/dist/hooks/scope-guard.d.ts +1 -3
- package/dist/hooks/trajectory-logger.d.ts +22 -6
- package/dist/hooks/trajectory-step-state.d.ts +43 -2
- package/dist/index.js +645 -622
- package/dist/learning/provenance.d.ts +9 -0
- package/dist/observability/catalog.d.ts +6 -4
- package/dist/prm/index.d.ts +3 -3
- package/dist/prm/replay.d.ts +29 -2
- package/dist/prm/trajectory-store.d.ts +210 -20
- package/dist/sandbox/capability-probe.d.ts +40 -1
- package/dist/sandbox/executor.d.ts +26 -1
- package/dist/sandbox/linux/bubblewrap-executor.d.ts +3 -1
- package/dist/sandbox/macos/sandbox-exec-executor.d.ts +3 -1
- package/dist/sandbox/skip-state.d.ts +24 -0
- package/dist/sandbox/win32/native-sandbox-executor.d.ts +5 -1
- package/dist/security/command-classifier.d.ts +22 -0
- package/dist/security/protected-input-integrity.d.ts +19 -0
- package/dist/security/protected-path-policy.d.ts +9 -0
- package/dist/security/write-authority.d.ts +46 -0
- package/dist/services/diagnose-service.d.ts +1 -1
- package/dist/services/skill-generator.d.ts +2 -0
- package/dist/services/skill-improver.d.ts +69 -0
- package/dist/telemetry.d.ts +21 -1
- package/dist/tools/dispatch-lanes.d.ts +47 -0
- package/dist/tools/repo-graph/query.d.ts +2 -1
- package/dist/tools/repo-graph/types.d.ts +64 -0
- package/dist/tools/repo-graph.d.ts +1 -1
- package/dist/tools/skill-improve.d.ts +7 -0
- package/dist/utils/atomic-write.d.ts +2 -0
- package/dist/utils/canonical-root.d.ts +31 -0
- package/dist/workflow/coder-settlement.d.ts +2 -0
- package/dist/worktree/index.d.ts +2 -2
- package/dist/worktree/merge.d.ts +47 -0
- package/package.json +2 -1
- package/dist/cli/curator-llm-factory-462rysph.js +0 -65
- package/dist/cli/guardrail-explain-7620hasq.js +0 -66
- package/dist/cli/index-3g0xk6tk.js +0 -219
- package/dist/cli/index-fxvgaeq4.js +0 -125
- package/dist/cli/worktree-provisioning-owner-cve95q4f.js +0 -22
- package/dist/cli/{curator-drift-2h1d2fnq.js → curator-drift-h57z6tm3.js} +1 -1
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* supply `producedAt` — callers that need determinism pass it explicitly.
|
|
18
18
|
*/
|
|
19
19
|
import { z } from 'zod';
|
|
20
|
+
import { type WriteAuthorityOrigin } from '../security/write-authority.js';
|
|
20
21
|
/**
|
|
21
22
|
* Hard cap on entries retained per reference class. Sorting happens before the
|
|
22
23
|
* cap so truncation is deterministic rather than insertion-order dependent.
|
|
@@ -41,6 +42,12 @@ export declare const LearningProvenanceV1Schema: z.ZodObject<{
|
|
|
41
42
|
writeOrigin: z.ZodObject<{
|
|
42
43
|
sessionId: z.ZodOptional<z.ZodString>;
|
|
43
44
|
agentRole: z.ZodOptional<z.ZodString>;
|
|
45
|
+
authority: z.ZodOptional<z.ZodEnum<{
|
|
46
|
+
critic_approved: "critic_approved";
|
|
47
|
+
autonomous: "autonomous";
|
|
48
|
+
optimizer_proposed: "optimizer_proposed";
|
|
49
|
+
human_approved: "human_approved";
|
|
50
|
+
}>>;
|
|
44
51
|
producedAt: z.ZodISODateTime;
|
|
45
52
|
}, z.core.$strict>;
|
|
46
53
|
}, z.core.$strict>;
|
|
@@ -56,6 +63,7 @@ export interface LearningProvenanceV1 {
|
|
|
56
63
|
writeOrigin: {
|
|
57
64
|
sessionId?: string;
|
|
58
65
|
agentRole?: string;
|
|
66
|
+
authority?: WriteAuthorityOrigin;
|
|
59
67
|
producedAt: string;
|
|
60
68
|
};
|
|
61
69
|
}
|
|
@@ -72,6 +80,7 @@ export interface LearningProvenanceInput {
|
|
|
72
80
|
export interface LearningWriteOriginInput {
|
|
73
81
|
sessionId?: string;
|
|
74
82
|
agentRole?: string;
|
|
83
|
+
authority?: WriteAuthorityOrigin;
|
|
75
84
|
producedAt?: string;
|
|
76
85
|
}
|
|
77
86
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The event catalog (issue #2029).
|
|
3
3
|
*
|
|
4
|
-
* Exactly
|
|
4
|
+
* Exactly 50 entries, matching the `TelemetryEvent` union at
|
|
5
5
|
* `src/telemetry.ts:15-131`. Thirty-eight predate the #2029 contract; the 39th is
|
|
6
6
|
* `agent_conflict_detected` (previously emitted through a force-cast past the
|
|
7
7
|
* type system), the 40th is `close_archive_result` (issue #2030 — the
|
|
@@ -16,9 +16,11 @@
|
|
|
16
16
|
* `skill_usage_health` storage audit for the issue-#2038
|
|
17
17
|
* `.swarm/skill-usage.jsonl` store and its authoritative pending sidecar,
|
|
18
18
|
* the 48th is the bounded `core_events_health` storage audit for the
|
|
19
|
-
* issue-#2039 `.swarm/events.jsonl` store,
|
|
19
|
+
* issue-#2039 `.swarm/events.jsonl` store, the 49th is the bounded
|
|
20
20
|
* `shell_audit_health` storage audit for the issue-#2040
|
|
21
|
-
* `.swarm/session/shell-audit.jsonl` security-audit store
|
|
21
|
+
* `.swarm/session/shell-audit.jsonl` security-audit store, and the 50th is
|
|
22
|
+
* the bounded `trajectory_health` storage audit for the issue-#2041
|
|
23
|
+
* `.swarm/trajectories/` PRM session store. These late additions are instances
|
|
22
24
|
* of the defect class this contract exists to close: an event kind entering
|
|
23
25
|
* the stream with no registration.
|
|
24
26
|
*
|
|
@@ -73,7 +75,7 @@ export interface CatalogEntry {
|
|
|
73
75
|
/**
|
|
74
76
|
* Whether an event of this kind must carry `trace.parentSpanId`.
|
|
75
77
|
*
|
|
76
|
-
* `false` for all
|
|
78
|
+
* `false` for all 50 entries today, and that is a truthful statement about
|
|
77
79
|
* the current system rather than a placeholder: no producer supplies a
|
|
78
80
|
* parent span, so `createObservation` never sets one. Setting this to `true`
|
|
79
81
|
* for a kind whose producer cannot supply a parent would make every
|
package/dist/prm/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ import { formatCourseCorrectionForInjection, generateCourseCorrection } from './
|
|
|
26
26
|
import { EscalationTracker } from './escalation';
|
|
27
27
|
import { detectPatterns } from './pattern-detector';
|
|
28
28
|
import { recordReplayEntry, startReplayRecording } from './replay';
|
|
29
|
-
import {
|
|
29
|
+
import { clearTrajectoryCache, getInMemoryTrajectory, readTrajectoryWithCoverage, scheduleTrajectoryCleanup } from './trajectory-store';
|
|
30
30
|
import type { PrmConfig } from './types';
|
|
31
31
|
/**
|
|
32
32
|
* Test-only dependency-injection seam — see `gitignore-warning.ts:_internals`.
|
|
@@ -38,12 +38,12 @@ import type { PrmConfig } from './types';
|
|
|
38
38
|
*/
|
|
39
39
|
export declare const _internals: {
|
|
40
40
|
getAgentSession: typeof getAgentSession;
|
|
41
|
-
|
|
41
|
+
readTrajectoryWithCoverage: typeof readTrajectoryWithCoverage;
|
|
42
42
|
getInMemoryTrajectory: typeof getInMemoryTrajectory;
|
|
43
43
|
detectPatterns: typeof detectPatterns;
|
|
44
44
|
generateCourseCorrection: typeof generateCourseCorrection;
|
|
45
45
|
formatCourseCorrectionForInjection: typeof formatCourseCorrectionForInjection;
|
|
46
|
-
|
|
46
|
+
scheduleTrajectoryCleanup: typeof scheduleTrajectoryCleanup;
|
|
47
47
|
clearTrajectoryCache: typeof clearTrajectoryCache;
|
|
48
48
|
recordReplayEntry: typeof recordReplayEntry;
|
|
49
49
|
startReplayRecording: typeof startReplayRecording;
|
package/dist/prm/replay.d.ts
CHANGED
|
@@ -60,8 +60,25 @@ declare function sanitizeFilename(input: string): string;
|
|
|
60
60
|
*/
|
|
61
61
|
export declare function startReplayRecording(sessionID: string, directory: string): Promise<string | null>;
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* Hard budgets for replay artifacts (issue #2041 Required 1 — the PRM budget
|
|
64
|
+
* set covers replays as well as trajectories). Replays are write-only
|
|
65
|
+
* best-effort diagnostics: at the cap, further entries for that artifact are
|
|
66
|
+
* skipped with a one-time warning rather than rotated (rotation would create
|
|
67
|
+
* unbounded sibling files, which is exactly what this cap exists to prevent).
|
|
68
|
+
* The 7-day age sweep + per-directory count cap in trajectory-store's
|
|
69
|
+
* `cleanupOldTrajectoryFiles` bound the directory as a whole.
|
|
70
|
+
*/
|
|
71
|
+
export declare const REPLAY_LIMITS: {
|
|
72
|
+
/** Per-artifact byte ceiling. */
|
|
73
|
+
readonly maxBytes: number;
|
|
74
|
+
/** Stat cadence per artifact (bytes are tracked in memory between stats). */
|
|
75
|
+
readonly checkIntervalEntries: 16;
|
|
76
|
+
/** Bound on tracked artifacts (Invariant 8). */
|
|
77
|
+
readonly maxTrackedArtifacts: 256;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Appends a ReplayEntry to the replay artifact file, enforcing the per-artifact
|
|
81
|
+
* byte cap. Non-blocking: errors are caught and logged, never thrown.
|
|
65
82
|
*
|
|
66
83
|
* @param artifactPath - Path to the replay artifact file
|
|
67
84
|
* @param sessionID - Session identifier
|
|
@@ -72,5 +89,15 @@ export declare const _test_exports: {
|
|
|
72
89
|
readonly isPathSafe: typeof isPathSafe;
|
|
73
90
|
readonly isWithinReplaysDir: typeof isWithinReplaysDir;
|
|
74
91
|
readonly sanitizeFilename: typeof sanitizeFilename;
|
|
92
|
+
readonly REPLAY_LIMITS: {
|
|
93
|
+
/** Per-artifact byte ceiling. */
|
|
94
|
+
readonly maxBytes: number;
|
|
95
|
+
/** Stat cadence per artifact (bytes are tracked in memory between stats). */
|
|
96
|
+
readonly checkIntervalEntries: 16;
|
|
97
|
+
/** Bound on tracked artifacts (Invariant 8). */
|
|
98
|
+
readonly maxTrackedArtifacts: 256;
|
|
99
|
+
};
|
|
100
|
+
/** Test isolation: drop per-artifact byte-cap bookkeeping. */
|
|
101
|
+
readonly resetReplayByteTracking: () => void;
|
|
75
102
|
};
|
|
76
103
|
export {};
|
|
@@ -1,40 +1,215 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TRAJECTORY STORE (Session-Level)
|
|
2
|
+
* TRAJECTORY STORE (Session-Level) — bounded (issue #2041)
|
|
3
3
|
*
|
|
4
4
|
* Per-session trajectory storage for PRM pattern detection.
|
|
5
|
-
* Writes to .swarm/trajectories/{sessionId}.jsonl
|
|
5
|
+
* Writes to .swarm/trajectories/{sessionId}.jsonl (+ a small
|
|
6
|
+
* {sessionId}.jsonl.meta.json checkpoint and a transient {sessionId}.jsonl.lock).
|
|
7
|
+
*
|
|
8
|
+
* Bounded session-trajectory contract (mirrors the #2040 shell-audit store):
|
|
9
|
+
* - ONE knob, `maxLines`, governs BOTH the in-memory cache trim and the disk
|
|
10
|
+
* compaction: over budget, the newest floor(maxLines/2) entries are retained
|
|
11
|
+
* (the cache has always used exactly this rule — the disk now matches it).
|
|
12
|
+
* - The disk byte ceiling sessionMaxBytesFor(maxLines) is SOVEREIGN and is
|
|
13
|
+
* enforced at APPEND time (the stat needed for torn-tail re-framing doubles
|
|
14
|
+
* as the size probe): over ceiling, compaction runs before the append.
|
|
15
|
+
* - A line-count check runs every `checkIntervalAppends` appends (the only
|
|
16
|
+
* part that needs a read; it is tail-bounded, never a whole-file read).
|
|
17
|
+
* - Readers (`readTrajectory`, `getCurrentStep`) read a bounded tail window and
|
|
18
|
+
* disclose coverage; `getCurrentStep` also consults the atomically persisted
|
|
19
|
+
* checkpoint so a restart never scans history to continue step numbering.
|
|
20
|
+
* - Crash semantics: compaction publishes via tmp+rename (a partial rewrite is
|
|
21
|
+
* never visible); the checkpoint is written after the data rewrite under the
|
|
22
|
+
* same lock, and merges `max(previous, observed)` so it can only ratchet UP.
|
|
23
|
+
* Compaction keeps the NEWEST entries, so the global max step always survives
|
|
24
|
+
* on disk — except when every retained line is corrupt, in which case the
|
|
25
|
+
* checkpoint alone preserves step continuity (that is why it exists).
|
|
26
|
+
* - Two writers: an in-process per-key promise chain (same-process appends
|
|
27
|
+
* never burn the cross-process retry budget) plus a per-file `.lock`
|
|
28
|
+
* (wx existence create — the PID inside is diagnostic only, never
|
|
29
|
+
* liveness-checked — stale-break, bounded retry). Lock exhaustion skips the
|
|
30
|
+
* append with a warning — telemetry loss is preferred over file corruption
|
|
31
|
+
* in this best-effort store — and is counted into `trajectory_health`.
|
|
6
32
|
*
|
|
7
33
|
* Coexists with task-level trajectory-logger.ts which writes to
|
|
8
|
-
* .swarm/evidence/{taskId}/trajectory.jsonl for audit/evidence
|
|
34
|
+
* .swarm/evidence/{taskId}/trajectory.jsonl for audit/evidence (bounded by its
|
|
35
|
+
* own write-side truncation; untouched by this contract).
|
|
9
36
|
*/
|
|
37
|
+
import { telemetry } from '../telemetry';
|
|
10
38
|
import type { TrajectoryEntry } from './types';
|
|
39
|
+
/**
|
|
40
|
+
* Hard budgets for the bounded session-trajectory contract (issue #2041).
|
|
41
|
+
* Exported for tests and for the retention registry's documented contract.
|
|
42
|
+
*/
|
|
43
|
+
export declare const TRAJECTORY_LIMITS: {
|
|
44
|
+
/** Line-count compaction check cadence (append-path, amortized). */
|
|
45
|
+
readonly checkIntervalAppends: 25;
|
|
46
|
+
/** Tail-bounded read window for readTrajectoryWithCoverage. */
|
|
47
|
+
readonly readMaxBytes: number;
|
|
48
|
+
/** Tail-bounded read window for getCurrentStep (newest lines carry max step). */
|
|
49
|
+
readonly stepReadMaxBytes: number;
|
|
50
|
+
/** Tail-bounded input window for compaction (legacy files may be huge). */
|
|
51
|
+
readonly compactMaxBytes: number;
|
|
52
|
+
/** A JSONL line longer than this is shed as oversize (append skips it). */
|
|
53
|
+
readonly maxLineBytes: number;
|
|
54
|
+
/** Estimated bytes per entry used to derive the per-session byte ceiling. */
|
|
55
|
+
readonly estimatedLineBytes: 512;
|
|
56
|
+
/** Floor for the derived per-session byte ceiling. */
|
|
57
|
+
readonly minSessionMaxBytes: number;
|
|
58
|
+
/** Per-file cross-process lock: bounded retries, then skip + warn. */
|
|
59
|
+
readonly lockRetries: 20;
|
|
60
|
+
readonly lockRetryDelayMs: 5;
|
|
61
|
+
/** A lock older than this is considered crashed and broken. */
|
|
62
|
+
readonly lockStaleMs: number;
|
|
63
|
+
/** Per-directory session-file count cap (age-sweep backstop). */
|
|
64
|
+
readonly maxFilesPerDir: 200;
|
|
65
|
+
/** Unlinks per cleanup invocation (converges across runs). */
|
|
66
|
+
readonly maxDeletionsPerRun: 256;
|
|
67
|
+
/** Default age sweep horizon for trajectories/ and replays/. */
|
|
68
|
+
readonly defaultMaxAgeDays: 7;
|
|
69
|
+
/** Debounce for the lazily scheduled cleanup pass. */
|
|
70
|
+
readonly cleanupDebounceMs: number;
|
|
71
|
+
/** Cooldown for append_skip health events (lock-exhaust observability). */
|
|
72
|
+
readonly appendSkipEventCooldownMs: 60000;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Sovereign per-session disk byte ceiling, derived from the same `maxLines`
|
|
76
|
+
* knob that governs cache trimming and line-count compaction.
|
|
77
|
+
*/
|
|
78
|
+
export declare function sessionMaxBytesFor(maxLines: number): number;
|
|
79
|
+
/** Test/DI seam — see `gitignore-warning.ts:_internals` for the convention. */
|
|
80
|
+
export declare const _internals: {
|
|
81
|
+
telemetry: typeof telemetry;
|
|
82
|
+
};
|
|
11
83
|
/**
|
|
12
84
|
* Returns cached trajectory entries for a session (empty array if not cached).
|
|
85
|
+
*
|
|
86
|
+
* @param sessionId - Session identifier
|
|
87
|
+
* @param directory - Workspace root that owns the session's trajectory file
|
|
13
88
|
*/
|
|
14
|
-
export declare function getInMemoryTrajectory(sessionId: string): TrajectoryEntry[];
|
|
89
|
+
export declare function getInMemoryTrajectory(sessionId: string, directory: string): TrajectoryEntry[];
|
|
15
90
|
/**
|
|
16
91
|
* Clears trajectory cache (for test isolation or session cleanup).
|
|
92
|
+
*
|
|
93
|
+
* With a sessionId but no directory, every root's entry for that session is
|
|
94
|
+
* cleared (suffix scan over the bounded map) — reset paths that legitimately
|
|
95
|
+
* lack a directory still release the cached window.
|
|
17
96
|
*/
|
|
18
97
|
export declare function clearTrajectoryCache(sessionId?: string): void;
|
|
98
|
+
interface TrajectoryCheckpoint {
|
|
99
|
+
version: 1;
|
|
100
|
+
highestStep: number;
|
|
101
|
+
droppedEntries: number;
|
|
102
|
+
/**
|
|
103
|
+
* Cumulative bytes discarded whole — chiefly the pre-window portion of an
|
|
104
|
+
* oversized file that a tail-bounded compaction rewrote away (shed
|
|
105
|
+
* windowed entries also contribute their bytes here, alongside their
|
|
106
|
+
* counts in droppedEntries: the two metrics are independent dimensions
|
|
107
|
+
* of the same loss). Without this, a compaction whose window kept every
|
|
108
|
+
* windowed entry (droppedEntries delta 0) would silently erase megabytes
|
|
109
|
+
* beyond the window while coverage still reported `complete`. Optional
|
|
110
|
+
* on READ for checkpoints written before this field existed.
|
|
111
|
+
*/
|
|
112
|
+
droppedBytes?: number;
|
|
113
|
+
compactedAt: string;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Reads a session's persisted step checkpoint (null when absent/corrupt).
|
|
117
|
+
*
|
|
118
|
+
* Production consumers: `getCurrentStep` (restart continuity) and the consensus
|
|
119
|
+
* corpus's default PRM coverage signal (dropped-by-compaction disclosure).
|
|
120
|
+
*/
|
|
121
|
+
export declare function readTrajectoryCheckpoint(sessionId: string, directory: string): Promise<TrajectoryCheckpoint | null>;
|
|
122
|
+
/**
|
|
123
|
+
* One bounded stat of a session's trajectory file (null when absent).
|
|
124
|
+
*
|
|
125
|
+
* Production consumer: the consensus corpus's default PRM coverage verdict —
|
|
126
|
+
* a file larger than the read window means the live bounded read was
|
|
127
|
+
* window-truncated, exactly matching `readTrajectoryWithCoverage`'s coverage
|
|
128
|
+
* semantics so the two paths cannot diverge (implementation-review round 1).
|
|
129
|
+
*/
|
|
130
|
+
export declare function trajectoryFileBytes(sessionId: string, directory: string): Promise<number | null>;
|
|
19
131
|
/**
|
|
20
|
-
* Appends a single TrajectoryEntry to the session's trajectory file
|
|
132
|
+
* Appends a single TrajectoryEntry to the session's trajectory file, enforcing
|
|
133
|
+
* the bounded session-trajectory contract on disk as well as in memory.
|
|
21
134
|
*
|
|
22
135
|
* @param sessionId - Session identifier
|
|
23
136
|
* @param entry - Trajectory entry to append
|
|
24
137
|
* @param directory - Base directory (workspace root)
|
|
25
|
-
* @param maxLines -
|
|
138
|
+
* @param maxLines - Line budget for BOTH the in-memory cache trim and disk
|
|
139
|
+
* compaction (compaction retains the newest floor(maxLines/2) entries; the
|
|
140
|
+
* derived byte ceiling sessionMaxBytesFor(maxLines) is sovereign)
|
|
26
141
|
*/
|
|
27
142
|
export declare function appendTrajectoryEntry(sessionId: string, entry: TrajectoryEntry, directory: string, maxLines?: number): Promise<void>;
|
|
143
|
+
export type TrajectoryCoverage = 'complete' | 'truncated' | 'empty';
|
|
144
|
+
export interface TrajectoryReadWithCoverage {
|
|
145
|
+
entries: TrajectoryEntry[];
|
|
146
|
+
coverage: TrajectoryCoverage;
|
|
147
|
+
/** Entries removed by prior compactions (persisted checkpoint total). */
|
|
148
|
+
droppedByCompaction: number;
|
|
149
|
+
skippedMalformed: number;
|
|
150
|
+
}
|
|
28
151
|
/**
|
|
29
|
-
*
|
|
152
|
+
* Tail-bounded read of a session's trajectory with explicit coverage
|
|
153
|
+
* disclosure (issue #2041 Required 3/4). Reads at most
|
|
154
|
+
* TRAJECTORY_LIMITS.readMaxBytes regardless of file size; the returned entries
|
|
155
|
+
* are the newest window in file order.
|
|
156
|
+
*
|
|
157
|
+
* `maxLines` is the SAME knob the append path uses: a cold read populates the
|
|
158
|
+
* in-memory cache trimmed to the configured budget, so a legacy pre-fix file
|
|
159
|
+
* cannot inflate the cache PRM pattern detection reads (review round 1).
|
|
160
|
+
*/
|
|
161
|
+
export declare function readTrajectoryWithCoverage(sessionId: string, directory: string, maxLines?: number): Promise<TrajectoryReadWithCoverage>;
|
|
162
|
+
/**
|
|
163
|
+
* Reads the newest bounded window of TrajectoryEntry records from a session's
|
|
164
|
+
* trajectory file.
|
|
30
165
|
*
|
|
31
166
|
* @param sessionId - Session identifier
|
|
32
167
|
* @param directory - Base directory (workspace root)
|
|
168
|
+
* @param maxLines - Optional cache-trim budget (same knob as the append path)
|
|
33
169
|
* @returns Array of trajectory entries (empty array if file doesn't exist)
|
|
34
170
|
*/
|
|
35
|
-
export declare function readTrajectory(sessionId: string, directory: string): Promise<TrajectoryEntry[]>;
|
|
171
|
+
export declare function readTrajectory(sessionId: string, directory: string, maxLines?: number): Promise<TrajectoryEntry[]>;
|
|
36
172
|
export declare const _test_exports: {
|
|
37
173
|
readonly MAX_TRACKED_TRAJECTORY_SESSIONS: 500;
|
|
174
|
+
readonly TRAJECTORY_LIMITS: {
|
|
175
|
+
/** Line-count compaction check cadence (append-path, amortized). */
|
|
176
|
+
readonly checkIntervalAppends: 25;
|
|
177
|
+
/** Tail-bounded read window for readTrajectoryWithCoverage. */
|
|
178
|
+
readonly readMaxBytes: number;
|
|
179
|
+
/** Tail-bounded read window for getCurrentStep (newest lines carry max step). */
|
|
180
|
+
readonly stepReadMaxBytes: number;
|
|
181
|
+
/** Tail-bounded input window for compaction (legacy files may be huge). */
|
|
182
|
+
readonly compactMaxBytes: number;
|
|
183
|
+
/** A JSONL line longer than this is shed as oversize (append skips it). */
|
|
184
|
+
readonly maxLineBytes: number;
|
|
185
|
+
/** Estimated bytes per entry used to derive the per-session byte ceiling. */
|
|
186
|
+
readonly estimatedLineBytes: 512;
|
|
187
|
+
/** Floor for the derived per-session byte ceiling. */
|
|
188
|
+
readonly minSessionMaxBytes: number;
|
|
189
|
+
/** Per-file cross-process lock: bounded retries, then skip + warn. */
|
|
190
|
+
readonly lockRetries: 20;
|
|
191
|
+
readonly lockRetryDelayMs: 5;
|
|
192
|
+
/** A lock older than this is considered crashed and broken. */
|
|
193
|
+
readonly lockStaleMs: number;
|
|
194
|
+
/** Per-directory session-file count cap (age-sweep backstop). */
|
|
195
|
+
readonly maxFilesPerDir: 200;
|
|
196
|
+
/** Unlinks per cleanup invocation (converges across runs). */
|
|
197
|
+
readonly maxDeletionsPerRun: 256;
|
|
198
|
+
/** Default age sweep horizon for trajectories/ and replays/. */
|
|
199
|
+
readonly defaultMaxAgeDays: 7;
|
|
200
|
+
/** Debounce for the lazily scheduled cleanup pass. */
|
|
201
|
+
readonly cleanupDebounceMs: number;
|
|
202
|
+
/** Cooldown for append_skip health events (lock-exhaust observability). */
|
|
203
|
+
readonly appendSkipEventCooldownMs: 60000;
|
|
204
|
+
};
|
|
205
|
+
readonly sessionMaxBytesFor: typeof sessionMaxBytesFor;
|
|
206
|
+
readonly getCacheSize: () => number;
|
|
207
|
+
readonly getChainSize: () => number;
|
|
208
|
+
/** Test isolation: the cleanup debounce is module-global state. */
|
|
209
|
+
readonly resetCleanupDebounce: () => void;
|
|
210
|
+
/** Test isolation: lock-skip counters are module-global state. */
|
|
211
|
+
readonly resetLockSkipCounters: () => void;
|
|
212
|
+
readonly appendFileIsTorn: (filePath: string) => Promise<boolean>;
|
|
38
213
|
};
|
|
39
214
|
/**
|
|
40
215
|
* Alias for readTrajectory - retrieves trajectory entries for a session.
|
|
@@ -44,17 +219,16 @@ export declare const _test_exports: {
|
|
|
44
219
|
* @returns Array of trajectory entries
|
|
45
220
|
*/
|
|
46
221
|
export declare function getTrajectoryForSession(sessionId: string, directory: string): Promise<TrajectoryEntry[]>;
|
|
47
|
-
/**
|
|
48
|
-
* Truncates the trajectory file to the newest half if lines exceed maxLines.
|
|
49
|
-
*
|
|
50
|
-
* @param sessionId - Session identifier
|
|
51
|
-
* @param directory - Base directory (workspace root)
|
|
52
|
-
* @param maxLines - Maximum number of lines to retain
|
|
53
|
-
*/
|
|
54
|
-
export declare function truncateTrajectoryIfNeeded(sessionId: string, directory: string, maxLines: number): Promise<void>;
|
|
55
222
|
/**
|
|
56
223
|
* Returns the highest step number in the session's trajectory.
|
|
57
|
-
* Used to determine the next step number when appending
|
|
224
|
+
* Used to determine the next step number when appending — the production
|
|
225
|
+
* restart-seeding path in trajectory-logger.ts calls this before the first
|
|
226
|
+
* mint of a session so step numbers stay monotonic across process restarts.
|
|
227
|
+
*
|
|
228
|
+
* Bounded: reads at most TRAJECTORY_LIMITS.stepReadMaxBytes of the file
|
|
229
|
+
* (the newest lines carry the max step) and merges the atomically persisted
|
|
230
|
+
* checkpoint, so a restart never scans unbounded history — and the high-water
|
|
231
|
+
* mark survives even a fully-corrupt data file.
|
|
58
232
|
*
|
|
59
233
|
* @param sessionId - Session identifier
|
|
60
234
|
* @param directory - Base directory (workspace root)
|
|
@@ -62,8 +236,24 @@ export declare function truncateTrajectoryIfNeeded(sessionId: string, directory:
|
|
|
62
236
|
*/
|
|
63
237
|
export declare function getCurrentStep(sessionId: string, directory: string): Promise<number>;
|
|
64
238
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
239
|
+
* Debounced, fire-and-forget cleanup scheduling used by the PRM hook's
|
|
240
|
+
* once-per-session trigger. The plugin's post-resolution init pass calls
|
|
241
|
+
* `cleanupOldTrajectoryFiles` directly (the debounce must not suppress the
|
|
242
|
+
* startup sweep).
|
|
243
|
+
*/
|
|
244
|
+
export declare function scheduleTrajectoryCleanup(directory: string): void;
|
|
245
|
+
/**
|
|
246
|
+
* Deletes aged trajectory and replay files, then enforces a per-directory
|
|
247
|
+
* session-file count cap (oldest-first) so a hostile or skewed mtime cannot
|
|
248
|
+
* grow `.swarm/trajectories/` or `.swarm/replays/` without bound. A session's
|
|
249
|
+
* `.meta.json` checkpoint is removed with its `.jsonl`; orphan checkpoints and
|
|
250
|
+
* stale atomic-write `*.tmp` leftovers age out on their own. Bounded to
|
|
251
|
+
* maxDeletionsPerRun unlinks per invocation (converges across runs); every
|
|
252
|
+
* failure is swallowed. Never touches `.swarm/evidence/` (task evidence is a
|
|
253
|
+
* different directory tree governed by its own contract).
|
|
254
|
+
*
|
|
255
|
+
* Replays and trajectories are independent artifacts sharing this sweep: no
|
|
256
|
+
* cross-linkage is enforced or implied.
|
|
68
257
|
*/
|
|
69
258
|
export declare function cleanupOldTrajectoryFiles(directory: string, maxAgeDays?: number): Promise<void>;
|
|
259
|
+
export {};
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* Each probe is bounded to 2 seconds via AbortController to satisfy
|
|
10
10
|
* Invariant 1 (plugin init is fast, bounded, fail-open).
|
|
11
11
|
*/
|
|
12
|
+
import { spawnSync } from 'node:child_process';
|
|
13
|
+
import * as fs from 'node:fs';
|
|
12
14
|
/** Possible sandbox status values. */
|
|
13
15
|
export type SandboxStatus = 'enabled' | 'disabled' | 'unsupported';
|
|
14
16
|
/**
|
|
@@ -20,6 +22,7 @@ export type SandboxStatus = 'enabled' | 'disabled' | 'unsupported';
|
|
|
20
22
|
* (issue #1778 H2).
|
|
21
23
|
*/
|
|
22
24
|
export type SandboxStrength = 'strong' | 'advisory';
|
|
25
|
+
export type SandboxDimensionStrength = 'real' | 'weak' | 'none';
|
|
23
26
|
/** Result of a sandbox capability probe. */
|
|
24
27
|
export interface SandboxCapability {
|
|
25
28
|
/** Whether the sandbox mechanism is available. */
|
|
@@ -36,6 +39,37 @@ export interface SandboxCapability {
|
|
|
36
39
|
/** Error message from the probe, if any. */
|
|
37
40
|
error?: string;
|
|
38
41
|
}
|
|
42
|
+
export interface SandboxCapabilityV1 extends SandboxCapability {
|
|
43
|
+
v: 1;
|
|
44
|
+
filesystem: SandboxDimensionStrength;
|
|
45
|
+
network: SandboxDimensionStrength;
|
|
46
|
+
process: SandboxDimensionStrength;
|
|
47
|
+
effective: SandboxDimensionStrength;
|
|
48
|
+
reasons: string[];
|
|
49
|
+
identity: string;
|
|
50
|
+
}
|
|
51
|
+
export interface SandboxRequirements {
|
|
52
|
+
mode?: 'advisory' | 'required';
|
|
53
|
+
require_filesystem?: boolean;
|
|
54
|
+
require_network?: boolean;
|
|
55
|
+
require_process?: boolean;
|
|
56
|
+
network_mode?: 'off' | 'on';
|
|
57
|
+
network_allowlist?: readonly string[];
|
|
58
|
+
writable_roots?: readonly string[];
|
|
59
|
+
}
|
|
60
|
+
export declare function assessSandboxRequirements(capability: SandboxCapabilityV1, requirements: SandboxRequirements | undefined): {
|
|
61
|
+
satisfied: boolean;
|
|
62
|
+
missing: string[];
|
|
63
|
+
};
|
|
64
|
+
interface BehavioralEvidence {
|
|
65
|
+
filesystem: SandboxDimensionStrength;
|
|
66
|
+
network: SandboxDimensionStrength;
|
|
67
|
+
process: SandboxDimensionStrength;
|
|
68
|
+
reasons: string[];
|
|
69
|
+
}
|
|
70
|
+
declare function currentProbeSourceIdentity(platform: 'linux' | 'darwin' | 'win32'): string;
|
|
71
|
+
declare function resolveWindowsCommandProcessorBinary(): string;
|
|
72
|
+
declare function detectBehavioralEvidence(capability: SandboxCapability): BehavioralEvidence;
|
|
39
73
|
/** Reset the session-lifetime capability cache. Test-only. */
|
|
40
74
|
export declare function _resetCapabilityCache(): void;
|
|
41
75
|
/**
|
|
@@ -56,6 +90,11 @@ declare function withProbeTimeout(cmd: string, args: string[], ms: number): Prom
|
|
|
56
90
|
*/
|
|
57
91
|
export declare const _internals: {
|
|
58
92
|
withProbeTimeout: typeof withProbeTimeout;
|
|
93
|
+
spawnSync: typeof spawnSync;
|
|
94
|
+
detectBehavioralEvidence: typeof detectBehavioralEvidence;
|
|
95
|
+
resolveWindowsCommandProcessorBinary: typeof resolveWindowsCommandProcessorBinary;
|
|
96
|
+
currentProbeSourceIdentity: typeof currentProbeSourceIdentity;
|
|
97
|
+
removeProbeTempRoot: typeof fs.rmSync;
|
|
59
98
|
};
|
|
60
99
|
/**
|
|
61
100
|
* Detects the availability of OS-native sandbox mechanisms.
|
|
@@ -86,6 +125,6 @@ export declare class SandboxCapabilityProbe {
|
|
|
86
125
|
*
|
|
87
126
|
* @returns A promise that resolves to the sandbox capability result.
|
|
88
127
|
*/
|
|
89
|
-
detect(): Promise<
|
|
128
|
+
detect(): Promise<SandboxCapabilityV1>;
|
|
90
129
|
}
|
|
91
130
|
export {};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Provides a unified interface for sandboxed shell command execution across
|
|
5
5
|
* Linux (Bubblewrap), macOS (sandbox-exec), and Windows (restricted token/Low Integrity).
|
|
6
6
|
*/
|
|
7
|
+
import { type SandboxCapabilityV1, type SandboxRequirements } from './capability-probe';
|
|
7
8
|
/**
|
|
8
9
|
* Error thrown when sandbox operations fail.
|
|
9
10
|
*/
|
|
@@ -11,6 +12,7 @@ export declare class SandboxError extends Error {
|
|
|
11
12
|
readonly code: string;
|
|
12
13
|
constructor(message: string, code: string);
|
|
13
14
|
}
|
|
15
|
+
export declare function normalizeSandboxMechanism(mechanism: string): string;
|
|
14
16
|
/**
|
|
15
17
|
* Validate that a string is a valid POSIX environment variable name.
|
|
16
18
|
* POSIX env var names: [a-zA-Z_][a-zA-Z0-9_]*
|
|
@@ -43,13 +45,33 @@ export interface SandboxExecutor {
|
|
|
43
45
|
* @returns The wrapped command string with sandbox prefix
|
|
44
46
|
* @throws SandboxError if sandbox cannot wrap the command
|
|
45
47
|
*/
|
|
46
|
-
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null
|
|
48
|
+
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null>, policy?: SandboxPolicyOptions): string;
|
|
47
49
|
/**
|
|
48
50
|
* Get the environment variable overrides for this sandbox.
|
|
49
51
|
* Returns a record of env vars to set/unset.
|
|
50
52
|
*/
|
|
51
53
|
getEnvOverrides(): Record<string, string | null>;
|
|
52
54
|
}
|
|
55
|
+
export interface SandboxPolicyOptions {
|
|
56
|
+
network_mode?: 'off' | 'on';
|
|
57
|
+
network_allowlist?: readonly string[];
|
|
58
|
+
writable_roots?: readonly string[];
|
|
59
|
+
}
|
|
60
|
+
declare function detectSandboxCapability(): Promise<SandboxCapabilityV1>;
|
|
61
|
+
export declare const _internals: {
|
|
62
|
+
detectSandboxCapability: typeof detectSandboxCapability;
|
|
63
|
+
};
|
|
64
|
+
export interface SandboxEnforcementAssessment {
|
|
65
|
+
capability: SandboxCapabilityV1;
|
|
66
|
+
requirements: Required<SandboxRequirements>;
|
|
67
|
+
policy: Required<SandboxPolicyOptions>;
|
|
68
|
+
satisfied: boolean;
|
|
69
|
+
missing: string[];
|
|
70
|
+
supported: boolean;
|
|
71
|
+
unsupported: string[];
|
|
72
|
+
cacheKey: string;
|
|
73
|
+
}
|
|
74
|
+
export declare function assessSandboxEnforcement(requirements: SandboxRequirements | undefined): Promise<SandboxEnforcementAssessment>;
|
|
53
75
|
/**
|
|
54
76
|
* Get the platform-appropriate sandbox executor.
|
|
55
77
|
*
|
|
@@ -80,3 +102,6 @@ export declare function _getMacOSSandboxPolicyForTest(): boolean;
|
|
|
80
102
|
* @internal
|
|
81
103
|
*/
|
|
82
104
|
export declare function _resetExecutorCache(): void;
|
|
105
|
+
/** @internal test seam */
|
|
106
|
+
export declare function _resetSandboxAssessmentCache(): void;
|
|
107
|
+
export {};
|
|
@@ -75,7 +75,9 @@ export declare class BubblewrapSandboxExecutor implements SandboxExecutor {
|
|
|
75
75
|
* @returns A bwrap-wrapped command string ready for shell execution,
|
|
76
76
|
* or the raw command string when the sandbox is unavailable (passthrough mode)
|
|
77
77
|
*/
|
|
78
|
-
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null
|
|
78
|
+
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null>, policy?: {
|
|
79
|
+
network_mode?: 'off' | 'on';
|
|
80
|
+
}): string;
|
|
79
81
|
/**
|
|
80
82
|
* Return environment variable overrides required for the bubblewrap sandbox.
|
|
81
83
|
*
|
|
@@ -104,7 +104,9 @@ export declare class MacOSSandboxExecutor implements SandboxExecutor {
|
|
|
104
104
|
* @returns A sandbox-exec wrapped command string ready for shell execution,
|
|
105
105
|
* or the raw command string when the sandbox is unavailable (passthrough mode)
|
|
106
106
|
*/
|
|
107
|
-
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null
|
|
107
|
+
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null>, _policy?: {
|
|
108
|
+
network_mode?: 'off' | 'on';
|
|
109
|
+
}): string;
|
|
108
110
|
/**
|
|
109
111
|
* Return environment variable overrides required for the macOS sandbox.
|
|
110
112
|
*
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface SandboxWrapOutcome {
|
|
2
|
+
sessionID: string;
|
|
3
|
+
callID: string;
|
|
4
|
+
originalCommandHash: number;
|
|
5
|
+
finalCommandHash: number;
|
|
6
|
+
wrapped: boolean;
|
|
7
|
+
capabilityIdentity: string;
|
|
8
|
+
assessmentCacheKey: string;
|
|
9
|
+
reason: string;
|
|
10
|
+
originalCommand: string;
|
|
11
|
+
executorMechanism: string;
|
|
12
|
+
capabilityMechanism: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function recordSandboxWrapOutcome(outcome: SandboxWrapOutcome): void;
|
|
15
|
+
export declare function readSandboxWrapOutcome(sessionID: string, callID: string): SandboxWrapOutcome | null;
|
|
16
|
+
export declare function clearSandboxWrapOutcome(sessionID: string, callID: string): void;
|
|
17
|
+
export declare function getSandboxSkipSummary(sessionID?: string): {
|
|
18
|
+
count: number;
|
|
19
|
+
reasons: readonly string[];
|
|
20
|
+
};
|
|
21
|
+
/** @internal test seam */
|
|
22
|
+
export declare function _resetSandboxWrapOutcomeState(): void;
|
|
23
|
+
/** @internal test seam */
|
|
24
|
+
export declare function _sandboxWrapOutcomeStateSize(): number;
|
|
@@ -37,7 +37,11 @@ export declare class NativeWindowsSandboxExecutor implements SandboxExecutor {
|
|
|
37
37
|
*
|
|
38
38
|
* When the runner is unavailable, falls back to the PowerShell wrapper.
|
|
39
39
|
*/
|
|
40
|
-
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null
|
|
40
|
+
wrapCommand(command: string, scopePaths: string[], tempDir?: string, envOverrides?: Record<string, string | null>, policy?: {
|
|
41
|
+
network_mode?: 'off' | 'on';
|
|
42
|
+
network_allowlist?: readonly string[];
|
|
43
|
+
writable_roots?: readonly string[];
|
|
44
|
+
}): string;
|
|
41
45
|
private _wrapWithRunner;
|
|
42
46
|
getEnvOverrides(): Record<string, string | null>;
|
|
43
47
|
/**
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type CommandRiskCategory = 'catastrophic' | 'destructive' | 'unknown' | 'escalate' | 'safe';
|
|
2
|
+
export interface CommandSegmentClassificationV1 {
|
|
3
|
+
segment: string;
|
|
4
|
+
category: CommandRiskCategory;
|
|
5
|
+
reason: string;
|
|
6
|
+
ruleId?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CommandClassificationV1 {
|
|
9
|
+
v: 1;
|
|
10
|
+
originalDigest: string;
|
|
11
|
+
aggregate: CommandRiskCategory;
|
|
12
|
+
ambiguous: boolean;
|
|
13
|
+
segments: readonly CommandSegmentClassificationV1[];
|
|
14
|
+
}
|
|
15
|
+
export interface SharedClassifierGuardrailBlockV1 {
|
|
16
|
+
ruleId: string;
|
|
17
|
+
category: Extract<CommandRiskCategory, 'catastrophic' | 'destructive'>;
|
|
18
|
+
destructiveCategory: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function getSharedClassifierGuardrailBlock(classification: Readonly<CommandClassificationV1>): Readonly<SharedClassifierGuardrailBlockV1> | null;
|
|
22
|
+
export declare function classifyCommand(original: string): Readonly<CommandClassificationV1>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ProtectedManifestV1 {
|
|
2
|
+
v: 1;
|
|
3
|
+
root: string;
|
|
4
|
+
digest: string;
|
|
5
|
+
entries: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
/** Snapshot a protected regular-file tree; ambiguity and budget exhaustion fail closed. */
|
|
8
|
+
export declare function snapshotProtectedTree(root: string): Promise<ProtectedManifestV1>;
|
|
9
|
+
export declare function verifyProtectedTree(before: ProtectedManifestV1): Promise<void>;
|
|
10
|
+
/** Mandatory transaction wrapper for governed evaluators. Verification always runs. */
|
|
11
|
+
export declare function withProtectedInputIntegrity<T>(root: string, operation: () => Promise<T>): Promise<T>;
|
|
12
|
+
export interface ProtectedSetManifestV1 {
|
|
13
|
+
v: 1;
|
|
14
|
+
roots: readonly string[];
|
|
15
|
+
states: readonly (ProtectedManifestV1 | 'missing')[];
|
|
16
|
+
}
|
|
17
|
+
export declare function snapshotProtectedSet(roots: readonly string[]): Promise<ProtectedSetManifestV1>;
|
|
18
|
+
export declare function verifyProtectedSet(before: ProtectedSetManifestV1): Promise<void>;
|
|
19
|
+
export declare function withProtectedSetIntegrity<T>(roots: readonly string[], operation: () => Promise<T>): Promise<T>;
|