@intutic/sync-daemon 2.4.0 → 2.5.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/configWriter.d.ts +2 -1
- package/dist/configWriter.d.ts.map +1 -1
- package/dist/configWriter.js +4 -4
- package/dist/configWriter.js.map +1 -1
- package/dist/disconnect/originals.d.ts.map +1 -1
- package/dist/disconnect/originals.js +5 -12
- package/dist/disconnect/originals.js.map +1 -1
- package/dist/disconnect/plan.d.ts.map +1 -1
- package/dist/disconnect/plan.js +3 -14
- package/dist/disconnect/plan.js.map +1 -1
- package/dist/harness/aiderConfigMerger.d.ts.map +1 -1
- package/dist/harness/aiderConfigMerger.js +4 -9
- package/dist/harness/aiderConfigMerger.js.map +1 -1
- package/dist/harness/antigravityCliHooks.d.ts.map +1 -1
- package/dist/harness/antigravityCliHooks.js +3 -7
- package/dist/harness/antigravityCliHooks.js.map +1 -1
- package/dist/harness/antigravityHooks.d.ts.map +1 -1
- package/dist/harness/antigravityHooks.js +3 -7
- package/dist/harness/antigravityHooks.js.map +1 -1
- package/dist/harness/claudeCodeHooks.d.ts.map +1 -1
- package/dist/harness/claudeCodeHooks.js +15 -4
- package/dist/harness/claudeCodeHooks.js.map +1 -1
- package/dist/harness/clineHooks.d.ts.map +1 -1
- package/dist/harness/clineHooks.js +4 -5
- package/dist/harness/clineHooks.js.map +1 -1
- package/dist/harness/codexConfigMerger.d.ts.map +1 -1
- package/dist/harness/codexConfigMerger.js +2 -3
- package/dist/harness/codexConfigMerger.js.map +1 -1
- package/dist/harness/codexHooks.d.ts.map +1 -1
- package/dist/harness/codexHooks.js +3 -7
- package/dist/harness/codexHooks.js.map +1 -1
- package/dist/harness/continueConfigMerger.d.ts.map +1 -1
- package/dist/harness/continueConfigMerger.js +2 -3
- package/dist/harness/continueConfigMerger.js.map +1 -1
- package/dist/harness/cursorHooks.d.ts.map +1 -1
- package/dist/harness/cursorHooks.js +3 -7
- package/dist/harness/cursorHooks.js.map +1 -1
- package/dist/harness/dshHooks.d.ts.map +1 -1
- package/dist/harness/dshHooks.js +7 -18
- package/dist/harness/dshHooks.js.map +1 -1
- package/dist/harness/gateBody.d.ts +39 -2
- package/dist/harness/gateBody.d.ts.map +1 -1
- package/dist/harness/gateBody.js +465 -70
- package/dist/harness/gateBody.js.map +1 -1
- package/dist/harness/gateSightings.d.ts.map +1 -1
- package/dist/harness/gateSightings.js +2 -3
- package/dist/harness/gateSightings.js.map +1 -1
- package/dist/harness/githubCopilotHooks.d.ts.map +1 -1
- package/dist/harness/githubCopilotHooks.js +2 -4
- package/dist/harness/githubCopilotHooks.js.map +1 -1
- package/dist/harness/gooseHooks.d.ts.map +1 -1
- package/dist/harness/gooseHooks.js +4 -10
- package/dist/harness/gooseHooks.js.map +1 -1
- package/dist/harness/grokHooks.d.ts.map +1 -1
- package/dist/harness/grokHooks.js +4 -10
- package/dist/harness/grokHooks.js.map +1 -1
- package/dist/harness/hermesHooks.d.ts.map +1 -1
- package/dist/harness/hermesHooks.js +5 -13
- package/dist/harness/hermesHooks.js.map +1 -1
- package/dist/harness/mcpAutoWrite.d.ts.map +1 -1
- package/dist/harness/mcpAutoWrite.js +9 -10
- package/dist/harness/mcpAutoWrite.js.map +1 -1
- package/dist/harness/museHooks.d.ts.map +1 -1
- package/dist/harness/museHooks.js +4 -10
- package/dist/harness/museHooks.js.map +1 -1
- package/dist/harness/n8nHooks.d.ts.map +1 -1
- package/dist/harness/n8nHooks.js +5 -12
- package/dist/harness/n8nHooks.js.map +1 -1
- package/dist/harness/openWebuiHooks.d.ts.map +1 -1
- package/dist/harness/openWebuiHooks.js +7 -7
- package/dist/harness/openWebuiHooks.js.map +1 -1
- package/dist/harness/openclawHooks.d.ts.map +1 -1
- package/dist/harness/openclawHooks.js +5 -4
- package/dist/harness/openclawHooks.js.map +1 -1
- package/dist/harness/openhandsHooks.d.ts.map +1 -1
- package/dist/harness/openhandsHooks.js +4 -10
- package/dist/harness/openhandsHooks.js.map +1 -1
- package/dist/harness/piHooks.d.ts.map +1 -1
- package/dist/harness/piHooks.js +2 -3
- package/dist/harness/piHooks.js.map +1 -1
- package/dist/harness/protectedPaths.d.ts +3 -1
- package/dist/harness/protectedPaths.d.ts.map +1 -1
- package/dist/harness/protectedPaths.js +47 -1
- package/dist/harness/protectedPaths.js.map +1 -1
- package/dist/harness/rulesSection.d.ts.map +1 -1
- package/dist/harness/rulesSection.js +3 -7
- package/dist/harness/rulesSection.js.map +1 -1
- package/dist/harness/windsurfHooks.d.ts.map +1 -1
- package/dist/harness/windsurfHooks.js +3 -7
- package/dist/harness/windsurfHooks.js.map +1 -1
- package/dist/harness/windsurfJetBrainsProxy.d.ts.map +1 -1
- package/dist/harness/windsurfJetBrainsProxy.js +1 -5
- package/dist/harness/windsurfJetBrainsProxy.js.map +1 -1
- package/dist/lib/approvedBypasses.d.ts.map +1 -1
- package/dist/lib/approvedBypasses.js +2 -4
- package/dist/lib/approvedBypasses.js.map +1 -1
- package/dist/lib/atomicWrite.d.ts +45 -0
- package/dist/lib/atomicWrite.d.ts.map +1 -0
- package/dist/lib/atomicWrite.js +104 -0
- package/dist/lib/atomicWrite.js.map +1 -0
- package/dist/lib/chaosPy.d.ts +11 -0
- package/dist/lib/chaosPy.d.ts.map +1 -0
- package/dist/lib/chaosPy.js +320 -0
- package/dist/lib/chaosPy.js.map +1 -0
- package/dist/lib/decisionsDigest.d.ts.map +1 -1
- package/dist/lib/decisionsDigest.js +2 -5
- package/dist/lib/decisionsDigest.js.map +1 -1
- package/dist/lib/egressPolicy.d.ts.map +1 -1
- package/dist/lib/egressPolicy.js +2 -4
- package/dist/lib/egressPolicy.js.map +1 -1
- package/dist/lib/policySnapshot.d.ts +2 -2
- package/dist/lib/policySnapshot.d.ts.map +1 -1
- package/dist/lib/policySnapshot.js +43 -20
- package/dist/lib/policySnapshot.js.map +1 -1
- package/dist/lib/regexLinearity.d.ts.map +1 -1
- package/dist/lib/regexLinearity.js +2 -0
- package/dist/lib/regexLinearity.js.map +1 -1
- package/dist/lib/runtimeEnv.d.ts.map +1 -1
- package/dist/lib/runtimeEnv.js +3 -4
- package/dist/lib/runtimeEnv.js.map +1 -1
- package/dist/skillWriter.d.ts +1 -1
- package/dist/skillWriter.d.ts.map +1 -1
- package/dist/skillWriter.js +8 -4
- package/dist/skillWriter.js.map +1 -1
- package/dist/trajectoryMonitor.d.ts +22 -6
- package/dist/trajectoryMonitor.d.ts.map +1 -1
- package/dist/trajectoryMonitor.js +40 -9
- package/dist/trajectoryMonitor.js.map +1 -1
- package/dist/watcher/settingsGuard.d.ts.map +1 -1
- package/dist/watcher/settingsGuard.js +23 -2
- package/dist/watcher/settingsGuard.js.map +1 -1
- package/package.json +9 -5
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* atomicWrite.ts — the one way the daemon replaces a whole file that a
|
|
3
|
+
* harness or a gate reads.
|
|
4
|
+
*
|
|
5
|
+
* A gate script, a hook registration, a harness settings file and the policy
|
|
6
|
+
* snapshot are all read by other processes at moments the daemon does not
|
|
7
|
+
* choose. A plain `writeFile` truncates first and fills after, so a reader in
|
|
8
|
+
* between sees an empty or half-written file: a truncated gate script crashes,
|
|
9
|
+
* and for the exit-code harnesses (Claude Code and most others) a crash with
|
|
10
|
+
* any code other than 2 lets the tool call through, ungoverned. So every such
|
|
11
|
+
* write goes to a temp file beside the target and is renamed over it: a
|
|
12
|
+
* reader opens either the old file or the new one, never a mix.
|
|
13
|
+
*
|
|
14
|
+
* `__tests__/lib/atomicWriteGuard.test.ts` fails when a harness writer calls
|
|
15
|
+
* `writeFile` itself instead of this.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { randomBytes } from 'node:crypto';
|
|
20
|
+
import * as fs from 'node:fs/promises';
|
|
21
|
+
/** Per-process counter, so two writes from one process never share a temp name. */
|
|
22
|
+
let sequence = 0;
|
|
23
|
+
/**
|
|
24
|
+
* Replaces `file` with `content` atomically: a unique temp file in the same
|
|
25
|
+
* directory (a rename is only atomic within one filesystem), written, given
|
|
26
|
+
* its final mode, flushed to disk, then renamed over the target. On any
|
|
27
|
+
* failure the temp file is removed and the error rethrown; the target is then
|
|
28
|
+
* untouched. The parent directory must exist.
|
|
29
|
+
*/
|
|
30
|
+
export async function writeFileAtomic(file, content, options = {}) {
|
|
31
|
+
const target = options.followSymlink ? await linkTarget(file) : file;
|
|
32
|
+
const mode = options.mode ?? (await currentMode(target));
|
|
33
|
+
// pid + counter is unique among live writers; the random part keeps a temp
|
|
34
|
+
// left behind by a crashed process whose pid came round again from
|
|
35
|
+
// colliding. `wx` refuses an existing path, a planted symlink included.
|
|
36
|
+
const tmp = `${target}.${process.pid}-${++sequence}-${randomBytes(4).toString('hex')}.intutic-tmp`;
|
|
37
|
+
let handle;
|
|
38
|
+
try {
|
|
39
|
+
handle = await fs.open(tmp, 'wx', mode ?? 0o666);
|
|
40
|
+
await handle.writeFile(content);
|
|
41
|
+
// `open`'s mode passes through the umask; this does not.
|
|
42
|
+
if (mode !== undefined)
|
|
43
|
+
await handle.chmod(mode);
|
|
44
|
+
await handle.sync();
|
|
45
|
+
await handle.close();
|
|
46
|
+
handle = undefined;
|
|
47
|
+
await renameOver(tmp, target, content, mode);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
await handle?.close().catch(() => undefined);
|
|
51
|
+
await fs.rm(tmp, { force: true }).catch(() => undefined);
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function linkTarget(file) {
|
|
56
|
+
try {
|
|
57
|
+
return await fs.realpath(file);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Nothing there yet (or a dangling link): write the path itself.
|
|
61
|
+
return file;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function currentMode(file) {
|
|
65
|
+
try {
|
|
66
|
+
return (await fs.stat(file)).mode & 0o7777;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const WINDOWS_RENAME_CODES = new Set(['EPERM', 'EACCES', 'EBUSY']);
|
|
73
|
+
const WINDOWS_RENAME_ATTEMPTS = 5;
|
|
74
|
+
/**
|
|
75
|
+
* POSIX rename replaces the target whatever its mode and whoever has it open.
|
|
76
|
+
* Windows refuses while the target is read-only (the 0444 snapshot) or open
|
|
77
|
+
* without delete sharing (an editor, a virus scanner), usually only for a
|
|
78
|
+
* moment. So there: clear read-only, retry with a short backoff, and as a last
|
|
79
|
+
* resort write the target in place, which is what every one of these writes
|
|
80
|
+
* did before and is better than leaving the old gate or settings in force.
|
|
81
|
+
*/
|
|
82
|
+
async function renameOver(tmp, target, content, mode) {
|
|
83
|
+
for (let attempt = 1;; attempt++) {
|
|
84
|
+
try {
|
|
85
|
+
await fs.rename(tmp, target);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
const code = err.code ?? '';
|
|
90
|
+
if (process.platform !== 'win32' || !WINDOWS_RENAME_CODES.has(code))
|
|
91
|
+
throw err;
|
|
92
|
+
if (attempt === 1)
|
|
93
|
+
await fs.chmod(target, 0o666).catch(() => undefined);
|
|
94
|
+
if (attempt >= WINDOWS_RENAME_ATTEMPTS)
|
|
95
|
+
break;
|
|
96
|
+
await new Promise((resolve) => setTimeout(resolve, 25 * 2 ** attempt));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
await fs.writeFile(target, content);
|
|
100
|
+
if (mode !== undefined)
|
|
101
|
+
await fs.chmod(target, mode);
|
|
102
|
+
await fs.rm(tmp, { force: true });
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=atomicWrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomicWrite.js","sourceRoot":"","sources":["../../src/lib/atomicWrite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chaos-run fault injection in Python, for the bash gates (their
|
|
3
|
+
* extractor already requires python3).
|
|
4
|
+
*
|
|
5
|
+
* Byte-identical to `packages/intutic-clawde/intutic_clawde/gate/chaos.py`,
|
|
6
|
+
* which a test compares; edit that file and copy it here. It is the
|
|
7
|
+
* transliteration of `@intutic/shared-types`'s chaosGate.ts, and both run the
|
|
8
|
+
* shared vectors.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CHAOS_PY_SOURCE: string;
|
|
11
|
+
//# sourceMappingURL=chaosPy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chaosPy.d.ts","sourceRoot":"","sources":["../../src/lib/chaosPy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,QAqT3B,CAAA"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chaos-run fault injection in Python, for the bash gates (their
|
|
3
|
+
* extractor already requires python3).
|
|
4
|
+
*
|
|
5
|
+
* Byte-identical to `packages/intutic-clawde/intutic_clawde/gate/chaos.py`,
|
|
6
|
+
* which a test compares; edit that file and copy it here. It is the
|
|
7
|
+
* transliteration of `@intutic/shared-types`'s chaosGate.ts, and both run the
|
|
8
|
+
* shared vectors.
|
|
9
|
+
*/
|
|
10
|
+
export const CHAOS_PY_SOURCE = String.raw `"""Fault injection in the hook gates, for chaos runs (intutic chaos run).
|
|
11
|
+
|
|
12
|
+
A transliteration of packages/shared-types/src/chaosGate.ts; read that
|
|
13
|
+
module's docstring for the counter files and why every count lives on disk.
|
|
14
|
+
In short: a gate is a new process per tool call, so the plan is decoded on
|
|
15
|
+
each call, plan_loaded is reported by whichever gate first creates
|
|
16
|
+
EVENTS.gate-plan-loaded, and each fault's seen and hit counts are numbered
|
|
17
|
+
empty files in EVENTS.gate-counters/, each number claimed with an exclusive
|
|
18
|
+
create (O_CREAT | O_EXCL), which exactly one process wins. A permission fault
|
|
19
|
+
never sleeps: it holds the call as an approval hold does, in a
|
|
20
|
+
FAULT.held.KEY.G file whose modification time is when, and the identical
|
|
21
|
+
retry is held again until delay_s has passed, then allowed (delay) or denied
|
|
22
|
+
(hold_then_deny) by the one retry that creates FAULT.released.KEY.G.
|
|
23
|
+
|
|
24
|
+
The bash gates emit this file verbatim (services/sync-daemon/src/lib/chaosPy.ts
|
|
25
|
+
holds a byte-identical copy, which a test compares), intutic_clawde.gate's
|
|
26
|
+
Gate.guard runs it in process, and every copy runs
|
|
27
|
+
packages/shared-types/fixtures/chaos-gate-vectors.json. It must stay
|
|
28
|
+
self-contained: the standard library only, no module state beyond the
|
|
29
|
+
constants below, and no backtick or dollar-brace, which the TypeScript copy
|
|
30
|
+
cannot hold.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import base64
|
|
34
|
+
import binascii
|
|
35
|
+
import datetime
|
|
36
|
+
import json
|
|
37
|
+
import os
|
|
38
|
+
import re
|
|
39
|
+
import sys
|
|
40
|
+
import time
|
|
41
|
+
|
|
42
|
+
_CHAOS_FAULT_IDS = (
|
|
43
|
+
"llm.rate_limit", "llm.upstream_5xx", "llm.context_trim", "llm.model_degrade", "tool.error", "tool.stale_data",
|
|
44
|
+
"mcp.toolset_change", "permission.deny_or_delay", "inject.tool_result", "egress.dns_fail", "egress.credential_401",
|
|
45
|
+
)
|
|
46
|
+
_CHAOS_B64URL = re.compile(r"^[A-Za-z0-9_-]+={0,2}$")
|
|
47
|
+
_CHAOS_RUN_ID = re.compile(r"^[A-Za-z0-9_-]{6,64}$")
|
|
48
|
+
_CHAOS_CANARY = re.compile(r"^E-INTUTIC-[0-9A-F]{4,16}$")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _chaos_int(v, low, high):
|
|
52
|
+
# JSON numbers as JavaScript reads them: 2.0 is the integer 2. A bool is not a number.
|
|
53
|
+
if isinstance(v, bool) or not isinstance(v, (int, float)):
|
|
54
|
+
return None
|
|
55
|
+
if isinstance(v, float):
|
|
56
|
+
if not v.is_integer():
|
|
57
|
+
return None
|
|
58
|
+
v = int(v)
|
|
59
|
+
return v if low <= v <= high else None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def chaos_decode(raw):
|
|
63
|
+
"""(plan, None), or (None, why it is not one)."""
|
|
64
|
+
def invalid(why):
|
|
65
|
+
return None, "INTUTIC_CHAOS_PLAN is not a valid plan: " + why
|
|
66
|
+
try:
|
|
67
|
+
if not isinstance(raw, str) or not _CHAOS_B64URL.match(raw):
|
|
68
|
+
raise ValueError("alphabet")
|
|
69
|
+
b64 = raw.rstrip("=")
|
|
70
|
+
data = json.loads(base64.urlsafe_b64decode(b64 + "=" * ((4 - len(b64) % 4) % 4)).decode("utf-8"))
|
|
71
|
+
except (ValueError, binascii.Error, UnicodeDecodeError):
|
|
72
|
+
return None, "INTUTIC_CHAOS_PLAN is not base64url-encoded JSON"
|
|
73
|
+
if not isinstance(data, dict):
|
|
74
|
+
return invalid("not a JSON object")
|
|
75
|
+
v = data.get("v")
|
|
76
|
+
if isinstance(v, bool) or v != 1:
|
|
77
|
+
return invalid("version " + json.dumps(v) + ", and a gate reads only version 1")
|
|
78
|
+
run_id = data.get("runId")
|
|
79
|
+
if not isinstance(run_id, str) or not _CHAOS_RUN_ID.match(run_id):
|
|
80
|
+
return invalid("runId")
|
|
81
|
+
canary = data.get("canary")
|
|
82
|
+
if not isinstance(canary, str) or not _CHAOS_CANARY.match(canary):
|
|
83
|
+
return invalid("canary")
|
|
84
|
+
raw_faults = data.get("faults")
|
|
85
|
+
if not isinstance(raw_faults, list) or len(raw_faults) > 50:
|
|
86
|
+
return invalid("faults")
|
|
87
|
+
faults = []
|
|
88
|
+
for i, f in enumerate(raw_faults):
|
|
89
|
+
at = "faults[" + str(i) + "]"
|
|
90
|
+
if not isinstance(f, dict) or not isinstance(f.get("id"), str) or f["id"] not in _CHAOS_FAULT_IDS:
|
|
91
|
+
return invalid(at + ".id")
|
|
92
|
+
if f["id"] not in ("tool.error", "permission.deny_or_delay"):
|
|
93
|
+
continue
|
|
94
|
+
match = None
|
|
95
|
+
if "match" in f:
|
|
96
|
+
if not isinstance(f["match"], dict):
|
|
97
|
+
return invalid(at + ".match")
|
|
98
|
+
for k, mv in f["match"].items():
|
|
99
|
+
if k not in ("tool", "host", "model") or not isinstance(mv, str) or not mv:
|
|
100
|
+
return invalid(at + ".match." + k)
|
|
101
|
+
match = f["match"]
|
|
102
|
+
after_calls = 0
|
|
103
|
+
if "after_calls" in f:
|
|
104
|
+
after_calls = _chaos_int(f["after_calls"], 0, 10000)
|
|
105
|
+
if after_calls is None:
|
|
106
|
+
return invalid(at + ".after_calls")
|
|
107
|
+
times = None
|
|
108
|
+
if "times" in f:
|
|
109
|
+
times = _chaos_int(f["times"], 1, 10000)
|
|
110
|
+
if times is None:
|
|
111
|
+
return invalid(at + ".times")
|
|
112
|
+
fault = {
|
|
113
|
+
"index": i, "id": f["id"], "match": match, "after_calls": after_calls, "times": times,
|
|
114
|
+
"message": "tool failed", "mode": "deny", "delay_s": 0,
|
|
115
|
+
}
|
|
116
|
+
if f["id"] == "tool.error" and "message" in f:
|
|
117
|
+
# Lengths in UTF-16 code units, as JavaScript counts them.
|
|
118
|
+
m = f["message"]
|
|
119
|
+
if not isinstance(m, str) or not 1 <= len(m.encode("utf-16-le", "surrogatepass")) // 2 <= 2000:
|
|
120
|
+
return invalid(at + ".message")
|
|
121
|
+
fault["message"] = m
|
|
122
|
+
if f["id"] == "permission.deny_or_delay":
|
|
123
|
+
if "mode" in f:
|
|
124
|
+
if f["mode"] not in ("deny", "delay", "hold_then_deny"):
|
|
125
|
+
return invalid(at + ".mode")
|
|
126
|
+
fault["mode"] = f["mode"]
|
|
127
|
+
if "delay_s" in f:
|
|
128
|
+
delay_s = _chaos_int(f["delay_s"], 0, 600)
|
|
129
|
+
if delay_s is None:
|
|
130
|
+
return invalid(at + ".delay_s")
|
|
131
|
+
fault["delay_s"] = delay_s
|
|
132
|
+
faults.append(fault)
|
|
133
|
+
return {"runId": run_id, "canary": canary, "faults": faults}, None
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def chaos_matches(match, tool):
|
|
137
|
+
"""Whether a fault's match covers a gate call, which has a tool and nothing else."""
|
|
138
|
+
if not match:
|
|
139
|
+
return True
|
|
140
|
+
if "host" in match or "model" in match:
|
|
141
|
+
return False
|
|
142
|
+
p = match.get("tool")
|
|
143
|
+
if p is None:
|
|
144
|
+
return True
|
|
145
|
+
return tool.endswith(p[1:]) if p.startswith("*") else tool == p
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def chaos_event(plan, type_, fields, now):
|
|
149
|
+
"""One events-file line: ts, runId, component, type, then the fields that are set."""
|
|
150
|
+
event = {"ts": now, "runId": plan["runId"], "component": "gate", "type": type_}
|
|
151
|
+
for k, v in fields:
|
|
152
|
+
if v is not None:
|
|
153
|
+
event[k] = v
|
|
154
|
+
return json.dumps(event, separators=(",", ":"), ensure_ascii=False) + "\n"
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def chaos_append(events_path, lines):
|
|
158
|
+
"""Appends whole lines in one write. An I/O error is reported, never raised."""
|
|
159
|
+
try:
|
|
160
|
+
fd = os.open(events_path, os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0o644)
|
|
161
|
+
try:
|
|
162
|
+
os.write(fd, lines.encode("utf-8"))
|
|
163
|
+
finally:
|
|
164
|
+
os.close(fd)
|
|
165
|
+
except OSError as e:
|
|
166
|
+
sys.stderr.write("[Intutic Governance] chaos: could not append to " + events_path + ": " + str(e) + "\n")
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def chaos_claim(directory, prefix, limit):
|
|
170
|
+
"""Claims the next numbered file DIRECTORY/PREFIXn with an exclusive create.
|
|
171
|
+
|
|
172
|
+
Returns n, 0 when every number up to limit is taken, or -1 on an I/O
|
|
173
|
+
error, after saying so.
|
|
174
|
+
"""
|
|
175
|
+
try:
|
|
176
|
+
# Beside the events file, never creating its directory: the runner did.
|
|
177
|
+
try:
|
|
178
|
+
os.mkdir(directory)
|
|
179
|
+
except FileExistsError:
|
|
180
|
+
pass
|
|
181
|
+
n = sum(1 for name in os.listdir(directory) if name.startswith(prefix)) + 1
|
|
182
|
+
while limit is None or n <= limit:
|
|
183
|
+
try:
|
|
184
|
+
os.close(os.open(os.path.join(directory, prefix + str(n)), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644))
|
|
185
|
+
return n
|
|
186
|
+
except FileExistsError:
|
|
187
|
+
n += 1
|
|
188
|
+
return 0
|
|
189
|
+
except OSError as e:
|
|
190
|
+
sys.stderr.write("[Intutic Governance] chaos: could not count calls in " + directory + ": " + str(e) + "\n")
|
|
191
|
+
return -1
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def chaos_open_hold(directory, fault, key):
|
|
195
|
+
"""The open hold of one fault on one call: (g, created), the number of
|
|
196
|
+
the newest FAULT.held.KEY.G file with no released twin and its
|
|
197
|
+
modification time in milliseconds; None when there is none or it cannot
|
|
198
|
+
be read."""
|
|
199
|
+
try:
|
|
200
|
+
held = str(fault) + ".held." + key + "."
|
|
201
|
+
names = os.listdir(directory)
|
|
202
|
+
g = 0
|
|
203
|
+
for name in names:
|
|
204
|
+
if name.startswith(held) and name[len(held):].isdigit():
|
|
205
|
+
g = max(g, int(name[len(held):]))
|
|
206
|
+
if g == 0 or (str(fault) + ".released." + key + "." + str(g)) in names:
|
|
207
|
+
return None
|
|
208
|
+
# In whole milliseconds, as now is: a hold is never younger than the call that reads it.
|
|
209
|
+
return g, os.stat(os.path.join(directory, held + str(g))).st_mtime_ns // 1000000
|
|
210
|
+
except OSError:
|
|
211
|
+
# No counters yet, or none readable: no hold to continue.
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def chaos_release(directory, fault, key, g):
|
|
216
|
+
"""Ends hold g with an exclusive create: True for the one caller that does."""
|
|
217
|
+
try:
|
|
218
|
+
os.close(os.open(os.path.join(directory, str(fault) + ".released." + key + "." + str(g)),
|
|
219
|
+
os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644))
|
|
220
|
+
return True
|
|
221
|
+
except OSError:
|
|
222
|
+
# Another gate released it first, or it cannot be written.
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _chaos_ms(now):
|
|
227
|
+
# The ISO-8601 time a call is decided at, in milliseconds; the clock if unreadable.
|
|
228
|
+
try:
|
|
229
|
+
return round(datetime.datetime.fromisoformat(now.replace("Z", "+00:00")).timestamp() * 1000)
|
|
230
|
+
except (AttributeError, TypeError, ValueError):
|
|
231
|
+
return int(time.time() * 1000)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def chaos_now():
|
|
235
|
+
"""The time as the JavaScript gates write it: 2026-10-10T12:00:00.000Z."""
|
|
236
|
+
return datetime.datetime.now(datetime.timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z")
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def chaos_call(plan, events_path, call, now):
|
|
240
|
+
"""Reports one call and returns the fault the gate must apply, or None.
|
|
241
|
+
|
|
242
|
+
call: tool, decision (allow, deny, ask or hold, before any fault), ruleId,
|
|
243
|
+
destructive, policyHit, and key: the call's digest in hex (its tool and
|
|
244
|
+
input, as the gate keys an approval hold), which a held call's retry
|
|
245
|
+
shares. The fault: faultId, kind (deny or hold) and reason, as
|
|
246
|
+
chaosGateCall returns it. now is the ISO-8601 time, and the clock a hold
|
|
247
|
+
is timed by.
|
|
248
|
+
"""
|
|
249
|
+
lines = ""
|
|
250
|
+
first = True
|
|
251
|
+
try:
|
|
252
|
+
os.close(os.open(events_path + ".gate-plan-loaded", os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644))
|
|
253
|
+
except FileExistsError:
|
|
254
|
+
first = False
|
|
255
|
+
except OSError:
|
|
256
|
+
pass
|
|
257
|
+
if first:
|
|
258
|
+
lines += chaos_event(plan, "plan_loaded", [("faults", len(plan["faults"]))], now)
|
|
259
|
+
lines += chaos_event(plan, "gate_decision", [
|
|
260
|
+
("tool", call["tool"]),
|
|
261
|
+
("decision", call["decision"]),
|
|
262
|
+
("ruleId", call.get("ruleId") or None),
|
|
263
|
+
("destructive", bool(call.get("destructive"))),
|
|
264
|
+
("policyHit", bool(call.get("policyHit"))),
|
|
265
|
+
], now)
|
|
266
|
+
fault = None
|
|
267
|
+
if call["decision"] == "allow":
|
|
268
|
+
directory = events_path + ".gate-counters"
|
|
269
|
+
key = re.sub(r"[^0-9A-Za-z]", "", str(call.get("key") or ""))[:128] or "call"
|
|
270
|
+
now_ms = _chaos_ms(now)
|
|
271
|
+
tag = " [" + plan["canary"] + "]"
|
|
272
|
+
held = "Permission held for approval; retrying this exact call passes once it is approved" + tag
|
|
273
|
+
# The retry of a held call: still held until the delay has passed,
|
|
274
|
+
# then let through or denied by the one retry that releases it.
|
|
275
|
+
retry = False
|
|
276
|
+
for f in plan["faults"]:
|
|
277
|
+
if f["id"] != "permission.deny_or_delay" or f["mode"] == "deny" or not chaos_matches(f["match"], call["tool"]):
|
|
278
|
+
continue
|
|
279
|
+
open_hold = chaos_open_hold(directory, f["index"], key)
|
|
280
|
+
if open_hold is None:
|
|
281
|
+
continue
|
|
282
|
+
retry = True
|
|
283
|
+
if f["delay_s"] > 0 and now_ms - open_hold[1] < f["delay_s"] * 1000:
|
|
284
|
+
fault = {"faultId": f["id"], "kind": "hold", "reason": held}
|
|
285
|
+
elif chaos_release(directory, f["index"], key, open_hold[0]):
|
|
286
|
+
if f["mode"] == "hold_then_deny":
|
|
287
|
+
fault = {"faultId": f["id"], "kind": "deny",
|
|
288
|
+
"reason": "Permission held for approval, then denied by approver" + tag}
|
|
289
|
+
else:
|
|
290
|
+
# Another gate released it first: this call is a new one.
|
|
291
|
+
retry = False
|
|
292
|
+
continue
|
|
293
|
+
break
|
|
294
|
+
for f in plan["faults"] if not retry else ():
|
|
295
|
+
if not chaos_matches(f["match"], call["tool"]):
|
|
296
|
+
continue
|
|
297
|
+
# An MCP tool's error is the MCP proxy's to inject; a gate injects the built-in side.
|
|
298
|
+
if f["id"] == "tool.error" and call["tool"].startswith("mcp__"):
|
|
299
|
+
continue
|
|
300
|
+
seen = chaos_claim(directory, str(f["index"]) + ".seen.", None)
|
|
301
|
+
if fault is not None or seen < 1 or seen <= f["after_calls"]:
|
|
302
|
+
continue
|
|
303
|
+
if f["times"] is not None and chaos_claim(directory, str(f["index"]) + ".hit.", f["times"]) < 1:
|
|
304
|
+
continue
|
|
305
|
+
if f["id"] == "tool.error":
|
|
306
|
+
fault = {"faultId": f["id"], "kind": "deny", "reason": f["message"] + tag}
|
|
307
|
+
elif f["mode"] == "deny":
|
|
308
|
+
fault = {"faultId": f["id"], "kind": "deny", "reason": "Permission denied by approver" + tag}
|
|
309
|
+
else:
|
|
310
|
+
# Held from now: the hold's file is what its retries find.
|
|
311
|
+
if chaos_claim(directory, str(f["index"]) + ".held." + key + ".", None) < 1:
|
|
312
|
+
continue
|
|
313
|
+
fault = {"faultId": f["id"], "kind": "hold", "reason": held}
|
|
314
|
+
lines += chaos_event(plan, "fault_injected", [("faultId", f["id"]), ("call", seen), ("target", call["tool"])], now)
|
|
315
|
+
if fault is None or fault["kind"] == "hold":
|
|
316
|
+
lines += chaos_event(plan, "tool_call", [("tool", call["tool"]), ("ok", fault is None)], now)
|
|
317
|
+
chaos_append(events_path, lines)
|
|
318
|
+
return fault
|
|
319
|
+
`;
|
|
320
|
+
//# sourceMappingURL=chaosPy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chaosPy.js","sourceRoot":"","sources":["../../src/lib/chaosPy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqTxC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decisionsDigest.d.ts","sourceRoot":"","sources":["../../src/lib/decisionsDigest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAKH,OAAO,EAAE,WAAW,EAAkC,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"decisionsDigest.d.ts","sourceRoot":"","sources":["../../src/lib/decisionsDigest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAKH,OAAO,EAAE,WAAW,EAAkC,MAAM,uBAAuB,CAAA;AAWnF,sCAAsC;AACtC,eAAO,MAAM,2BAA2B,QAAwC,CAAA;AAEhF,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,sDAAsD,CAAA;AAExF,2IAA2I;AAC3I,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,oBAAoB,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,uGAAuG;IACvG,SAAS,EAAE,WAAW,EAAE,CAAA;CACzB;AAyBD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,CAAC,sBAAsB,EAAE,iBAAiB,GAAG,QAAQ,GAAG,aAAa,CAAC,GAC/E,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CA0BzC;AAkBD,0EAA0E;AAC1E,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAO/E;AAED,yFAAyF;AACzF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,KAAK,SAAK,GAAG,MAAM,CAO9F;AAgBD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BjI;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB/E;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAe5C"}
|
|
@@ -65,6 +65,7 @@ import { claudeCodeReadsAgentsMd } from '../harness/claudeAgentsMd.js';
|
|
|
65
65
|
import { openclawAgentWorkspace } from '../harness/openclawHooks.js';
|
|
66
66
|
import { ensureAiderReadEntry } from '../harness/aiderConfigMerger.js';
|
|
67
67
|
import { forgetOriginal, readOriginal, writeOwnedFile } from '../disconnect/originals.js';
|
|
68
|
+
import { writeFileAtomic } from './atomicWrite.js';
|
|
68
69
|
const log = createLogger('sync-decisions-digest');
|
|
69
70
|
/** Relative to the workspace root. */
|
|
70
71
|
export const DECISIONS_LOG_RELATIVE_PATH = path.join('.intutic', 'DECISIONS.md');
|
|
@@ -224,11 +225,7 @@ export async function retireClaudeMdDigest(workspaceRoot) {
|
|
|
224
225
|
log.info({ action: 'decisions_claude_md_removed', path: file }, 'Removed the CLAUDE.md an earlier version created for the decisions log');
|
|
225
226
|
return;
|
|
226
227
|
}
|
|
227
|
-
|
|
228
|
-
const tmp = `${file}.intutic-tmp`;
|
|
229
|
-
await fs.writeFile(tmp, next, 'utf-8');
|
|
230
|
-
await fs.chmod(tmp, mode);
|
|
231
|
-
await fs.rename(tmp, file);
|
|
228
|
+
await writeFileAtomic(file, next);
|
|
232
229
|
log.info({ action: 'decisions_claude_md_section_removed', path: file }, 'Took the decisions-log section out of CLAUDE.md');
|
|
233
230
|
}
|
|
234
231
|
await retireRulesFile(file, workspaceRoot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decisionsDigest.js","sourceRoot":"","sources":["../../src/lib/decisionsDigest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AACtH,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"decisionsDigest.js","sourceRoot":"","sources":["../../src/lib/decisionsDigest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AACtH,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAAA;AAEjD,sCAAsC;AACtC,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;AAEhF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,qBAAqB,GAAG,mDAAmD,CAAA;AAwBxF;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,CAAS;IACpC,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,CAAA;IAClB,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS;QAAE,GAAG,EAAE,CAAA;IAC/D,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,MAAM,CAAC,GAAG,KAAgC,CAAA;IAC1C,OAAO,CACL,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ;QACxB,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;QAC1B,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;QAC/B,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAC9B,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAgF;IAEhF,MAAM,GAAG,GACP,GAAG,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,oCAAoC;QAChF,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAA;IACxD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,IAAI,CAAC,WAAW,EAAE;YACvF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,GAAG,CAAC,IAAI,CACN,EAAE,MAAM,EAAE,+BAA+B,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAC/D,kCAAkC,CACnC,CAAA;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAY,CAAA;QAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QAC1D,MAAM,GAAG,GAAG,IAA+B,CAAA;QAC3C,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAA;QAC5F,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACnF,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAA;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,+BAA+B,EAAE,GAAG,EAAE,EAAE,8BAA8B,CAAC,CAAA;QAC1F,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,+FAA+F;AAC/F,SAAS,YAAY,CAAC,OAA+B;IACnD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,OAAO,CAAA;IAC/C,OAAO;QACL,mDAAmD;QACnD,gDAAgD;QAChD,wBAAwB,MAAM,EAAE;QAChC,GAAG;QACH,sEAAsE;QACtE,yEAAyE;QACzE,yCAAyC;QACzC,EAAE;QACF,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,uBAAuB,CAAC,OAA+B;IACrE,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,MAAM,2CAA2C,CAAA;IAC7D,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACnE,OAAO,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AACzC,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,0BAA0B,CAAC,OAA+B,EAAE,KAAK,GAAG,EAAE;IACpF,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACvC,MAAM,KAAK,GACT,OAAO,CAAC,MAAM,GAAG,CAAC;QAChB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAA;IACjD,OAAO,CAAC,8BAA8B,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAClE,CAAC;AAED,uFAAuF;AACvF,SAAS,mBAAmB,CAAC,IAAY,EAAE,WAAmB;IAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,WAAW,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9D,OAAO,GAAG,IAAI,GAAG,qBAAqB,uDAAuD,IAAI,IAAI,CAAA;AACvG,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAY;IAClC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,aAAqB,EAAE,SAAiC,EAAE,IAAY;IAChH,MAAM,kBAAkB,GACtB,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC;QAC3C,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC;QACrD,CAAC,MAAM,uBAAuB,CAAC,aAAa,CAAC,CAAC,CAAA;IAChD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;QACzC,IAAI,CAAC,MAAM;YAAE,SAAQ;QACrB,MAAM,IAAI,GACR,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM;YAClD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,sBAAsB,EAAE,EAAE,WAAW,CAAC;YACxD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAC3C,IAAI,OAAO,KAAK,WAAW,CAAC,WAAW,IAAI,kBAAkB,EAAE,CAAC;YAC9D,MAAM,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YAC1C,SAAQ;QACV,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC/B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjB,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAA;YACrE,SAAQ;QACV,CAAC;QACD,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,gCAAgC,CAAC,IAAI,EAAE,CAAC,CAAA;QACvG,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,OAAO;YAAE,MAAM,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,CAAA;QAC1F,4CAA4C;QAC5C,IAAI,OAAO,KAAK,WAAW,CAAC,KAAK;YAAE,MAAM,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,EAAE,IAAI,CAAC,CAAA;IAClH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,aAAqB;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAM;IACzB,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IACxD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QACtD,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpD,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;YAClC,MAAM,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YACzC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,6BAA6B,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,wEAAwE,CAAC,CAAA;YACzI,OAAM;QACR,CAAC;QACD,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACjC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,qCAAqC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,iDAAiD,CAAC,CAAA;IAC5H,CAAC;IACD,MAAM,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAA4B;IAE5B,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAC/C,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAEhC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,2BAA2B,CAAC,CAAA;QAC3E,MAAM,WAAW,CAAC,QAAQ,EAAE,uBAAuB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;QAEpE,MAAM,qBAAqB,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,EAAE,0BAA0B,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QAE/G,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAA;IAClD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,+BAA+B,EAAE,GAAG,EAAE,EAAE,qCAAqC,CAAC,CAAA;QACjG,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"egressPolicy.d.ts","sourceRoot":"","sources":["../../src/lib/egressPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;
|
|
1
|
+
{"version":3,"file":"egressPolicy.d.ts","sourceRoot":"","sources":["../../src/lib/egressPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,eAAO,MAAM,wBAAwB,QAA+C,CAAA;AACpF,eAAO,MAAM,kBAAkB,uBAAuB,CAAA;AAEtD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAA;AAEtD,wFAAwF;AACxF,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;IACvB,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAaD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAElF;AAED;;0DAE0D;AAC1D,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CA0BvC;AAED;;yCAEyC;AACzC,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,qBAAqB,EAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,GAAE,MAAiC,GAC1C,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;CAAE,CAAC,CAoBtD;AAED;;sBAEsB;AACtB,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAAC,CAS7D"}
|
package/dist/lib/egressPolicy.js
CHANGED
|
@@ -30,6 +30,7 @@ import * as path from 'node:path';
|
|
|
30
30
|
import * as os from 'node:os';
|
|
31
31
|
import { createHash } from 'node:crypto';
|
|
32
32
|
import { createLogger } from '@intutic/logger';
|
|
33
|
+
import { writeFileAtomic } from './atomicWrite.js';
|
|
33
34
|
const log = createLogger('sync-egress-policy');
|
|
34
35
|
export const DEFAULT_EGRESS_CACHE_DIR = path.join(os.homedir(), '.intutic', 'hooks');
|
|
35
36
|
export const EGRESS_POLICY_FILE = 'egress-policy.json';
|
|
@@ -101,10 +102,7 @@ export async function writeEgressPolicy(policy, workspaceId, cacheDir = DEFAULT_
|
|
|
101
102
|
const text = JSON.stringify(doc, null, 2) + '\n';
|
|
102
103
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
103
104
|
const target = path.join(cacheDir, EGRESS_POLICY_FILE);
|
|
104
|
-
|
|
105
|
-
await fs.writeFile(tmp, text, { encoding: 'utf-8' });
|
|
106
|
-
await fs.chmod(tmp, 0o444);
|
|
107
|
-
await fs.rename(tmp, target);
|
|
105
|
+
await writeFileAtomic(target, text, { mode: 0o444 });
|
|
108
106
|
log.debug({ action: 'egress_policy_written', digest, mode: policy.mode, count: policy.allow.length, dir: cacheDir }, 'Egress policy cache refreshed');
|
|
109
107
|
return { digest, mode: policy.mode };
|
|
110
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"egressPolicy.js","sourceRoot":"","sources":["../../src/lib/egressPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"egressPolicy.js","sourceRoot":"","sources":["../../src/lib/egressPolicy.ts"],"names":[],"mappings":"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"}
|
|
@@ -79,7 +79,7 @@ export declare function snapshotRulesVerify(text: string): boolean;
|
|
|
79
79
|
/**
|
|
80
80
|
* Whether the destructive tier ships as `block` or as `warn`.
|
|
81
81
|
*
|
|
82
|
-
* `warn`. These
|
|
82
|
+
* `warn`. These eight patterns qualify for `block` on the merits — every one is
|
|
83
83
|
* unrecoverable without a reinstall or a backup — but they have never run
|
|
84
84
|
* against real developer traffic, and they would land on thirteen harnesses at
|
|
85
85
|
* once. A false positive here does not merely annoy: the fastest workaround
|
|
@@ -103,7 +103,7 @@ export declare const DESTRUCTIVE_TIER_SEVERITY: 'block' | 'warn';
|
|
|
103
103
|
*
|
|
104
104
|
* `block` — deliberately not following `DESTRUCTIVE_TIER_SEVERITY`'s warn-first
|
|
105
105
|
* ramp, because the thing that ramp is buying time for does not exist on this
|
|
106
|
-
* surface. `DESTRUCTIVE_COMMAND_PATTERNS` rides at `warn` because those
|
|
106
|
+
* surface. `DESTRUCTIVE_COMMAND_PATTERNS` rides at `warn` because those eight
|
|
107
107
|
* families are unmeasured against real developer traffic and a false positive
|
|
108
108
|
* has a real cost (see that constant's own comment). `SKILL_SURFACE_PATTERNS`
|
|
109
109
|
* is not that kind of rule: it does not run `scanSkillContent` or judge
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policySnapshot.d.ts","sourceRoot":"","sources":["../../src/lib/policySnapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAOH,OAAO,
|
|
1
|
+
{"version":3,"file":"policySnapshot.d.ts","sourceRoot":"","sources":["../../src/lib/policySnapshot.ts"],"names":[],"mappings":"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"}
|