opencode-swarm 7.150.0 → 7.151.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.
Files changed (71) hide show
  1. package/dist/cli/{config-doctor-96qyv31a.js → config-doctor-08zmx89c.js} +2 -2
  2. package/dist/cli/{core-xx0x5tfv.js → core-w0gjhw5q.js} +1 -1
  3. package/dist/cli/{curation-policy-nck9g765.js → curation-policy-fmvccdrg.js} +6 -6
  4. package/dist/cli/{curator-llm-factory-b83jsg02.js → curator-llm-factory-jmx72zhc.js} +28 -28
  5. package/dist/cli/{curator-frrehxxe.js → curator-twqjxden.js} +28 -28
  6. package/dist/cli/{evidence-summary-service-dv4bt2bx.js → evidence-summary-service-py66zgn4.js} +12 -12
  7. package/dist/cli/{gate-evidence-dkvs7aez.js → gate-evidence-ynhyzwsw.js} +6 -6
  8. package/dist/cli/{guardrail-explain-1zbk21fq.js → guardrail-explain-j9h5r8gh.js} +29 -29
  9. package/dist/cli/{guardrail-log-d20jewtr.js → guardrail-log-7995v5q5.js} +5 -5
  10. package/dist/cli/{guardrail-reset-wb3ba243.js → guardrail-reset-seextj6h.js} +28 -28
  11. package/dist/cli/{hive-promoter-10zv1b45.js → hive-promoter-a6xtvynw.js} +28 -28
  12. package/dist/cli/{index-k2sm9677.js → index-0q2mjxp2.js} +1 -1
  13. package/dist/cli/{index-bhg6brtw.js → index-1z7kx41f.js} +745 -8
  14. package/dist/cli/index-2xfffkk0.js +149 -0
  15. package/dist/cli/{index-mef0trex.js → index-4y7n76bn.js} +2 -1
  16. package/dist/cli/{index-htqs4p52.js → index-5jwbepcr.js} +1 -1
  17. package/dist/cli/{index-1wmd5wn1.js → index-5sh0kqf5.js} +4 -4
  18. package/dist/cli/{index-exn0ztsv.js → index-6zkm4p7p.js} +1 -1
  19. package/dist/cli/{index-x3pt7d0b.js → index-7w2b1z4j.js} +2 -2
  20. package/dist/cli/{index-s0xz2520.js → index-9d9p7bv2.js} +3 -3
  21. package/dist/cli/{index-prxrmc3b.js → index-9wpr1p2g.js} +2 -2
  22. package/dist/cli/{index-t54jt9cs.js → index-a2phfdsv.js} +1 -1
  23. package/dist/cli/{index-an922xj4.js → index-akef15kb.js} +7 -7
  24. package/dist/cli/{index-xggpmtfx.js → index-aw492hpn.js} +57 -40
  25. package/dist/cli/{index-dtmgt2xn.js → index-dvycdkhj.js} +1 -0
  26. package/dist/cli/{index-4sdhbxgq.js → index-f73px21b.js} +1 -1
  27. package/dist/cli/{index-0tn1kxej.js → index-fbj6wvew.js} +7 -7
  28. package/dist/cli/{index-apwcvfjt.js → index-frp2hwdg.js} +2 -2
  29. package/dist/cli/{index-zyv56em5.js → index-gqss5zbr.js} +3 -3
  30. package/dist/cli/{index-8cn6545x.js → index-hw93dwd0.js} +30 -30
  31. package/dist/cli/{index-n99s022c.js → index-jjpppdvb.js} +1 -1
  32. package/dist/cli/{index-qqs44wcp.js → index-kzdv0g9e.js} +79 -66
  33. package/dist/cli/{index-mnhagjvn.js → index-n35866rr.js} +4 -4
  34. package/dist/cli/{index-ma1p1w05.js → index-npzmqk01.js} +6 -6
  35. package/dist/cli/{index-w9pb72vg.js → index-qmwed766.js} +2 -2
  36. package/dist/cli/{index-g75rbw3e.js → index-t9h95vjd.js} +5 -5
  37. package/dist/cli/{index-1rpjd5na.js → index-twhhwe74.js} +1 -1
  38. package/dist/cli/{index-m8dn0qnm.js → index-txbd25bc.js} +1 -1
  39. package/dist/cli/{index-jb9tb1sd.js → index-v3gshkpz.js} +1 -1
  40. package/dist/cli/{index-r5djc1cc.js → index-xtyxnxf4.js} +5 -5
  41. package/dist/cli/{index-reknv4f9.js → index-xysb3ed7.js} +2 -2
  42. package/dist/cli/{index-1rww5k9e.js → index-z09fmg67.js} +4 -4
  43. package/dist/cli/{index-vy6q9d8j.js → index-z4bg1hv8.js} +1 -1
  44. package/dist/cli/index.js +28 -28
  45. package/dist/cli/{knowledge-escalator-pc7smwrd.js → knowledge-escalator-bqnkq3k7.js} +11 -11
  46. package/dist/cli/{knowledge-events-jmb3jm84.js → knowledge-events-rz3mt7gf.js} +9 -9
  47. package/dist/cli/{knowledge-link-mzn8x0qd.js → knowledge-link-v7hj1h8m.js} +5 -5
  48. package/dist/cli/{knowledge-store-wd6zh05h.js → knowledge-store-1m74b90j.js} +6 -6
  49. package/dist/cli/{knowledge-validator-2v6ar1wk.js → knowledge-validator-hfvhpkgk.js} +8 -8
  50. package/dist/cli/{pending-delegations-qzy6rnvw.js → pending-delegations-a2nmssr1.js} +3 -3
  51. package/dist/cli/{pr-subscriptions-q862pvz1.js → pr-subscriptions-7879nq5k.js} +3 -3
  52. package/dist/cli/{runner-1aygs98c.js → runner-7znestx4.js} +6 -6
  53. package/dist/cli/{scan-cursor-hr8e3jqj.js → scan-cursor-b36bzxkt.js} +7 -7
  54. package/dist/cli/{schema-g44y7s0w.js → schema-sc332es3.js} +1 -1
  55. package/dist/cli/{scope-persistence-0n2cv4kn.js → scope-persistence-phkj8438.js} +8 -8
  56. package/dist/cli/{skill-generator-0gmpxwgk.js → skill-generator-2d005nr6.js} +13 -13
  57. package/dist/cli/{telemetry-5deacb7w.js → telemetry-52pw5xac.js} +1 -1
  58. package/dist/cli/{worktree-collision-ownership-9v8e0dz7.js → worktree-collision-ownership-p31zm5k0.js} +3 -3
  59. package/dist/cli/{worktree-isolation-pcr5zv0c.js → worktree-isolation-zpgkd71h.js} +28 -28
  60. package/dist/commands/close.d.ts +1 -0
  61. package/dist/commands/registry.d.ts +2 -2
  62. package/dist/hooks/guardrails/audit-log.d.ts +70 -19
  63. package/dist/hooks/guardrails/helpers.d.ts +16 -1
  64. package/dist/hooks/guardrails/shell-audit-store.d.ts +211 -0
  65. package/dist/hooks/guardrails/tool-before.d.ts +0 -2
  66. package/dist/index.js +339 -319
  67. package/dist/observability/catalog.d.ts +7 -5
  68. package/dist/services/guardrail-log-service.d.ts +4 -0
  69. package/dist/telemetry.d.ts +22 -1
  70. package/package.json +2 -1
  71. package/dist/cli/index-ggs716fj.js +0 -110
