@corenel/harness 0.10.0 → 0.11.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/approvals/decisionLog.d.ts +21 -0
- package/dist/approvals/decisionLog.d.ts.map +1 -0
- package/dist/approvals/decisionLog.js +129 -0
- package/dist/approvals/decisionLog.js.map +1 -0
- package/dist/approvals/hooks.d.ts +18 -0
- package/dist/approvals/hooks.d.ts.map +1 -0
- package/dist/approvals/hooks.js +34 -0
- package/dist/approvals/hooks.js.map +1 -0
- package/dist/approvals/index.d.ts +10 -0
- package/dist/approvals/index.d.ts.map +1 -0
- package/dist/approvals/index.js +10 -0
- package/dist/approvals/index.js.map +1 -0
- package/dist/approvals/service.d.ts +46 -0
- package/dist/approvals/service.d.ts.map +1 -0
- package/dist/approvals/service.js +181 -0
- package/dist/approvals/service.js.map +1 -0
- package/dist/approvals/settings.d.ts +20 -0
- package/dist/approvals/settings.d.ts.map +1 -0
- package/dist/approvals/settings.js +32 -0
- package/dist/approvals/settings.js.map +1 -0
- package/dist/approvals/shellTools.d.ts +10 -0
- package/dist/approvals/shellTools.d.ts.map +1 -0
- package/dist/approvals/shellTools.js +17 -0
- package/dist/approvals/shellTools.js.map +1 -0
- package/dist/approvals/standingStore.d.ts +15 -0
- package/dist/approvals/standingStore.d.ts.map +1 -0
- package/dist/approvals/standingStore.js +50 -0
- package/dist/approvals/standingStore.js.map +1 -0
- package/dist/approvals/suggest.d.ts +15 -0
- package/dist/approvals/suggest.d.ts.map +1 -0
- package/dist/approvals/suggest.js +23 -0
- package/dist/approvals/suggest.js.map +1 -0
- package/dist/approvals/summarize.d.ts +7 -0
- package/dist/approvals/summarize.d.ts.map +1 -0
- package/dist/approvals/summarize.js +70 -0
- package/dist/approvals/summarize.js.map +1 -0
- package/dist/approvals/testTextStore.d.ts +6 -0
- package/dist/approvals/testTextStore.d.ts.map +1 -0
- package/dist/approvals/testTextStore.js +11 -0
- package/dist/approvals/testTextStore.js.map +1 -0
- package/dist/approvals/textStore.d.ts +9 -0
- package/dist/approvals/textStore.d.ts.map +1 -0
- package/dist/approvals/textStore.js +2 -0
- package/dist/approvals/textStore.js.map +1 -0
- package/dist/audit/canonical.d.ts +5 -0
- package/dist/audit/canonical.d.ts.map +1 -0
- package/dist/audit/canonical.js +15 -0
- package/dist/audit/canonical.js.map +1 -0
- package/dist/audit/ids.d.ts +3 -0
- package/dist/audit/ids.d.ts.map +1 -0
- package/dist/audit/ids.js +11 -0
- package/dist/audit/ids.js.map +1 -0
- package/dist/audit/index.d.ts +7 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +7 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/log.d.ts +64 -0
- package/dist/audit/log.d.ts.map +1 -0
- package/dist/audit/log.js +457 -0
- package/dist/audit/log.js.map +1 -0
- package/dist/audit/recorder.d.ts +31 -0
- package/dist/audit/recorder.d.ts.map +1 -0
- package/dist/audit/recorder.js +185 -0
- package/dist/audit/recorder.js.map +1 -0
- package/dist/audit/runAudit.d.ts +38 -0
- package/dist/audit/runAudit.d.ts.map +1 -0
- package/dist/audit/runAudit.js +99 -0
- package/dist/audit/runAudit.js.map +1 -0
- package/dist/audit/verify.d.ts +14 -0
- package/dist/audit/verify.d.ts.map +1 -0
- package/dist/audit/verify.js +47 -0
- package/dist/audit/verify.js.map +1 -0
- package/dist/conversation.d.ts +31 -0
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +33 -0
- package/dist/conversation.js.map +1 -1
- package/dist/core/hash.d.ts +2 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +9 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/loop.d.ts +18 -0
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +61 -5
- package/dist/core/loop.js.map +1 -1
- package/dist/core/spawn.d.ts +59 -4
- package/dist/core/spawn.d.ts.map +1 -1
- package/dist/core/spawn.js +83 -5
- package/dist/core/spawn.js.map +1 -1
- package/dist/core/turnVerify.d.ts +25 -0
- package/dist/core/turnVerify.d.ts.map +1 -0
- package/dist/core/turnVerify.js +177 -0
- package/dist/core/turnVerify.js.map +1 -0
- package/dist/dag/executeNode.d.ts +7 -0
- package/dist/dag/executeNode.d.ts.map +1 -1
- package/dist/dag/executeNode.js +3 -0
- package/dist/dag/executeNode.js.map +1 -1
- package/dist/guardrail/guardrail.d.ts +7 -0
- package/dist/guardrail/guardrail.d.ts.map +1 -1
- package/dist/guardrail/guardrail.js +8 -0
- package/dist/guardrail/guardrail.js.map +1 -1
- package/dist/guardrail/index.d.ts +2 -2
- package/dist/guardrail/index.d.ts.map +1 -1
- package/dist/guardrail/index.js +2 -2
- package/dist/guardrail/index.js.map +1 -1
- package/dist/guardrail/permission-service.d.ts +37 -6
- package/dist/guardrail/permission-service.d.ts.map +1 -1
- package/dist/guardrail/permission-service.js +111 -11
- package/dist/guardrail/permission-service.js.map +1 -1
- package/dist/guardrail/serialize.d.ts.map +1 -1
- package/dist/guardrail/serialize.js +2 -0
- package/dist/guardrail/serialize.js.map +1 -1
- package/dist/guardrail/validate.d.ts.map +1 -1
- package/dist/guardrail/validate.js +3 -1
- package/dist/guardrail/validate.js.map +1 -1
- package/dist/install/lockfile.d.ts +13 -5
- package/dist/install/lockfile.d.ts.map +1 -1
- package/dist/install/lockfile.js +31 -2
- package/dist/install/lockfile.js.map +1 -1
- package/dist/orchestrator/agentSearch.d.ts +15 -0
- package/dist/orchestrator/agentSearch.d.ts.map +1 -0
- package/dist/orchestrator/agentSearch.js +102 -0
- package/dist/orchestrator/agentSearch.js.map +1 -0
- package/dist/orchestrator/agentTags.d.ts +13 -0
- package/dist/orchestrator/agentTags.d.ts.map +1 -0
- package/dist/orchestrator/agentTags.js +48 -0
- package/dist/orchestrator/agentTags.js.map +1 -0
- package/dist/orchestrator/branch.d.ts +9 -0
- package/dist/orchestrator/branch.d.ts.map +1 -0
- package/dist/orchestrator/branch.js +26 -0
- package/dist/orchestrator/branch.js.map +1 -0
- package/dist/orchestrator/checks.d.ts +16 -0
- package/dist/orchestrator/checks.d.ts.map +1 -0
- package/dist/orchestrator/checks.js +66 -0
- package/dist/orchestrator/checks.js.map +1 -0
- package/dist/orchestrator/planDoc.d.ts +15 -0
- package/dist/orchestrator/planDoc.d.ts.map +1 -0
- package/dist/orchestrator/planDoc.js +59 -0
- package/dist/orchestrator/planDoc.js.map +1 -0
- package/dist/orchestrator/record.d.ts +103 -0
- package/dist/orchestrator/record.d.ts.map +1 -0
- package/dist/orchestrator/record.js +168 -0
- package/dist/orchestrator/record.js.map +1 -0
- package/dist/orchestrator/sidecarTools.d.ts +7 -0
- package/dist/orchestrator/sidecarTools.d.ts.map +1 -0
- package/dist/orchestrator/sidecarTools.js +141 -0
- package/dist/orchestrator/sidecarTools.js.map +1 -0
- package/dist/prompts/config.d.ts.map +1 -1
- package/dist/prompts/config.js +11 -0
- package/dist/prompts/config.js.map +1 -1
- package/dist/prompts/index.d.ts +0 -6
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +10 -17
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/library/defaults.generated.d.ts.map +1 -1
- package/dist/prompts/library/defaults.generated.js +29 -12
- package/dist/prompts/library/defaults.generated.js.map +1 -1
- package/dist/redact.d.ts.map +1 -1
- package/dist/redact.js +1 -0
- package/dist/redact.js.map +1 -1
- package/dist/rooms/findings.d.ts +14 -0
- package/dist/rooms/findings.d.ts.map +1 -1
- package/dist/rooms/findings.js +37 -0
- package/dist/rooms/findings.js.map +1 -1
- package/dist/sessions/blobGc.d.ts.map +1 -1
- package/dist/sessions/blobGc.js +2 -5
- package/dist/sessions/blobGc.js.map +1 -1
- package/dist/sessions/childSessions.d.ts +12 -0
- package/dist/sessions/childSessions.d.ts.map +1 -0
- package/dist/sessions/childSessions.js +43 -0
- package/dist/sessions/childSessions.js.map +1 -0
- package/dist/sessions/fileRecallStore.d.ts.map +1 -1
- package/dist/sessions/fileRecallStore.js +1 -3
- package/dist/sessions/fileRecallStore.js.map +1 -1
- package/dist/sessions/fileSessionStore.d.ts +11 -7
- package/dist/sessions/fileSessionStore.d.ts.map +1 -1
- package/dist/sessions/fileSessionStore.js +27 -16
- package/dist/sessions/fileSessionStore.js.map +1 -1
- package/dist/sessions/inflight.js +0 -0
- package/dist/sessions/inflight.js.map +1 -1
- package/dist/sessions/jsonl.d.ts +4 -0
- package/dist/sessions/jsonl.d.ts.map +1 -1
- package/dist/sessions/jsonl.js +1 -0
- package/dist/sessions/jsonl.js.map +1 -1
- package/dist/sessions/testFs.d.ts.map +1 -1
- package/dist/sessions/testFs.js +1 -1
- package/dist/sessions/testFs.js.map +1 -1
- package/dist/sidecar/host.d.ts +178 -1
- package/dist/sidecar/host.d.ts.map +1 -1
- package/dist/sidecar/host.js +363 -3
- package/dist/sidecar/host.js.map +1 -1
- package/dist/sidecar/identity.d.ts +44 -0
- package/dist/sidecar/identity.d.ts.map +1 -0
- package/dist/sidecar/identity.js +45 -0
- package/dist/sidecar/identity.js.map +1 -0
- package/dist/sidecar/server.d.ts +245 -2
- package/dist/sidecar/server.d.ts.map +1 -1
- package/dist/sidecar/server.js +833 -45
- package/dist/sidecar/server.js.map +1 -1
- package/dist/skillSource.js +1 -1
- package/dist/skillSource.js.map +1 -1
- package/dist/skills.d.ts +23 -7
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +62 -37
- package/dist/skills.js.map +1 -1
- package/dist/tools/callAgent.d.ts +29 -12
- package/dist/tools/callAgent.d.ts.map +1 -1
- package/dist/tools/callAgent.js +120 -14
- package/dist/tools/callAgent.js.map +1 -1
- package/dist/tools/crewList.d.ts +33 -0
- package/dist/tools/crewList.d.ts.map +1 -0
- package/dist/tools/crewList.js +66 -0
- package/dist/tools/crewList.js.map +1 -0
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +11 -5
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/findAgent.d.ts +23 -0
- package/dist/tools/findAgent.d.ts.map +1 -0
- package/dist/tools/findAgent.js +58 -0
- package/dist/tools/findAgent.js.map +1 -0
- package/dist/tools/namespaces.d.ts.map +1 -1
- package/dist/tools/namespaces.js +7 -0
- package/dist/tools/namespaces.js.map +1 -1
- package/dist/tools/orchestrate.d.ts +4 -0
- package/dist/tools/orchestrate.d.ts.map +1 -0
- package/dist/tools/orchestrate.js +38 -0
- package/dist/tools/orchestrate.js.map +1 -0
- package/dist/tools/orchestration.d.ts +24 -0
- package/dist/tools/orchestration.d.ts.map +1 -0
- package/dist/tools/orchestration.js +173 -0
- package/dist/tools/orchestration.js.map +1 -0
- package/dist/tools/orchestrationSet.d.ts +6 -0
- package/dist/tools/orchestrationSet.d.ts.map +1 -0
- package/dist/tools/orchestrationSet.js +12 -0
- package/dist/tools/orchestrationSet.js.map +1 -0
- package/dist/tools/roomTools.d.ts +6 -0
- package/dist/tools/roomTools.d.ts.map +1 -1
- package/dist/tools/roomTools.js +26 -2
- package/dist/tools/roomTools.js.map +1 -1
- package/dist/tools/skillTool.d.ts +15 -0
- package/dist/tools/skillTool.d.ts.map +1 -0
- package/dist/tools/skillTool.js +39 -0
- package/dist/tools/skillTool.js.map +1 -0
- package/dist/tools/urlGuard.d.ts +7 -0
- package/dist/tools/urlGuard.d.ts.map +1 -1
- package/dist/tools/urlGuard.js +54 -18
- package/dist/tools/urlGuard.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { flattenFiles } from '@corenel/protocol';
|
|
2
|
+
import { sha256Hex } from '../core/hash.js';
|
|
3
|
+
import { newSpanId } from './ids.js';
|
|
4
|
+
export const AUDIT_SEGMENT_LINES = 1000;
|
|
5
|
+
export const AUDIT_RETENTION_DAYS = 180;
|
|
6
|
+
export const AUDIT_GENESIS = 'sha256:genesis';
|
|
7
|
+
const DAY = 86400000;
|
|
8
|
+
const ZERO_TRACE = '0'.repeat(32);
|
|
9
|
+
/** A writerId becomes part of file names, so it is limited to letters,
|
|
10
|
+
* digits and `_`: no `-` (names are split on it), no path characters. */
|
|
11
|
+
const WRITER_ID = /^[A-Za-z0-9_]{1,64}$/;
|
|
12
|
+
/** `audit-<host>` or `audit-<host>-<writerId>`: the name prefix of one file set. */
|
|
13
|
+
function auditStem(host, writerId) {
|
|
14
|
+
if (writerId === undefined)
|
|
15
|
+
return `audit-${host}`;
|
|
16
|
+
if (!WRITER_ID.test(writerId))
|
|
17
|
+
throw new Error(`audit: invalid writerId ${JSON.stringify(writerId)}`);
|
|
18
|
+
return `audit-${host}-${writerId}`;
|
|
19
|
+
}
|
|
20
|
+
export function activeSegmentName(host, writerId) {
|
|
21
|
+
return `${auditStem(host, writerId)}.jsonl`;
|
|
22
|
+
}
|
|
23
|
+
/** The files of `host` that belong to a writer OTHER than `ownWriterId`: every
|
|
24
|
+
* `audit-<host>-<writerId>.jsonl` active segment and
|
|
25
|
+
* `audit-<host>-<writerId>-<yyyymmdd>-<n>.jsonl` archive whose writerId
|
|
26
|
+
* differs. Files without a writerId (the daemon's) and other hosts' files
|
|
27
|
+
* never match: a writerless archive `audit-<host>-<date>-<n>.jsonl` has no
|
|
28
|
+
* way to fit `<writerId>` (no `-`) followed by `.jsonl` or a full
|
|
29
|
+
* `-<8 digits>-<n>` suffix. `date` is set for an archive, absent for an active segment. */
|
|
30
|
+
export function foreignWriterFiles(names, host, ownWriterId) {
|
|
31
|
+
const re = new RegExp(`^audit-${host}-([A-Za-z0-9_]{1,64})(?:-(\\d{8})-\\d+)?\\.jsonl$`);
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const name of names) {
|
|
34
|
+
const m = re.exec(name);
|
|
35
|
+
if (!m || m[1] === ownWriterId)
|
|
36
|
+
continue;
|
|
37
|
+
out.push(m[2] ? { name, date: m[2] } : { name });
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/** The archived segments of one file set (`host`, plus `writerId` when set)
|
|
42
|
+
* among `names` (basenames), oldest first by (date, n). Shared with the
|
|
43
|
+
* verifier so both walk the same order. Without a writerId only the host's
|
|
44
|
+
* own archives match: a writerId holds no `-` and a date is exactly 8 digits
|
|
45
|
+
* then `-`, so `audit-<host>-<writerId>-...` never parses as
|
|
46
|
+
* `audit-<host>-<date>-<n>`. */
|
|
47
|
+
export function sortedAuditArchives(names, host, writerId) {
|
|
48
|
+
const re = new RegExp(`^${auditStem(host, writerId)}-(\\d{8})-(\\d+)\\.jsonl$`);
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const name of names) {
|
|
51
|
+
const m = re.exec(name);
|
|
52
|
+
if (m)
|
|
53
|
+
out.push({ name, date: m[1], n: Number(m[2]) });
|
|
54
|
+
}
|
|
55
|
+
return out.sort((a, b) => (a.date === b.date ? a.n - b.n : a.date < b.date ? -1 : 1));
|
|
56
|
+
}
|
|
57
|
+
/** Basenames of every file under `root` (as decisionLog does, via flattenFiles). */
|
|
58
|
+
export function auditFileNames(nodes) {
|
|
59
|
+
return flattenFiles(nodes).map((n) => n.path.split('/').pop() ?? '');
|
|
60
|
+
}
|
|
61
|
+
/** The non-empty lines of a segment's text, without their newlines. */
|
|
62
|
+
export function segmentLines(text) {
|
|
63
|
+
return text.split('\n').filter((l) => l.length > 0);
|
|
64
|
+
}
|
|
65
|
+
export async function lineHash(line) {
|
|
66
|
+
return 'sha256:' + (await sha256Hex(line + '\n'));
|
|
67
|
+
}
|
|
68
|
+
/** Last retention run per file set (`root`+`host`+`writerId`): retention runs
|
|
69
|
+
* at most once a day per log, however many log instances a process creates. */
|
|
70
|
+
const retentionRuns = new Map();
|
|
71
|
+
/** Test-only: forget every retention run so each test starts independent. */
|
|
72
|
+
export function __resetAuditRetentionForTest() {
|
|
73
|
+
retentionRuns.clear();
|
|
74
|
+
}
|
|
75
|
+
function parseLine(line) {
|
|
76
|
+
try {
|
|
77
|
+
const v = JSON.parse(line);
|
|
78
|
+
return v && typeof v === 'object' && !Array.isArray(v) ? v : null;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** `event` of the newest `kind: 'audit'` line in `lines`, or null. */
|
|
85
|
+
function newestAuditEvent(lines) {
|
|
86
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
87
|
+
const v = parseLine(lines[i]);
|
|
88
|
+
if (v?.kind === 'audit' && typeof v.event === 'string')
|
|
89
|
+
return v.event;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
/** Epoch ms of the newest line's `ts`, or NaN when it cannot be dated. */
|
|
94
|
+
function newestTs(lines) {
|
|
95
|
+
return Date.parse(String(parseLine(lines[lines.length - 1] ?? '')?.ts ?? ''));
|
|
96
|
+
}
|
|
97
|
+
const utcDate = (ms) => new Date(ms).toISOString().slice(0, 10).replace(/-/g, '');
|
|
98
|
+
async function readOrNull(fs, path) {
|
|
99
|
+
try {
|
|
100
|
+
return await fs.read(path);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export function createAuditLog(opts) {
|
|
107
|
+
const requested = opts.segmentLines ?? AUDIT_SEGMENT_LINES;
|
|
108
|
+
const maxLines = Number.isFinite(requested) ? Math.max(1, Math.floor(requested)) : AUDIT_SEGMENT_LINES;
|
|
109
|
+
const retentionDays = opts.retentionDays ?? AUDIT_RETENTION_DAYS;
|
|
110
|
+
const flushMs = opts.flushMs ?? 1000;
|
|
111
|
+
const flushAt = opts.flushAt ?? 50;
|
|
112
|
+
const now = opts.now ?? (() => Date.now());
|
|
113
|
+
const host = opts.host;
|
|
114
|
+
const writerId = opts.writerId;
|
|
115
|
+
const stem = auditStem(host, writerId);
|
|
116
|
+
const activeName = activeSegmentName(host, writerId);
|
|
117
|
+
const activePath = `${opts.root}/${activeName}`;
|
|
118
|
+
const retentionKey = `${opts.root}|${host}|${writerId ?? ''}`;
|
|
119
|
+
/** Resolve `enabled` live: a plain boolean is fixed, a callback is called
|
|
120
|
+
* fresh on every check (see AuditLogOptions.enabled). The ONE guarded read
|
|
121
|
+
* site for `opts.enabled` -- append(), flush() and writeBatch() all go
|
|
122
|
+
* through this, so a callback that throws can never escape as an unhandled
|
|
123
|
+
* exception (flush() would otherwise reject) or an unhandled rejection.
|
|
124
|
+
* Fails toward ENABLED: a broken settings read must not silently turn
|
|
125
|
+
* auditing off. */
|
|
126
|
+
const isEnabled = () => {
|
|
127
|
+
try {
|
|
128
|
+
return typeof opts.enabled === 'function' ? opts.enabled() : opts.enabled;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
let queue = [];
|
|
135
|
+
let timer = null;
|
|
136
|
+
let chain = Promise.resolve();
|
|
137
|
+
/* Disk-confirmed state, loaded lazily and reloaded when another writer
|
|
138
|
+
* changed the active file. Only advanced after a write lands. */
|
|
139
|
+
let loaded = false;
|
|
140
|
+
/** The active file's exact bytes as last read or written; null = absent. */
|
|
141
|
+
let diskText = null;
|
|
142
|
+
/** What the next active write starts from: diskText with a torn tail
|
|
143
|
+
* newline-terminated and any prefix already archived dropped. */
|
|
144
|
+
let activeText = '';
|
|
145
|
+
let activeCount = 0;
|
|
146
|
+
let lastHash = AUDIT_GENESIS;
|
|
147
|
+
let lastAuditEvent = null;
|
|
148
|
+
let lostCount = 0;
|
|
149
|
+
let pendingGap = 0;
|
|
150
|
+
let gapSince = null;
|
|
151
|
+
const isoNow = () => new Date(now()).toISOString();
|
|
152
|
+
const pointLine = (extra) => ({
|
|
153
|
+
v: 1, ts: isoNow(), trace: ZERO_TRACE, span: newSpanId(), phase: 'point', host, kind: 'audit', ...extra,
|
|
154
|
+
});
|
|
155
|
+
async function listNames(fs) {
|
|
156
|
+
try {
|
|
157
|
+
return auditFileNames(await fs.list(opts.root));
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** Throws when the state cannot be known: guessing "empty" would restart
|
|
164
|
+
* the chain at genesis over data that is really there. */
|
|
165
|
+
async function ensureLoaded(fs) {
|
|
166
|
+
if (loaded)
|
|
167
|
+
return;
|
|
168
|
+
const names = await listNames(fs);
|
|
169
|
+
let disk;
|
|
170
|
+
try {
|
|
171
|
+
disk = await fs.read(activePath);
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
// Absent only when the read fails AND a successful listing agrees.
|
|
175
|
+
if (names === null || names.includes(activeName))
|
|
176
|
+
throw e;
|
|
177
|
+
disk = null;
|
|
178
|
+
}
|
|
179
|
+
let text = disk ?? '';
|
|
180
|
+
// A torn tail stays as data (the verifier reports it) but is terminated,
|
|
181
|
+
// so the next line is never concatenated onto it.
|
|
182
|
+
if (text.length && !text.endsWith('\n'))
|
|
183
|
+
text += '\n';
|
|
184
|
+
let lines = segmentLines(text);
|
|
185
|
+
if (!lines.length && names === null)
|
|
186
|
+
throw new Error('audit: cannot list archives to find the last line');
|
|
187
|
+
const archives = sortedAuditArchives(names ?? [], host, writerId);
|
|
188
|
+
const newest = archives[archives.length - 1];
|
|
189
|
+
const archived = newest ? segmentLines(await fs.read(`${opts.root}/${newest.name}`)) : [];
|
|
190
|
+
// A rollover that archived these lines but died before rewriting the
|
|
191
|
+
// active file leaves them duplicated here: they are already archived.
|
|
192
|
+
if (lines.length && archived.length && lines[0] === archived[0]) {
|
|
193
|
+
let k = 0;
|
|
194
|
+
while (k < lines.length && k < archived.length && lines[k] === archived[k])
|
|
195
|
+
k++;
|
|
196
|
+
lines = lines.slice(k);
|
|
197
|
+
text = lines.map((l) => l + '\n').join('');
|
|
198
|
+
}
|
|
199
|
+
diskText = disk;
|
|
200
|
+
activeText = text;
|
|
201
|
+
activeCount = lines.length;
|
|
202
|
+
lastHash = lines.length
|
|
203
|
+
? await lineHash(lines[lines.length - 1])
|
|
204
|
+
: archived.length ? await lineHash(archived[archived.length - 1]) : AUDIT_GENESIS;
|
|
205
|
+
lastAuditEvent = newestAuditEvent(lines) ?? newestAuditEvent(archived);
|
|
206
|
+
loaded = true;
|
|
207
|
+
}
|
|
208
|
+
/** Another writer changed the active file since we last touched it: reload
|
|
209
|
+
* so the pending lines chain onto the true last line. */
|
|
210
|
+
async function ensureFresh(fs) {
|
|
211
|
+
if ((await readOrNull(fs, activePath)) === diskText)
|
|
212
|
+
return;
|
|
213
|
+
loaded = false;
|
|
214
|
+
await ensureLoaded(fs);
|
|
215
|
+
}
|
|
216
|
+
/** Delete archives older than the window, judged by the UTC date in their
|
|
217
|
+
* name (the date of their newest line): before the cutoff day -> delete
|
|
218
|
+
* unread; after it -> keep unread; on it -> read the newest line. Never
|
|
219
|
+
* this log's own active segment, never by count; at most once a day per
|
|
220
|
+
* file set, checked on every flush so a long-lived log keeps pruning.
|
|
221
|
+
*
|
|
222
|
+
* A log WITH a writerId also sweeps the same host's other writers' files
|
|
223
|
+
* (foreignWriterFiles): a writerId lives only as long as its page, so a
|
|
224
|
+
* closed page would otherwise never be pruned. Their archives follow the
|
|
225
|
+
* same rule; their active segment goes only when its newest line is older
|
|
226
|
+
* than the cutoff -- one that cannot be read or dated is kept. Another
|
|
227
|
+
* host's files, and writerless files, are never touched. */
|
|
228
|
+
async function retention(fs) {
|
|
229
|
+
const t = now();
|
|
230
|
+
const last = retentionRuns.get(retentionKey);
|
|
231
|
+
if (last !== undefined && t - last < DAY)
|
|
232
|
+
return;
|
|
233
|
+
retentionRuns.set(retentionKey, t);
|
|
234
|
+
const cutoff = t - retentionDays * DAY;
|
|
235
|
+
const cutoffDate = utcDate(cutoff);
|
|
236
|
+
const names = await listNames(fs);
|
|
237
|
+
if (!names)
|
|
238
|
+
return;
|
|
239
|
+
const expired = [...sortedAuditArchives(names, host, writerId)];
|
|
240
|
+
if (writerId !== undefined)
|
|
241
|
+
expired.push(...foreignWriterFiles(names, host, writerId));
|
|
242
|
+
for (const f of expired) {
|
|
243
|
+
if (f.date !== undefined && f.date > cutoffDate)
|
|
244
|
+
continue;
|
|
245
|
+
const path = `${opts.root}/${f.name}`;
|
|
246
|
+
try {
|
|
247
|
+
if (f.date !== undefined && f.date < cutoffDate) {
|
|
248
|
+
await fs.remove(path);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
// On the cutoff day, or an active segment (no date in its name).
|
|
252
|
+
const ts = newestTs(segmentLines(await fs.read(path)));
|
|
253
|
+
if (Number.isFinite(ts) && ts < cutoff)
|
|
254
|
+
await fs.remove(path);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
/* best effort: one file's failure does not stop the rest, and a
|
|
259
|
+
* file that cannot be read is kept */
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/** Archive `text` under `<stem>-<date>-<n>.jsonl`: the UTC date of
|
|
264
|
+
* its newest line, n = 1 + the highest listed n for that date, bumped past
|
|
265
|
+
* any name that already exists (a listing may omit it) -- never overwrites. */
|
|
266
|
+
async function createArchive(fs, text) {
|
|
267
|
+
const ts = newestTs(segmentLines(text));
|
|
268
|
+
const date = utcDate(Number.isFinite(ts) ? ts : now());
|
|
269
|
+
let n = 0;
|
|
270
|
+
for (const a of sortedAuditArchives((await listNames(fs)) ?? [], host, writerId))
|
|
271
|
+
if (a.date === date)
|
|
272
|
+
n = Math.max(n, a.n);
|
|
273
|
+
for (;;) {
|
|
274
|
+
n += 1;
|
|
275
|
+
const path = `${opts.root}/${stem}-${date}-${n}.jsonl`;
|
|
276
|
+
try {
|
|
277
|
+
await fs.create(path, text);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
catch (e) {
|
|
281
|
+
// Taken -> try the next n; otherwise it is a real write failure.
|
|
282
|
+
if ((await readOrNull(fs, path)) === null)
|
|
283
|
+
throw e;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
async function writeActive(fs, text) {
|
|
288
|
+
if (diskText === null)
|
|
289
|
+
await fs.create(activePath, text);
|
|
290
|
+
else
|
|
291
|
+
await fs.write(activePath, text);
|
|
292
|
+
diskText = text;
|
|
293
|
+
}
|
|
294
|
+
/** Commit entries[from, to) as landed on disk. */
|
|
295
|
+
function landed(entries, from, to) {
|
|
296
|
+
for (let i = from; i < to; i++) {
|
|
297
|
+
const e = entries[i];
|
|
298
|
+
if (e.draft.kind === 'audit' && typeof e.draft.event === 'string')
|
|
299
|
+
lastAuditEvent = e.draft.event;
|
|
300
|
+
if (e.covers) {
|
|
301
|
+
pendingGap -= e.covers;
|
|
302
|
+
if (pendingGap <= 0) {
|
|
303
|
+
pendingGap = 0;
|
|
304
|
+
gapSince = null;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/** Write entries[progress.done..], advancing `progress.done` and the
|
|
310
|
+
* disk-confirmed state at each write that lands. */
|
|
311
|
+
async function writeFrom(fs, entries, progress) {
|
|
312
|
+
await ensureFresh(fs);
|
|
313
|
+
let text = activeText;
|
|
314
|
+
let count = activeCount;
|
|
315
|
+
let hash = lastHash;
|
|
316
|
+
let start = progress.done;
|
|
317
|
+
for (let i = progress.done; i < entries.length; i++) {
|
|
318
|
+
if (count >= maxLines) {
|
|
319
|
+
await createArchive(fs, text);
|
|
320
|
+
/* Lines [start, i) are durable in the archive. The active file still
|
|
321
|
+
* holds them until the write below lands; a reload reconciles that. */
|
|
322
|
+
activeText = '';
|
|
323
|
+
activeCount = 0;
|
|
324
|
+
lastHash = hash;
|
|
325
|
+
landed(entries, start, i);
|
|
326
|
+
progress.done = i;
|
|
327
|
+
start = i;
|
|
328
|
+
text = '';
|
|
329
|
+
count = 0;
|
|
330
|
+
}
|
|
331
|
+
const line = JSON.stringify({ ...entries[i].draft, prev: hash });
|
|
332
|
+
hash = await lineHash(line);
|
|
333
|
+
text += line + '\n';
|
|
334
|
+
count += 1;
|
|
335
|
+
}
|
|
336
|
+
await writeActive(fs, text);
|
|
337
|
+
activeText = text;
|
|
338
|
+
activeCount = count;
|
|
339
|
+
lastHash = hash;
|
|
340
|
+
landed(entries, start, entries.length);
|
|
341
|
+
progress.done = entries.length;
|
|
342
|
+
}
|
|
343
|
+
function lose(drafts) {
|
|
344
|
+
if (!drafts.length)
|
|
345
|
+
return;
|
|
346
|
+
lostCount += drafts.length;
|
|
347
|
+
pendingGap += drafts.length;
|
|
348
|
+
if (gapSince === null)
|
|
349
|
+
gapSince = String(drafts[0].ts);
|
|
350
|
+
}
|
|
351
|
+
const gapLine = () => ({
|
|
352
|
+
draft: pointLine({ kind: 'gap', lost: pendingGap, since: gapSince ?? isoNow() }), user: false, covers: pendingGap,
|
|
353
|
+
});
|
|
354
|
+
async function writeBatch(drafts) {
|
|
355
|
+
let fs = null;
|
|
356
|
+
try {
|
|
357
|
+
fs = await opts.files();
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
fs = null;
|
|
361
|
+
}
|
|
362
|
+
if (!fs) {
|
|
363
|
+
lose(drafts);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
for (let attempt = 0; !loaded; attempt++) {
|
|
367
|
+
try {
|
|
368
|
+
await ensureLoaded(fs);
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
if (attempt >= 1) {
|
|
372
|
+
lose(drafts);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
await retention(fs);
|
|
379
|
+
}
|
|
380
|
+
catch { /* best effort */ }
|
|
381
|
+
// The setting applies at APPEND time: append() only ever queued a draft
|
|
382
|
+
// because isEnabled() said yes when it was called, so every draft here
|
|
383
|
+
// was accepted while enabled and must be written -- never dropped
|
|
384
|
+
// uncounted -- however isEnabled() answers NOW at flush time. What
|
|
385
|
+
// differs by the current answer is only ORDER and whether a marker is
|
|
386
|
+
// owed: turning off announces AFTER whatever was captured before the
|
|
387
|
+
// flip; turning back on announces BEFORE whatever was captured since.
|
|
388
|
+
const entries = [];
|
|
389
|
+
const enabledNow = isEnabled();
|
|
390
|
+
if (enabledNow && lastAuditEvent === 'disabled') {
|
|
391
|
+
entries.push({ draft: pointLine({ event: 'enabled' }), user: false });
|
|
392
|
+
}
|
|
393
|
+
if (pendingGap > 0 && (drafts.length || entries.length || (!enabledNow && lastAuditEvent !== 'disabled'))) {
|
|
394
|
+
entries.push(gapLine());
|
|
395
|
+
}
|
|
396
|
+
for (const draft of drafts)
|
|
397
|
+
entries.push({ draft, user: true });
|
|
398
|
+
if (!enabledNow && lastAuditEvent !== 'disabled') {
|
|
399
|
+
entries.push({ draft: pointLine({ event: 'disabled' }), user: false });
|
|
400
|
+
}
|
|
401
|
+
if (!entries.length)
|
|
402
|
+
return;
|
|
403
|
+
const progress = { done: 0 };
|
|
404
|
+
for (let attempt = 0; attempt < 2 && progress.done < entries.length; attempt++) {
|
|
405
|
+
try {
|
|
406
|
+
await writeFrom(fs, entries, progress);
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
/* retried once; then the remainder is counted as lost */
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
lose(entries.slice(progress.done).filter((e) => e.user).map((e) => e.draft));
|
|
413
|
+
}
|
|
414
|
+
function flush() {
|
|
415
|
+
if (timer) {
|
|
416
|
+
clearTimeout(timer);
|
|
417
|
+
timer = null;
|
|
418
|
+
}
|
|
419
|
+
const batch = queue;
|
|
420
|
+
queue = [];
|
|
421
|
+
const switchPending = !isEnabled() || !loaded;
|
|
422
|
+
if (!batch.length && !switchPending)
|
|
423
|
+
return chain;
|
|
424
|
+
chain = chain.then(() => writeBatch(batch)).catch(() => {
|
|
425
|
+
/* writeBatch accounts for its own failures; nothing may reject flush() */
|
|
426
|
+
});
|
|
427
|
+
return chain;
|
|
428
|
+
}
|
|
429
|
+
function schedule() {
|
|
430
|
+
if (!timer)
|
|
431
|
+
timer = setTimeout(() => { timer = null; void flush(); }, flushMs);
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
append(d) {
|
|
435
|
+
try {
|
|
436
|
+
if (!isEnabled()) {
|
|
437
|
+
/* Dropped by design; only the one-time `disabled` line is owed. */
|
|
438
|
+
if (!loaded)
|
|
439
|
+
schedule();
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
queue.push(d);
|
|
443
|
+
if (queue.length >= flushAt) {
|
|
444
|
+
void flush();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
schedule();
|
|
448
|
+
}
|
|
449
|
+
catch {
|
|
450
|
+
/* never throws into a run */
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
flush,
|
|
454
|
+
lost: () => lostCount,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../audit/log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AgentEvent, AuditDraft, AuditHost, DecisionEvent, NodeEvent } from '@corenel/protocol';
|
|
2
|
+
export interface AuditRunContext {
|
|
3
|
+
host: AuditHost;
|
|
4
|
+
session?: string;
|
|
5
|
+
run?: string;
|
|
6
|
+
agent?: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface AuditRecorder {
|
|
10
|
+
onEvent(e: AgentEvent): void;
|
|
11
|
+
onNodeEvent(e: NodeEvent): void;
|
|
12
|
+
onDecision(e: DecisionEvent): void;
|
|
13
|
+
finish(outcome: string): void;
|
|
14
|
+
/** Resolves once every step enqueued so far has run (and emitted, or had
|
|
15
|
+
* its emit swallowed -- see `safeEmit`). A host awaits this before
|
|
16
|
+
* flushing/closing the log, so a pending async step can never be dropped
|
|
17
|
+
* mid-write. */
|
|
18
|
+
whenIdle(): Promise<void>;
|
|
19
|
+
readonly trace: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function createAuditRecorder(opts: {
|
|
22
|
+
ctx: AuditRunContext;
|
|
23
|
+
emit: (d: AuditDraft) => void;
|
|
24
|
+
now?: () => number;
|
|
25
|
+
ids?: {
|
|
26
|
+
trace: () => string;
|
|
27
|
+
span: () => string;
|
|
28
|
+
};
|
|
29
|
+
hash?: (args: unknown) => Promise<string>;
|
|
30
|
+
}): AuditRecorder;
|
|
31
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../audit/recorder.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAIrG,MAAM,WAAW,eAAe;IAAG,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AACpH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;oBAGgB;IAChB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AA0CD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,GAAG,EAAE,eAAe,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,MAAM,CAAA;KAAE,CAAC;IAClD,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C,GAAG,aAAa,CAsIhB"}
|