@@ -2,22 +2,30 @@
2
2
  * Unified Guardrail Decision Audit Log
3
3
  *
4
4
  * Additive JSONL schema for guardrail decisions. Each append writes one
5
- * validated JSON line to the configured audit path under `.swarm/session/`.
5
+ * validated, redacted, size-bounded JSON line to the canonical
6
+ * `.swarm/session/shell-audit.jsonl` store (issue #2040). Persistence itself
7
+ * — locking, framing, retention, compaction — is owned by
8
+ * `./shell-audit-store.ts`; this module owns entry validation, write-time
9
+ * redaction/minimization, and line shaping.
6
10
  *
7
11
  * The existing shell audit entry shape is preserved byte-for-byte when
8
12
  * `type: 'shell'` is used (fields: ts, sessionID, agent, tool, command).
9
13
  *
10
- * Path redaction: there is no cross-cutting path-redaction helper in this
11
- * module today. Callers MAY pass a pre-redacted path via `redactPath(...)`
12
- * before constructing the entry; the module itself does not mutate path
13
- * strings beyond normalizing separators. Future hardening: add a shared
14
- * path-redaction utility and call it here.
14
+ * Write-time minimization (issue #2040 requirement 4/5):
15
+ * - Commands are redacted FIRST via `redactShellCommand` (secrets, home
16
+ * paths) redaction sees the full command then truncated to
17
+ * SHELL_AUDIT_LIMITS.maxCommandChars with an explicit `…[truncated]`
18
+ * marker. Callers cannot opt out. Redacting first keeps the correlation
19
+ * hash on the persisted form and minimizes secrets anywhere in the
20
+ * command before any bytes are selected for persistence.
21
+ * - Paths are redacted via `redactPath`; free-text reasons embed
22
+ * home-profile paths via `redactEmbeddedPaths`.
23
+ * - Typed command-bearing entries additionally persist `commandHash` (a
24
+ * 16-hex sha256 digest of the FINAL redacted command) so correlation and
25
+ * duplicate detection survive without reversible content. Legacy
26
+ * `shell` entries stay EXACTLY five fields (SC-119 pinned contract) and
27
+ * never carry the hash.
15
28
  */
16
- import * as fs from 'node:fs/promises';
17
- export declare const _internals: {
18
- mkdir: typeof fs.mkdir;
19
- appendFile: typeof fs.appendFile;
20
- };
21
29
  /**
22
30
  * Discriminated union of guardrail decision types.
23
31
  *
@@ -86,29 +94,72 @@ export interface SandboxSkipDecision {
86
94
  skipReason: string;
87
95
  }
88
96
  export type GuardrailDecisionEntry = ShellDecision | FileWriteDecision | ScopeViolationDecision | DestructiveBlockDecision | SandboxWrapDecision | SandboxSkipDecision;
97
+ /**
98
+ * Redaction/content class of every persisted audit field. SINGLE SOURCE OF
99
+ * TRUTH: the ratchet test (`tests/unit/hooks/shell-audit-field-classes.test.ts`)
100
+ * enumerates the union's fields against this map — adding a decision field
101
+ * without declaring its class fails CI. Classes:
102
+ *
103
+ * - `timestamp` — ISO-8601 string, no free content.
104
+ * - `identifier` — opaque session/agent/tool identity string.
105
+ * - `decision-type` — closed enum discriminator.
106
+ * - `redacted-command` — shell command text after truncation + redaction.
107
+ * - `redacted-path` — filesystem path after home-profile redaction.
108
+ * - `enum` — closed per-type classification string.
109
+ * - `free-text-redacted` — producer free text after bounded truncation +
110
+ * embedded-path redaction.
111
+ * - `content-hash` — one-way digest of redacted content (correlation
112
+ * only; never rendered, never reversible).
113
+ */
114
+ export type ShellAuditFieldClass = 'timestamp' | 'identifier' | 'decision-type' | 'redacted-command' | 'redacted-path' | 'enum' | 'free-text-redacted' | 'content-hash';
115
+ export declare const SHELL_AUDIT_FIELD_CLASSES: Readonly<Record<string, ShellAuditFieldClass>>;
116
+ /** 16-hex sha256 digest of the final redacted command — correlation without
117
+ * reversible content. Deterministic: identical redacted commands hash
118
+ * identically (issue #2040 edge-case: deterministic-enough-for-correlation). */
119
+ export declare function hashRedactedCommand(redacted: string): string;
89
120
  /**
90
121
  * Best-effort path redaction for audit logs.
91
122
  *
92
123
  * Replaces leading home/profile segments with a tilde placeholder so
93
- * absolute paths do not leak user-specific directory names.
124
+ * absolute paths do not leak user-specific directory names (POSIX
125
+ * `/home/<name>`, macOS `/Users/<name>`, Windows drive profiles
126
+ * `C:\Users\<name>` case-insensitive, and UNC profile shares).
94
127
  *
95
- * This is intentionally minimal — callers remain responsible for
96
- * stripping any domain-specific secrets that may appear in path segments.
128
+ * This is intentionally minimal on non-home paths ordinary project paths
129
+ * are diagnostic content and are preserved (over-redaction guards pin it).
97
130
  */
98
131
  export declare function redactPath(filePath: string): string;
132
+ declare function redactEmbeddedPaths(text: string): string;
133
+ export { redactEmbeddedPaths };
134
+ /**
135
+ * Archive-boundary re-redaction (issue #2040 requirement 4 / review round
136
+ * F4): re-apply the CURRENT redaction policy to one persisted decision line
137
+ * before the close pipeline archives it. Legacy pre-#2040 lines written with
138
+ * weaker redaction are normalized here so no legacy record can bypass
139
+ * current policy in the archived cut. Parse-safe passthrough: an
140
+ * unparseable line is returned unchanged (the store's corrupt accounting
141
+ * owns it).
142
+ */
143
+ export declare function redactDecisionLineForArchive(line: string): string;
99
144
  export interface AppendGuardrailDecisionOptions {
100
- auditPath: string;
145
+ /** Project root; the store resolves `.swarm/session/shell-audit.jsonl`. */
146
+ directory: string;
101
147
  enabled: boolean;
102
148
  }
103
149
  /**
104
- * Append a validated guardrail decision entry to the JSONL audit log.
150
+ * Append a validated guardrail decision entry to the JSONL audit store.
105
151
  *
106
- * - Writes exactly one JSON line per call (`JSON.stringify(entry) + '\n'`).
107
152
  * - Skips silently when `enabled` is false.
108
153
  * - Skips malformed entries after debug logging; never throws.
109
- * - `.swarm/` containment is enforced by the caller-supplied `auditPath`.
154
+ * - Truncates + redacts content at line-shaping time (caller-independent
155
+ * minimization); typed command entries carry a correlation hash.
156
+ * - Delegates persistence (lock, framing, retention, compaction) to the
157
+ * bounded store; store failures (locked, oversize, I/O) are caught and
158
+ * logged — audit failures NEVER block tool execution (issue #2040
159
+ * requirement 6: a guardrail block still blocks when logging fails).
160
+ * - `.swarm/` containment is enforced by the store's path resolution.
110
161
  *
111
162
  * @param entry Decision entry to persist.
112
- * @param ctx Audit destination and enablement flag.
163
+ * @param ctx Audit destination (project root) and enablement flag.
113
164
  */
114
165
  export declare function appendGuardrailDecision(entry: GuardrailDecisionEntry, ctx: AppendGuardrailDecisionOptions): Promise<void>;
@@ -33,6 +33,21 @@ export declare function hasTraversalSegments(filePath: string): boolean;
33
33
  export declare function isInDeclaredScope(filePath: string, scopeEntries: string[], cwd?: string): boolean;
34
34
  /**
35
35
  * Redacts sensitive values from a shell command string before audit logging.
36
- * Covers env-var assignments, CLI flags, Bearer/Basic auth, and -H header flags.
36
+ *
37
+ * Covers env-var assignments (POSIX/PowerShell `$env:`/cmd `set`), CLI flags
38
+ * (sensitive names, both `=`-joined and space-separated), Bearer/Basic auth,
39
+ * `-H` header flags, URL credentials (`scheme://user:pass@host`), well-known
40
+ * token VALUE shapes (OpenAI/GitHub/AWS/Slack/Google — content-based, so they
41
+ * fire regardless of the surrounding flag name), and long base64-like payload
42
+ * runs (≥80 chars with mixed case + digit — the encoded-wrapper/heredoc
43
+ * minimization class from issue #2040; plain hex SHAs and short payloads are
44
+ * deliberately NOT matched). Sensitive values are consumed through closing
45
+ * quotes when quoted (`KEY="two words"` redacts the whole value, not just the
46
+ * first word). UNC profile material (`\\server\share\user\…`) is minimized
47
+ * like the other home-profile families.
48
+ *
49
+ * Deterministic: identical inputs always redact identically (correlation via
50
+ * the audit `commandHash` relies on it). No pattern retains any reversible
51
+ * secret material.
37
52
  */
38
53
  export declare function redactShellCommand(cmd: string): string;
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Shell-audit bounded store — the single append seam and bounded store for
3
+ * `.swarm/session/shell-audit.jsonl` (issue #2040, Observability PR 12/23).
4
+ *
5
+ * HISTORY: the guardrail decision audit was a fire-and-forget append-only
6
+ * JSONL with NO byte/age/count ceiling, no locking, no torn-tail handling,
7
+ * and one whole-file reader (`/swarm guardrail-log` read the entire file
8
+ * before filtering) — unbounded growth and unbounded read memory in long
9
+ * sessions.
10
+ *
11
+ * NOW it is a BOUNDED single-file store in the `src/events/core-events.ts`
12
+ * (#2039) house pattern, with SECURITY-AUDIT retention defined separately
13
+ * from general events (issue #2040 requirement 1):
14
+ *
15
+ * Line 1: `swarm-shell-audit-manifest` header carrying the size-bounded
16
+ * FOLDED aggregate (decisions compacted away: lifetime total,
17
+ * per-type counts ≤16 keys + "other", corrupt/dropped counters).
18
+ * Line 2+: raw decision JSONL — the RECENT retained window, byte-for-byte
19
+ * preserved (the store never normalizes producer lines; legacy
20
+ * 5-field shell entries stay legacy).
21
+ *
22
+ * DECISION-CLASS PRIORITY (issue #2040 requirement 2):
23
+ * - SECURITY class — every typed entry (file_write, scope_violation,
24
+ * destructive_block, sandbox_wrap, sandbox_skip): never AGE-folded.
25
+ * - ALLOWED class — legacy no-`type` shell entries: age-folded past
26
+ * allowedAgeMaxMs and held to their own tighter count cap.
27
+ * - The byte ceiling (activeMaxBytes) is SOVEREIGN over both classes:
28
+ * when it binds, the oldest lines fold regardless of class, disclosed
29
+ * via the folded per-type counts and shell_audit_health. Retention
30
+ * NEVER alters guardrail authorization — this store is write-only
31
+ * telemetry; enforcement decisions are computed and thrown by the
32
+ * guardrail hooks independently of any append succeeding.
33
+ *
34
+ * CONCURRENCY: every write (append, fold, finalize) holds the exclusive
35
+ * `.swarm/session/shell-audit.lock` (`wx` create, stale-broken after
36
+ * 5 minutes) — there are no lockless writes.
37
+ *
38
+ * LEGACY MIGRATION: header-less files are read as-is (the manifest is
39
+ * stripped only when line 1 parses as one); the first throttled maintenance
40
+ * fold rewrites them manifest-first in bounded compactMaxBytes passes;
41
+ * close finalize drains to convergence. A crash mid-migration leaves either
42
+ * form, both readable.
43
+ *
44
+ * All functions are synchronous (house pattern). The `_internals` DI seam
45
+ * lets tests override filesystem operations and limits without `mock.module`
46
+ * (AGENTS.md invariant 7). State lives exclusively under `.swarm/session/`
47
+ * (invariant 4) — every function takes an explicit project-root `directory`.
48
+ * No `bun:` imports — Node-ESM-loadable (invariant 2).
49
+ */
50
+ import * as fs from 'node:fs';
51
+ export interface ShellAuditLimits {
52
+ /** Hard ceiling on the retained window (manifest line + decision lines). */
53
+ activeMaxBytes: number;
54
+ /** Hard ceiling on retained SECURITY-class (typed) decision lines. */
55
+ securityMaxEntries: number;
56
+ /** Hard ceiling on retained ALLOWED-class (legacy shell) decision lines. */
57
+ allowedMaxEntries: number;
58
+ /** ALLOWED-class retention age; older allowed decisions fold into the header. */
59
+ allowedAgeMaxMs: number;
60
+ /** Bounded fold work per maintenance pass (bytes of folded lines). */
61
+ compactMaxBytes: number;
62
+ /** Hard documented read bound for public reads, independent of history. */
63
+ readMaxBytes: number;
64
+ /** Appends between throttled maintenance checks. */
65
+ checkInterval: number;
66
+ /** Disk-pressure/failure warning cooldown. */
67
+ warnCooldownMs: number;
68
+ /** Upper bound for a serialized manifest header (single line). */
69
+ headerMaxBytes: number;
70
+ /** Serialized single-decision bound; larger appends fail with a typed error. */
71
+ maxLineBytes: number;
72
+ /** Raw command truncation bound applied at line-shaping time. */
73
+ maxCommandChars: number;
74
+ /** Free-text (reason) truncation bound applied at line-shaping time. */
75
+ maxReasonChars: number;
76
+ /**
77
+ * Hard bound on any single whole-file store read. A legacy header-less
78
+ * file larger than this migrates through the bounded STREAMING reader
79
+ * (chunked line folding) instead of being materialized whole (review
80
+ * round RC-2: the legacy path is exactly the file that lacks the
81
+ * activeMaxBytes ceiling).
82
+ */
83
+ migrationMaxBytes: number;
84
+ }
85
+ export declare const SHELL_AUDIT_LIMITS: ShellAuditLimits;
86
+ export type ShellAuditDecisionClass = 'security' | 'allowed';
87
+ /** Size-bounded folded aggregate persisted in the manifest header. FOLDED-ONLY:
88
+ * decisions compacted/cut away from the retained window. Retained decisions
89
+ * are NOT in here. Lifetime totals = folded + retained. */
90
+ export interface ShellAuditFolded {
91
+ totalDecisions: number;
92
+ /** Per-discriminator counts, capped at 16 distinct keys + "other". */
93
+ byType: Record<string, number>;
94
+ corrupt: number;
95
+ dropped: number;
96
+ oldestTimestamp: string | null;
97
+ newestTimestamp: string | null;
98
+ }
99
+ export interface ShellAuditManifest {
100
+ v: 1;
101
+ type: 'swarm-shell-audit-manifest';
102
+ schemaVersion: number;
103
+ folded: ShellAuditFolded;
104
+ updatedAt: string;
105
+ }
106
+ export declare const _internals: {
107
+ readonly appendFileSync: typeof fs.appendFileSync;
108
+ readonly readFileSync: typeof fs.readFileSync;
109
+ readonly existsSync: typeof fs.existsSync;
110
+ readonly mkdirSync: typeof fs.mkdirSync;
111
+ readonly statSync: fs.StatSyncFn;
112
+ readonly renameSync: typeof fs.renameSync;
113
+ readonly writeFileSync: typeof fs.writeFileSync;
114
+ readonly unlinkSync: typeof fs.unlinkSync;
115
+ readonly openSync: typeof fs.openSync;
116
+ readonly closeSync: typeof fs.closeSync;
117
+ readonly readSync: typeof fs.readSync;
118
+ readonly now: () => number;
119
+ readonly limits: ShellAuditLimits;
120
+ readonly emitHealth: typeof emitShellAuditHealth;
121
+ };
122
+ export declare function shellAuditFilePath(directory: string): string;
123
+ export type ShellAuditCoverage = 'complete' | 'truncated' | 'empty';
124
+ /** The bounded view of the retained window. `text` is manifest-stripped
125
+ * decision lines in append order (never starting mid-line). */
126
+ export interface ShellAuditReadResult {
127
+ text: string;
128
+ truncated: boolean;
129
+ coverage: ShellAuditCoverage;
130
+ }
131
+ export interface ShellAuditStoreLock {
132
+ /** Release the lock (idempotent). */
133
+ release: () => void;
134
+ }
135
+ /**
136
+ * Acquire the exclusive store lock with a brief bounded retry, then run `fn`
137
+ * while holding it. Returns null when the lock stays contended for the whole
138
+ * retry window — callers map that onto their existing error contract (the
139
+ * audit append path is fail-open: catch + debug log, never block the tool).
140
+ */
141
+ export declare function withShellAuditStoreLock<T>(directory: string, fn: () => T): T | null;
142
+ /** Test seam (AGENTS.md invariant 7): reset module-scoped maintenance
143
+ * counters between tests. Restore by calling in `afterEach`. */
144
+ export declare function _resetMaintenanceCounters(): void;
145
+ /**
146
+ * Bounded read of the retained window: the newest `readMaxBytes` of decision
147
+ * lines, manifest-stripped, in append order. `truncated` means older history
148
+ * exists beyond the read bound (a legacy header-less file larger than the
149
+ * bound, or a store mid-drain) — callers disclose it, never silently treat
150
+ * the window as complete history.
151
+ */
152
+ export declare function readShellAuditTail(directory: string, maxBytes?: number): ShellAuditReadResult;
153
+ /** Manifest folded summary via a header-only bounded read (null when the file
154
+ * is absent or still header-less/legacy). */
155
+ export declare function getShellAuditFoldedSummary(directory: string): ShellAuditFolded | null;
156
+ /** Typed store-busy error — the audit append path maps it onto its existing
157
+ * fail-open contract (catch + debug log; never block the tool call). */
158
+ export declare const SHELL_AUDIT_STORE_LOCKED = "SHELL_AUDIT_STORE_LOCKED";
159
+ export declare const SHELL_AUDIT_LINE_TOO_LARGE = "SHELL_AUDIT_LINE_TOO_LARGE";
160
+ /**
161
+ * Append one serialized decision line to the store through the canonical
162
+ * seam. The caller (audit-log.ts) has already validated the entry shape and
163
+ * applied write-time redaction; this function owns framing, locking, and
164
+ * retention.
165
+ *
166
+ * - Holds the store lock for the write; re-establishes line framing when a
167
+ * prior crash tore the tail (newline prefix).
168
+ * - First write on a fresh store is atomic (manifest + one line) so a crash
169
+ * can never leave a torn header at line 1.
170
+ * - A legacy header-less file is appended to as-is; the throttled maintenance
171
+ * pass migrates it manifest-first in bounded passes.
172
+ * - Runs throttled maintenance (bounded compaction / legacy drain) every
173
+ * `checkInterval` appends, after the lock is released.
174
+ *
175
+ * Throws `SHELL_AUDIT_STORE_LOCKED` after bounded lock retry, or
176
+ * `SHELL_AUDIT_LINE_TOO_LARGE` for oversized lines — the audit append path
177
+ * catches both and logs non-fatally (logging failure never blocks a tool).
178
+ */
179
+ export declare function appendShellAuditLineSync(directory: string, line: string): void;
180
+ /** External compaction trigger. Fail-open. */
181
+ export declare function compactShellAudit(directory: string): void;
182
+ /**
183
+ * Close finalize (issue #2040 requirement 7): under one lock acquisition,
184
+ * drain any legacy header-less file to convergence and fold the remaining
185
+ * window into a defined, VALIDATED cut (the atomicReplace pre-rename
186
+ * validation), which `/swarm close` then archives as part of the session
187
+ * directory copy. Fail-open: never throws to the close pipeline. Releasing
188
+ * the lock also unlinks it, so a stale lock file is never archived.
189
+ *
190
+ * `options.lineTransform` (review round F4): when provided, every retained
191
+ * decision line is passed through it before the final validated rewrite —
192
+ * the close pipeline supplies the CURRENT redaction policy so a legacy
193
+ * record with weaker pre-#2040 redaction cannot bypass it in the archived
194
+ * cut ("re-redact at the archive boundary").
195
+ */
196
+ export declare function finalizeShellAuditForClose(directory: string, options?: {
197
+ lineTransform?: (line: string) => string;
198
+ }): void;
199
+ declare function emitShellAuditHealth(directory: string, payload: {
200
+ trigger: 'compaction' | 'close';
201
+ accepted: number;
202
+ compacted: number;
203
+ retained: number;
204
+ dropped: number;
205
+ corrupt: number;
206
+ oldest: string | null;
207
+ newest: string | null;
208
+ bytes: number;
209
+ limitBytes: number;
210
+ }): void;
211
+ export {};
@@ -23,8 +23,6 @@ export interface ToolBeforeContext {
23
23
  precomputedAuthorityRules: Record<string, AgentRule>;
24
24
  /** Global deny prefixes — apply to all agents regardless of per-agent rules */
25
25
  universalDenyPrefixes: string[];
26
- /** Shell audit log path */
27
- shellAuditPath: string;
28
26
  /** Whether shell audit logging is enabled */
29
27
  shellAuditEnabled: boolean;
30
28
  /** Agents allowed to use bash/shell interpreter (undefined = all allowed) */