@oxagen/cli 2.1.4-684 → 2.1.4-699
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/oxagen.mjs +2219 -1459
- package/package.json +1 -1
package/oxagen.mjs
CHANGED
|
@@ -5253,6 +5253,78 @@ var init_envelope = __esm({
|
|
|
5253
5253
|
}
|
|
5254
5254
|
});
|
|
5255
5255
|
|
|
5256
|
+
// ../../packages/tacho/src/harness-limits.ts
|
|
5257
|
+
function isLimitedHarness(harness) {
|
|
5258
|
+
return harness !== void 0 && LIMITED_HARNESSES.includes(harness);
|
|
5259
|
+
}
|
|
5260
|
+
function harnessHookLimitChars(harness) {
|
|
5261
|
+
return HARNESS_HOOK_LIMITS[isLimitedHarness(harness) ? harness : SMALLEST_LIMIT_HARNESS].chars;
|
|
5262
|
+
}
|
|
5263
|
+
function hookAnswerMaxChars(harness) {
|
|
5264
|
+
return harnessHookLimitChars(harness) - HOOK_ANSWER_RESERVE_CHARS;
|
|
5265
|
+
}
|
|
5266
|
+
function prefixBudgetTokens(harness) {
|
|
5267
|
+
return Math.floor(
|
|
5268
|
+
(hookAnswerMaxChars(harness) - STEER_ROOM_CHARS) / 4
|
|
5269
|
+
);
|
|
5270
|
+
}
|
|
5271
|
+
function harnessesAtLargestBudget() {
|
|
5272
|
+
return LIMITED_HARNESSES.filter(
|
|
5273
|
+
(harness) => prefixBudgetTokens(harness) === LARGEST_PREFIX_BUDGET_TOKENS
|
|
5274
|
+
);
|
|
5275
|
+
}
|
|
5276
|
+
var CONTEXT_SYSTEM_MAX_CHARS, CODEX_ADDITIONAL_CONTEXT_LIMIT, LIMITED_HARNESSES, HARNESS_HOOK_LIMITS, HOOK_ANSWER_RESERVE_CHARS, STEER_ROOM_CHARS, SMALLEST_LIMIT_HARNESS, SMALLEST_PREFIX_BUDGET_TOKENS, LARGEST_PREFIX_BUDGET_TOKENS;
|
|
5277
|
+
var init_harness_limits = __esm({
|
|
5278
|
+
"../../packages/tacho/src/harness-limits.ts"() {
|
|
5279
|
+
"use strict";
|
|
5280
|
+
CONTEXT_SYSTEM_MAX_CHARS = 16384;
|
|
5281
|
+
CODEX_ADDITIONAL_CONTEXT_LIMIT = 16384;
|
|
5282
|
+
LIMITED_HARNESSES = [
|
|
5283
|
+
"claude-code",
|
|
5284
|
+
"codex",
|
|
5285
|
+
"cursor",
|
|
5286
|
+
"stella"
|
|
5287
|
+
];
|
|
5288
|
+
HARNESS_HOOK_LIMITS = {
|
|
5289
|
+
"claude-code": {
|
|
5290
|
+
documented: 1e4,
|
|
5291
|
+
chars: 1e4,
|
|
5292
|
+
source: "https://code.claude.com/docs/en/hooks",
|
|
5293
|
+
note: "A hook's additionalContext is capped at 10,000 characters. Past the cap Claude Code saves the text to a file and passes a path with a 2,000-character preview. No setting raises the cap."
|
|
5294
|
+
},
|
|
5295
|
+
codex: {
|
|
5296
|
+
documented: CODEX_ADDITIONAL_CONTEXT_LIMIT,
|
|
5297
|
+
chars: Math.min(CODEX_ADDITIONAL_CONTEXT_LIMIT, CONTEXT_SYSTEM_MAX_CHARS),
|
|
5298
|
+
source: "https://developers.openai.com/codex/hooks",
|
|
5299
|
+
note: "Codex spills additionalContext past about 2,500 approximate tokens unless the hook sets additionalContextLimit. Oxagen writes that setting on every hook that answers with text, and a string never has fewer characters than tokens."
|
|
5300
|
+
},
|
|
5301
|
+
cursor: {
|
|
5302
|
+
documented: null,
|
|
5303
|
+
chars: CONTEXT_SYSTEM_MAX_CHARS,
|
|
5304
|
+
source: "https://cursor.com/docs/agent/hooks",
|
|
5305
|
+
note: "The sessionStart hook's additional_context has no documented limit, so the host's context.system cap binds."
|
|
5306
|
+
},
|
|
5307
|
+
stella: {
|
|
5308
|
+
documented: null,
|
|
5309
|
+
chars: CONTEXT_SYSTEM_MAX_CHARS,
|
|
5310
|
+
source: "crates/stella-core/src/hooks.rs in macanderson/stella",
|
|
5311
|
+
note: "Stella appends a SessionStart hook's whole stdout to the system prompt and caps nothing, so the host's context.system cap binds."
|
|
5312
|
+
}
|
|
5313
|
+
};
|
|
5314
|
+
HOOK_ANSWER_RESERVE_CHARS = 500;
|
|
5315
|
+
STEER_ROOM_CHARS = 1500;
|
|
5316
|
+
SMALLEST_LIMIT_HARNESS = [...LIMITED_HARNESSES].sort(
|
|
5317
|
+
(a, b5) => HARNESS_HOOK_LIMITS[a].chars - HARNESS_HOOK_LIMITS[b5].chars
|
|
5318
|
+
)[0];
|
|
5319
|
+
SMALLEST_PREFIX_BUDGET_TOKENS = prefixBudgetTokens(
|
|
5320
|
+
SMALLEST_LIMIT_HARNESS
|
|
5321
|
+
);
|
|
5322
|
+
LARGEST_PREFIX_BUDGET_TOKENS = Math.max(
|
|
5323
|
+
...LIMITED_HARNESSES.map(prefixBudgetTokens)
|
|
5324
|
+
);
|
|
5325
|
+
}
|
|
5326
|
+
});
|
|
5327
|
+
|
|
5256
5328
|
// ../../packages/tacho/src/policy/context.ts
|
|
5257
5329
|
function clockContext(now) {
|
|
5258
5330
|
const date = new Date(now);
|
|
@@ -5377,6 +5449,7 @@ var init_wire = __esm({
|
|
|
5377
5449
|
init_zod();
|
|
5378
5450
|
init_digest();
|
|
5379
5451
|
init_envelope();
|
|
5452
|
+
init_harness_limits();
|
|
5380
5453
|
init_context();
|
|
5381
5454
|
TACHO_BATCH_SCHEMA = "tacho.batch.v1";
|
|
5382
5455
|
TACHO_BUNDLE_SCHEMA = "tacho.bundle.v1";
|
|
@@ -5763,7 +5836,7 @@ var init_wire = __esm({
|
|
|
5763
5836
|
mode: external_exports.enum(["observed", "enforced"])
|
|
5764
5837
|
}).strict(),
|
|
5765
5838
|
context: external_exports.object({
|
|
5766
|
-
system: external_exports.string().max(
|
|
5839
|
+
system: external_exports.string().max(CONTEXT_SYSTEM_MAX_CHARS).nullable(),
|
|
5767
5840
|
/**
|
|
5768
5841
|
* Emitted only to a host that advertised
|
|
5769
5842
|
* `BUNDLE_FEATURE_STEERING_MANIFEST`; see that constant.
|
|
@@ -7343,13 +7416,13 @@ function candidatePaths(path2, context) {
|
|
|
7343
7416
|
cwd !== void 0 && lib.isAbsolute(cwd) ? lib.resolve(cwd, expanded) : lib.normalize(expanded)
|
|
7344
7417
|
);
|
|
7345
7418
|
const out = [resolved];
|
|
7346
|
-
const
|
|
7419
|
+
const under2 = (root) => {
|
|
7347
7420
|
const base2 = fold(lib.normalize(root)).replace(/\/+$/, "");
|
|
7348
7421
|
return resolved.startsWith(`${base2}/`) ? resolved.slice(base2.length + 1) : void 0;
|
|
7349
7422
|
};
|
|
7350
|
-
const
|
|
7351
|
-
if (
|
|
7352
|
-
const fromHome = home !== void 0 ?
|
|
7423
|
+
const relative11 = cwd !== void 0 ? under2(cwd) : void 0;
|
|
7424
|
+
if (relative11 !== void 0) out.push(relative11);
|
|
7425
|
+
const fromHome = home !== void 0 ? under2(home) : void 0;
|
|
7353
7426
|
if (fromHome !== void 0) out.push(`~/${fromHome}`);
|
|
7354
7427
|
return out;
|
|
7355
7428
|
}
|
|
@@ -9519,11 +9592,12 @@ function stripCodexHooks(existing, enrollmentId) {
|
|
|
9519
9592
|
function codexHookPresence(existing, enrollmentId) {
|
|
9520
9593
|
return hookGroupPresence(existing, CODEX_HOOK_EVENTS, enrollmentId);
|
|
9521
9594
|
}
|
|
9522
|
-
var CODEX_TELEMETRY_EVENTS, CODEX_HOOK_EVENTS, TELEMETRY_TIMEOUT_S2,
|
|
9595
|
+
var CODEX_TELEMETRY_EVENTS, CODEX_HOOK_EVENTS, TELEMETRY_TIMEOUT_S2, CONTEXT_EVENTS;
|
|
9523
9596
|
var init_codex_writer = __esm({
|
|
9524
9597
|
"../../packages/tacho/src/host/codex-writer.ts"() {
|
|
9525
9598
|
"use strict";
|
|
9526
9599
|
init_settings_writer();
|
|
9600
|
+
init_harness_limits();
|
|
9527
9601
|
CODEX_TELEMETRY_EVENTS = [
|
|
9528
9602
|
"PostToolUse",
|
|
9529
9603
|
"SubagentStart",
|
|
@@ -9538,7 +9612,6 @@ var init_codex_writer = __esm({
|
|
|
9538
9612
|
...CODEX_TELEMETRY_EVENTS
|
|
9539
9613
|
];
|
|
9540
9614
|
TELEMETRY_TIMEOUT_S2 = 5;
|
|
9541
|
-
CODEX_ADDITIONAL_CONTEXT_LIMIT = 1e4;
|
|
9542
9615
|
CONTEXT_EVENTS = /* @__PURE__ */ new Set([
|
|
9543
9616
|
"SessionStart",
|
|
9544
9617
|
"UserPromptSubmit",
|
|
@@ -24024,7 +24097,7 @@ import { readFileSync as readFileSync11 } from "node:fs";
|
|
|
24024
24097
|
import { dirname as dirname9, resolve as resolve3 } from "node:path";
|
|
24025
24098
|
import { fileURLToPath } from "node:url";
|
|
24026
24099
|
function readVersion() {
|
|
24027
|
-
if (true) return "2.1.4-
|
|
24100
|
+
if (true) return "2.1.4-699";
|
|
24028
24101
|
try {
|
|
24029
24102
|
const here = dirname9(fileURLToPath(import.meta.url));
|
|
24030
24103
|
const pkg = JSON.parse(
|
|
@@ -24284,11 +24357,11 @@ function harnessFacts(exec4, name, platform = process.platform, env = process.en
|
|
|
24284
24357
|
path2 ??= shellExecutable(exec4("sh", ["-lc", `command -v ${name}`]));
|
|
24285
24358
|
}
|
|
24286
24359
|
if (path2 === void 0) {
|
|
24287
|
-
const
|
|
24360
|
+
const sep13 = platform === "win32" ? "\\" : "/";
|
|
24288
24361
|
const names2 = platform === "win32" ? [`${name}.exe`, `${name}.cmd`] : [name];
|
|
24289
24362
|
outer: for (const dir of wellKnownBinDirs(home, platform, env)) {
|
|
24290
24363
|
for (const file of names2) {
|
|
24291
|
-
const candidate = `${dir}${
|
|
24364
|
+
const candidate = `${dir}${sep13}${file}`;
|
|
24292
24365
|
if (exists(candidate)) {
|
|
24293
24366
|
path2 = candidate;
|
|
24294
24367
|
break outer;
|
|
@@ -25029,10 +25102,12 @@ function createControlClient(options) {
|
|
|
25029
25102
|
ingestTimeoutMs
|
|
25030
25103
|
)
|
|
25031
25104
|
),
|
|
25032
|
-
bundle: async (etag) => bundleResponseSchema.parse(
|
|
25105
|
+
bundle: async (etag, run3) => bundleResponseSchema.parse(
|
|
25033
25106
|
await post2(options.endpoints.bundle, {
|
|
25034
25107
|
host_enrollment_id: options.hostEnrollmentId,
|
|
25035
|
-
...etag !== void 0 ? { etag } : {}
|
|
25108
|
+
...etag !== void 0 ? { etag } : {},
|
|
25109
|
+
...run3?.remote !== void 0 ? { remote: run3.remote } : {},
|
|
25110
|
+
...run3?.harness !== void 0 ? { harness: run3.harness } : {}
|
|
25036
25111
|
})
|
|
25037
25112
|
),
|
|
25038
25113
|
commands: async (acknowledgements = [], daemon) => commandsResponseSchema.parse(
|
|
@@ -29171,8 +29246,8 @@ function harnessFileProblems(harnesses, deps) {
|
|
|
29171
29246
|
if (harnesses.includes("codex"))
|
|
29172
29247
|
check2(deps.paths.codexHooks, deps.readCodexHooks, hooksShapeProblem);
|
|
29173
29248
|
if (harnesses.includes("cursor")) {
|
|
29174
|
-
const
|
|
29175
|
-
if (
|
|
29249
|
+
const relative11 = absoluteHookCommandProblem(deps.runtime.hookCommand);
|
|
29250
|
+
if (relative11 !== void 0) problems.push(relative11);
|
|
29176
29251
|
for (const path2 of deps.paths.cursorHooks)
|
|
29177
29252
|
check2(path2, () => deps.readCursorHooks(path2), cursorHooksShapeProblem);
|
|
29178
29253
|
}
|
|
@@ -38218,6 +38293,7 @@ async function readRepositoryRemote(exec4, cwd) {
|
|
|
38218
38293
|
const slash = canonical3.lastIndexOf("/");
|
|
38219
38294
|
const name = slash === -1 ? "" : canonical3.slice(slash + 1);
|
|
38220
38295
|
return {
|
|
38296
|
+
canonical: canonical3,
|
|
38221
38297
|
remote_digest: digestBytes(canonical3),
|
|
38222
38298
|
remote_digest_folded: digestBytes(foldedRemote(canonical3)),
|
|
38223
38299
|
...name.length > 0 ? { name } : {},
|
|
@@ -40608,6 +40684,7 @@ function deliversMessages(harness, hookEventName) {
|
|
|
40608
40684
|
function drainMessages(record, deps, events, used = 0) {
|
|
40609
40685
|
const delivered = [];
|
|
40610
40686
|
const now = deps.now();
|
|
40687
|
+
const max2 = hookAnswerMaxChars(record.harness);
|
|
40611
40688
|
const queue = record.control.messages.splice(0);
|
|
40612
40689
|
for (const [index, message] of queue.entries()) {
|
|
40613
40690
|
if (message.expiresAt !== null && Date.parse(message.expiresAt) < now) {
|
|
@@ -40619,17 +40696,17 @@ function drainMessages(record, deps, events, used = 0) {
|
|
|
40619
40696
|
});
|
|
40620
40697
|
continue;
|
|
40621
40698
|
}
|
|
40622
|
-
if (message.text.length >
|
|
40699
|
+
if (message.text.length > max2) {
|
|
40623
40700
|
deps.acknowledge?.({
|
|
40624
40701
|
command_id: message.id,
|
|
40625
40702
|
status: "failed",
|
|
40626
40703
|
session_uuid: record.recorder.sessionUuid,
|
|
40627
|
-
detail: `longer than the ${
|
|
40704
|
+
detail: `longer than the ${max2} characters a hook delivers`
|
|
40628
40705
|
});
|
|
40629
40706
|
continue;
|
|
40630
40707
|
}
|
|
40631
40708
|
const size = (used > 0 ? CONTEXT_JOINER.length : 0) + message.text.length;
|
|
40632
|
-
if (used + size >
|
|
40709
|
+
if (used + size > max2) {
|
|
40633
40710
|
record.control.messages.unshift(...queue.slice(index));
|
|
40634
40711
|
break;
|
|
40635
40712
|
}
|
|
@@ -40812,8 +40889,8 @@ function promptText(input) {
|
|
|
40812
40889
|
const userInput = input["user_input"];
|
|
40813
40890
|
return typeof userInput === "string" ? userInput : void 0;
|
|
40814
40891
|
}
|
|
40815
|
-
function recallContext(memories, used) {
|
|
40816
|
-
const room =
|
|
40892
|
+
function recallContext(memories, used, max2 = ADDITIONAL_CONTEXT_MAX_CHARS) {
|
|
40893
|
+
const room = max2 - used - (used > 0 ? CONTEXT_JOINER.length : 0);
|
|
40817
40894
|
let text5 = RECALL_HEADING;
|
|
40818
40895
|
let count12 = 0;
|
|
40819
40896
|
for (const memory of memories) {
|
|
@@ -40827,6 +40904,19 @@ function recallContext(memories, used) {
|
|
|
40827
40904
|
}
|
|
40828
40905
|
return count12 > 0 ? { text: text5, count: count12 } : void 0;
|
|
40829
40906
|
}
|
|
40907
|
+
async function runSteeringBundle(record, deps) {
|
|
40908
|
+
if (deps.runSteering === void 0) return void 0;
|
|
40909
|
+
const named = record.harness ?? "claude-code";
|
|
40910
|
+
const harness = WRAPPED_HARNESSES.includes(named) ? named : void 0;
|
|
40911
|
+
const remote = Promise.resolve(
|
|
40912
|
+
deps.repositoryRemote === void 0 ? void 0 : readRepository(recallView(record), deps.repositoryRemote)
|
|
40913
|
+
).then((repository) => repository?.canonical);
|
|
40914
|
+
try {
|
|
40915
|
+
return await deps.runSteering(remote, harness);
|
|
40916
|
+
} catch {
|
|
40917
|
+
return void 0;
|
|
40918
|
+
}
|
|
40919
|
+
}
|
|
40830
40920
|
function skillsHarness(record) {
|
|
40831
40921
|
if (record.customAgent !== void 0) return void 0;
|
|
40832
40922
|
return record.harness ?? "claude-code";
|
|
@@ -40836,7 +40926,13 @@ async function placeSessionSkills(view, record, deps, env) {
|
|
|
40836
40926
|
const harness = skillsHarness(record);
|
|
40837
40927
|
if (deps.skills === void 0 || harness === void 0 || !view.verified || skills === void 0 || skills.length === 0)
|
|
40838
40928
|
return;
|
|
40839
|
-
await deps.skills.place(
|
|
40929
|
+
await deps.skills.place(
|
|
40930
|
+
harness,
|
|
40931
|
+
record.harnessSessionId,
|
|
40932
|
+
skills,
|
|
40933
|
+
env,
|
|
40934
|
+
view.bundle.cedar?.policies
|
|
40935
|
+
);
|
|
40840
40936
|
}
|
|
40841
40937
|
async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
40842
40938
|
const input = hookInputSchema.parse(raw);
|
|
@@ -40906,7 +41002,8 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
40906
41002
|
switch (input.hook_event_name) {
|
|
40907
41003
|
case "SessionStart": {
|
|
40908
41004
|
const block = operatorBlock(view, record);
|
|
40909
|
-
const
|
|
41005
|
+
const steering = block === void 0 && replay === void 0 ? await runSteeringBundle(record, deps) ?? view.bundle : view.bundle;
|
|
41006
|
+
const context = steering.context.system;
|
|
40910
41007
|
const messages = block === void 0 && replay === void 0 ? drainMessages(record, deps, events, context?.length ?? 0) : [];
|
|
40911
41008
|
const additional = block === void 0 ? [context ?? "", ...messages.map((m) => m.text)].filter((s4) => s4.length > 0).join(CONTEXT_JOINER) : "";
|
|
40912
41009
|
const delivered = replay === void 0 ? void 0 : readDeliveredContext(replay.deliveredContext);
|
|
@@ -40958,12 +41055,12 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
40958
41055
|
}
|
|
40959
41056
|
if (replay === void 0)
|
|
40960
41057
|
await placeSessionSkills(view, record, deps, env);
|
|
40961
|
-
const manifest =
|
|
40962
|
-
if (manifest !== void 0 && (replay === void 0 || delivered?.bundle_etag ===
|
|
41058
|
+
const manifest = steering.context.manifest;
|
|
41059
|
+
if (manifest !== void 0 && (replay === void 0 || delivered?.bundle_etag === steering.etag && manifest.text_digest === (delivered.digest ?? null))) {
|
|
40963
41060
|
events.push(
|
|
40964
41061
|
record.recorder.sealCollectorEvent(
|
|
40965
41062
|
"steering.manifest",
|
|
40966
|
-
steeringManifestFrame(manifest,
|
|
41063
|
+
steeringManifestFrame(manifest, steering, messages),
|
|
40967
41064
|
{ hook_event_name: "SessionStart", attrs: replayed }
|
|
40968
41065
|
)
|
|
40969
41066
|
);
|
|
@@ -41006,7 +41103,8 @@ async function routeHook(raw, env, deps, replay, harness, agent, hookId) {
|
|
|
41006
41103
|
...recallScope(recallView(record)),
|
|
41007
41104
|
text: promptText(input) ?? ""
|
|
41008
41105
|
}),
|
|
41009
|
-
delivered.join(CONTEXT_JOINER).length
|
|
41106
|
+
delivered.join(CONTEXT_JOINER).length,
|
|
41107
|
+
hookAnswerMaxChars(record.harness)
|
|
41010
41108
|
) : void 0;
|
|
41011
41109
|
if (block === void 0) record.control.resumeOwed = void 0;
|
|
41012
41110
|
if (block === void 0) notePrompt(record, promptText(input));
|
|
@@ -41452,6 +41550,7 @@ var init_hook_handler = __esm({
|
|
|
41452
41550
|
init_context2();
|
|
41453
41551
|
init_tools();
|
|
41454
41552
|
init_steering_manifest();
|
|
41553
|
+
init_harness_limits();
|
|
41455
41554
|
init_timestamp();
|
|
41456
41555
|
init_wire();
|
|
41457
41556
|
init_bundle();
|
|
@@ -41471,7 +41570,7 @@ var init_hook_handler = __esm({
|
|
|
41471
41570
|
"Stop"
|
|
41472
41571
|
]);
|
|
41473
41572
|
RESUMED_TEXT = "Resumed by the operator. Continue the task.";
|
|
41474
|
-
ADDITIONAL_CONTEXT_MAX_CHARS =
|
|
41573
|
+
ADDITIONAL_CONTEXT_MAX_CHARS = hookAnswerMaxChars(void 0);
|
|
41475
41574
|
CONTEXT_JOINER = "\n\n";
|
|
41476
41575
|
TOOL_CALL_HOOK_EVENTS = /* @__PURE__ */ new Set([
|
|
41477
41576
|
"PreToolUse",
|
|
@@ -45570,6 +45669,37 @@ import { createHash as createHash13 } from "node:crypto";
|
|
|
45570
45669
|
import { mkdir as mkdir2, readdir as readdir2, readFile as readFile2, rm as rm2, writeFile } from "node:fs/promises";
|
|
45571
45670
|
import { homedir as homedir5 } from "node:os";
|
|
45572
45671
|
import { dirname as dirname20, join as join36 } from "node:path";
|
|
45672
|
+
function skillToolLimits(policies) {
|
|
45673
|
+
const limits = /* @__PURE__ */ new Map();
|
|
45674
|
+
for (const text5 of Object.values(policies)) {
|
|
45675
|
+
const lineage = SKILL_POLICY_ANNOTATION.exec(text5)?.[1];
|
|
45676
|
+
if (lineage === void 0) continue;
|
|
45677
|
+
const list = UNLESS_ACTIONS.exec(text5)?.[1] ?? "";
|
|
45678
|
+
const actions = [...list.matchAll(ACTION_ID)].map((m) => m[1]);
|
|
45679
|
+
const held = limits.get(lineage);
|
|
45680
|
+
const permitted = held === void 0 ? actions : held.filter((action) => actions.includes(action));
|
|
45681
|
+
limits.set(lineage, [...new Set(permitted)].sort());
|
|
45682
|
+
}
|
|
45683
|
+
return limits;
|
|
45684
|
+
}
|
|
45685
|
+
function harnessToolNames(harness, actions) {
|
|
45686
|
+
if (harness !== "claude-code") return null;
|
|
45687
|
+
const names2 = /* @__PURE__ */ new Set();
|
|
45688
|
+
for (const action of actions) {
|
|
45689
|
+
for (const name of CLAUDE_CODE_TOOL_NAMES[action] ?? []) names2.add(name);
|
|
45690
|
+
}
|
|
45691
|
+
return CLAUDE_CODE_TOOL_ORDER.filter((name) => names2.has(name));
|
|
45692
|
+
}
|
|
45693
|
+
function withToolLimits(skills, limits) {
|
|
45694
|
+
if (limits === void 0) return [...skills];
|
|
45695
|
+
const byLineage = skillToolLimits(limits.policies);
|
|
45696
|
+
return skills.map((skill) => {
|
|
45697
|
+
const actions = byLineage.get(skill.lineage);
|
|
45698
|
+
if (actions === void 0) return skill;
|
|
45699
|
+
const names2 = harnessToolNames(limits.harness, actions);
|
|
45700
|
+
return names2 === null ? skill : { ...skill, allowedTools: names2 };
|
|
45701
|
+
});
|
|
45702
|
+
}
|
|
45573
45703
|
function envDir(env, key) {
|
|
45574
45704
|
const value = env[key];
|
|
45575
45705
|
return value === void 0 || value.trim() === "" ? null : value;
|
|
@@ -45610,10 +45740,12 @@ function skillFileRefusal(path2) {
|
|
|
45610
45740
|
return null;
|
|
45611
45741
|
}
|
|
45612
45742
|
function skillMarkdown(skill) {
|
|
45743
|
+
const tools = skill.allowedTools !== void 0 && skill.allowedTools.length > 0 ? `allowed-tools: ${skill.allowedTools.join(", ")}
|
|
45744
|
+
` : "";
|
|
45613
45745
|
return `---
|
|
45614
45746
|
name: ${skill.name}
|
|
45615
45747
|
description: ${JSON.stringify(skill.description)}
|
|
45616
|
-
---
|
|
45748
|
+
${tools}---
|
|
45617
45749
|
|
|
45618
45750
|
${skill.body.replace(/^\n+/, "")}`;
|
|
45619
45751
|
}
|
|
@@ -45691,11 +45823,11 @@ function skillRefusal(skill) {
|
|
|
45691
45823
|
}
|
|
45692
45824
|
return null;
|
|
45693
45825
|
}
|
|
45694
|
-
async function placeSkills(root, sessionId, skills, now = /* @__PURE__ */ new Date()) {
|
|
45826
|
+
async function placeSkills(root, sessionId, skills, now = /* @__PURE__ */ new Date(), limits) {
|
|
45695
45827
|
const result2 = { placed: [], skipped: [], warnings: [] };
|
|
45696
45828
|
await mkdir2(root, { recursive: true });
|
|
45697
45829
|
const taken = /* @__PURE__ */ new Set();
|
|
45698
|
-
for (const skill of skills) {
|
|
45830
|
+
for (const skill of withToolLimits(skills, limits)) {
|
|
45699
45831
|
const refusal = skillRefusal(skill);
|
|
45700
45832
|
if (refusal !== null) {
|
|
45701
45833
|
result2.skipped.push(skill.name);
|
|
@@ -45785,13 +45917,36 @@ async function removeSkills(root, sessionId, now = /* @__PURE__ */ new Date()) {
|
|
|
45785
45917
|
}
|
|
45786
45918
|
return result2;
|
|
45787
45919
|
}
|
|
45788
|
-
var SESSION_MARKER, SESSION_TTL_MS, SKILL_NAME_PATTERN;
|
|
45920
|
+
var SESSION_MARKER, SESSION_TTL_MS, SKILL_NAME_PATTERN, SKILL_POLICY_ANNOTATION, UNLESS_ACTIONS, ACTION_ID, CLAUDE_CODE_TOOL_NAMES, CLAUDE_CODE_TOOL_ORDER;
|
|
45789
45921
|
var init_place = __esm({
|
|
45790
45922
|
"../../packages/tacho/src/skills/place.ts"() {
|
|
45791
45923
|
"use strict";
|
|
45792
45924
|
SESSION_MARKER = ".oxagen-session";
|
|
45793
45925
|
SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
45794
45926
|
SKILL_NAME_PATTERN = /^[a-z0-9-]{1,64}$/;
|
|
45927
|
+
SKILL_POLICY_ANNOTATION = /@skill\s*\(\s*"((?:[^"\\]|\\.)*)"\s*\)/;
|
|
45928
|
+
UNLESS_ACTIONS = /unless\s*\{\s*action\s+in\s*\[([^\]]*)\]\s*\}/;
|
|
45929
|
+
ACTION_ID = /Action::"((?:[^"\\]|\\.)*)"/g;
|
|
45930
|
+
CLAUDE_CODE_TOOL_NAMES = {
|
|
45931
|
+
builtin__read_file: ["Read"],
|
|
45932
|
+
builtin__search_files: ["Grep", "Glob"],
|
|
45933
|
+
builtin__shell: ["Bash"],
|
|
45934
|
+
builtin__write_file: ["Edit", "Write"],
|
|
45935
|
+
builtin__web_fetch: ["WebFetch"],
|
|
45936
|
+
builtin__web_search: ["WebSearch"],
|
|
45937
|
+
builtin__start_subagent: ["Agent"]
|
|
45938
|
+
};
|
|
45939
|
+
CLAUDE_CODE_TOOL_ORDER = [
|
|
45940
|
+
"Read",
|
|
45941
|
+
"Grep",
|
|
45942
|
+
"Glob",
|
|
45943
|
+
"Bash",
|
|
45944
|
+
"Edit",
|
|
45945
|
+
"Write",
|
|
45946
|
+
"WebFetch",
|
|
45947
|
+
"WebSearch",
|
|
45948
|
+
"Agent"
|
|
45949
|
+
];
|
|
45795
45950
|
}
|
|
45796
45951
|
});
|
|
45797
45952
|
|
|
@@ -45839,7 +45994,7 @@ function sessionSkills(options) {
|
|
|
45839
45994
|
}
|
|
45840
45995
|
}
|
|
45841
45996
|
return {
|
|
45842
|
-
async place(harness, sessionId, skills, env) {
|
|
45997
|
+
async place(harness, sessionId, skills, env, policies) {
|
|
45843
45998
|
const root = skillsRoot(harness, env, home);
|
|
45844
45999
|
if (root === null || skills.length === 0) return;
|
|
45845
46000
|
placedRoots.set(sessionId, root);
|
|
@@ -45849,7 +46004,8 @@ function sessionSkills(options) {
|
|
|
45849
46004
|
root,
|
|
45850
46005
|
sessionId,
|
|
45851
46006
|
skills.map(decodeSkill),
|
|
45852
|
-
now()
|
|
46007
|
+
now(),
|
|
46008
|
+
policies === void 0 ? void 0 : { harness, policies }
|
|
45853
46009
|
);
|
|
45854
46010
|
for (const warning of result2.warnings) log(`skills: ${warning}`);
|
|
45855
46011
|
} catch (error) {
|
|
@@ -46604,8 +46760,8 @@ function resolveModelRoute(rawUrl, headers) {
|
|
|
46604
46760
|
const mark = rawUrl.indexOf("?");
|
|
46605
46761
|
const pathname = mark === -1 ? rawUrl : rawUrl.slice(0, mark);
|
|
46606
46762
|
const search = mark === -1 ? "" : rawUrl.slice(mark);
|
|
46607
|
-
const
|
|
46608
|
-
const stella =
|
|
46763
|
+
const under2 = (prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`) ? pathname.slice(prefix.length) || "/" : void 0;
|
|
46764
|
+
const stella = under2("/stella/anthropic");
|
|
46609
46765
|
if (stella !== void 0) {
|
|
46610
46766
|
return {
|
|
46611
46767
|
provider: "anthropic",
|
|
@@ -46615,7 +46771,7 @@ function resolveModelRoute(rawUrl, headers) {
|
|
|
46615
46771
|
harness: "stella"
|
|
46616
46772
|
};
|
|
46617
46773
|
}
|
|
46618
|
-
const anthropic =
|
|
46774
|
+
const anthropic = under2("/anthropic");
|
|
46619
46775
|
if (anthropic !== void 0) {
|
|
46620
46776
|
return {
|
|
46621
46777
|
provider: "anthropic",
|
|
@@ -46624,11 +46780,11 @@ function resolveModelRoute(rawUrl, headers) {
|
|
|
46624
46780
|
path: `${anthropic}${search}`
|
|
46625
46781
|
};
|
|
46626
46782
|
}
|
|
46627
|
-
const codex =
|
|
46783
|
+
const codex = under2("/backend-api/codex");
|
|
46628
46784
|
if (codex !== void 0) return openAiRoute(codex, search, headers);
|
|
46629
|
-
const openai =
|
|
46785
|
+
const openai = under2("/openai/v1");
|
|
46630
46786
|
if (openai !== void 0) return openAiRoute(openai, search, headers);
|
|
46631
|
-
const bare =
|
|
46787
|
+
const bare = under2("/v1");
|
|
46632
46788
|
if (bare !== void 0) {
|
|
46633
46789
|
const isAnthropic = bare === "/messages" || bare.startsWith("/messages/") || bare !== "/responses" && bare !== "/chat/completions" && looksAnthropic(headers);
|
|
46634
46790
|
if (isAnthropic) {
|
|
@@ -49925,6 +50081,22 @@ function settleWithin(work, ms) {
|
|
|
49925
50081
|
work.then(done, done);
|
|
49926
50082
|
});
|
|
49927
50083
|
}
|
|
50084
|
+
function valueWithin(work, ms) {
|
|
50085
|
+
return new Promise((resolve23) => {
|
|
50086
|
+
const timer = setTimeout(() => resolve23(void 0), ms);
|
|
50087
|
+
timer.unref();
|
|
50088
|
+
work.then(
|
|
50089
|
+
(value) => {
|
|
50090
|
+
clearTimeout(timer);
|
|
50091
|
+
resolve23(value);
|
|
50092
|
+
},
|
|
50093
|
+
() => {
|
|
50094
|
+
clearTimeout(timer);
|
|
50095
|
+
resolve23(void 0);
|
|
50096
|
+
}
|
|
50097
|
+
);
|
|
50098
|
+
});
|
|
50099
|
+
}
|
|
49928
50100
|
function olderBundle(candidate, held) {
|
|
49929
50101
|
return candidate.version < held.version && !(Date.parse(candidate.issued_at) > Date.parse(held.issued_at));
|
|
49930
50102
|
}
|
|
@@ -50656,6 +50828,43 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
50656
50828
|
bundleFetch = run3;
|
|
50657
50829
|
return run3;
|
|
50658
50830
|
}
|
|
50831
|
+
const RUN_BUNDLES_MAX = 64;
|
|
50832
|
+
const runBundles = /* @__PURE__ */ new Map();
|
|
50833
|
+
async function runBundle(remote, harness) {
|
|
50834
|
+
if (remote === void 0 && harness === void 0) return void 0;
|
|
50835
|
+
const key = `${harness ?? ""}\0${remote ?? ""}`;
|
|
50836
|
+
const held = runBundles.get(key);
|
|
50837
|
+
try {
|
|
50838
|
+
const response = await client.bundle(held?.etag, { remote, harness });
|
|
50839
|
+
lastControlAt = now();
|
|
50840
|
+
if (response.not_modified) return held;
|
|
50841
|
+
if (response.bundle === null) return void 0;
|
|
50842
|
+
const verification = verifyBundle(
|
|
50843
|
+
response.bundle,
|
|
50844
|
+
host.bundle_public_key_pem,
|
|
50845
|
+
host.host_enrollment_id
|
|
50846
|
+
);
|
|
50847
|
+
if (!verification.ok) {
|
|
50848
|
+
log(
|
|
50849
|
+
`refused a run bundle that does not verify: ${verification.reason ?? "unknown"}`
|
|
50850
|
+
);
|
|
50851
|
+
return void 0;
|
|
50852
|
+
}
|
|
50853
|
+
runBundles.delete(key);
|
|
50854
|
+
runBundles.set(key, response.bundle);
|
|
50855
|
+
while (runBundles.size > RUN_BUNDLES_MAX) {
|
|
50856
|
+
const oldest = runBundles.keys().next().value;
|
|
50857
|
+
if (oldest === void 0) break;
|
|
50858
|
+
runBundles.delete(oldest);
|
|
50859
|
+
}
|
|
50860
|
+
return response.bundle;
|
|
50861
|
+
} catch (error) {
|
|
50862
|
+
log(
|
|
50863
|
+
`run bundle fetch failed: ${error instanceof Error ? error.message : String(error)}`
|
|
50864
|
+
);
|
|
50865
|
+
return void 0;
|
|
50866
|
+
}
|
|
50867
|
+
}
|
|
50659
50868
|
async function onControl(control) {
|
|
50660
50869
|
lastControlAt = now();
|
|
50661
50870
|
if (control.agent_day_spend !== void 0)
|
|
@@ -51257,6 +51466,12 @@ async function initializeDaemon(options, server, port, ready) {
|
|
|
51257
51466
|
refreshBundle: async () => {
|
|
51258
51467
|
await settleWithin(refreshBundle(), timers.hookBundleWaitMs);
|
|
51259
51468
|
},
|
|
51469
|
+
// One wait covers the repository read and the run's bundle fetch.
|
|
51470
|
+
// Past it, the start hands the agent the host's bundle (ADR-350).
|
|
51471
|
+
runSteering: (remote, harness) => valueWithin(
|
|
51472
|
+
remote.then((canonical3) => runBundle(canonical3, harness)),
|
|
51473
|
+
timers.hookBundleWaitMs
|
|
51474
|
+
),
|
|
51260
51475
|
acknowledge: (ack) => {
|
|
51261
51476
|
acks.push(ack);
|
|
51262
51477
|
},
|
|
@@ -53116,7 +53331,7 @@ import {
|
|
|
53116
53331
|
writeFileSync as writeFileSync5
|
|
53117
53332
|
} from "node:fs";
|
|
53118
53333
|
import { dirname as dirname22, join as join39, resolve as resolve15 } from "node:path";
|
|
53119
|
-
function bundlePath(root,
|
|
53334
|
+
function bundlePath(root, relative11, create2 = false) {
|
|
53120
53335
|
const absolute = resolve15(root);
|
|
53121
53336
|
if (create2) mkdirSync8(absolute, { recursive: true, mode: 448 });
|
|
53122
53337
|
if (lstatSync7(absolute).isSymbolicLink() || !lstatSync7(absolute).isDirectory()) {
|
|
@@ -53124,7 +53339,7 @@ function bundlePath(root, relative10, create2 = false) {
|
|
|
53124
53339
|
}
|
|
53125
53340
|
const base2 = realpathSync5(absolute);
|
|
53126
53341
|
let current = base2;
|
|
53127
|
-
const parts =
|
|
53342
|
+
const parts = relative11.split("/");
|
|
53128
53343
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
53129
53344
|
current = join39(current, parts[i2]);
|
|
53130
53345
|
try {
|
|
@@ -53143,8 +53358,8 @@ function bundlePath(root, relative10, create2 = false) {
|
|
|
53143
53358
|
}
|
|
53144
53359
|
return current;
|
|
53145
53360
|
}
|
|
53146
|
-
function readBounded(root,
|
|
53147
|
-
const path2 = bundlePath(root,
|
|
53361
|
+
function readBounded(root, relative11, limit = ARP_MAX_BLOB_BYTES) {
|
|
53362
|
+
const path2 = bundlePath(root, relative11);
|
|
53148
53363
|
const fd2 = openSync7(path2, constants3.O_RDONLY | constants3.O_NOFOLLOW);
|
|
53149
53364
|
try {
|
|
53150
53365
|
const stat6 = fstatSync2(fd2);
|
|
@@ -53166,8 +53381,8 @@ function readBounded(root, relative10, limit = ARP_MAX_BLOB_BYTES) {
|
|
|
53166
53381
|
closeSync7(fd2);
|
|
53167
53382
|
}
|
|
53168
53383
|
}
|
|
53169
|
-
function writeNew(root,
|
|
53170
|
-
const path2 = bundlePath(root,
|
|
53384
|
+
function writeNew(root, relative11, bytes) {
|
|
53385
|
+
const path2 = bundlePath(root, relative11, true);
|
|
53171
53386
|
const fd2 = openSync7(
|
|
53172
53387
|
path2,
|
|
53173
53388
|
constants3.O_WRONLY | constants3.O_CREAT | constants3.O_EXCL | constants3.O_NOFOLLOW,
|
|
@@ -54937,7 +55152,7 @@ var init_package = __esm({
|
|
|
54937
55152
|
"package.json"() {
|
|
54938
55153
|
package_default = {
|
|
54939
55154
|
name: "@oxagen/cli",
|
|
54940
|
-
version: "2.1.4-
|
|
55155
|
+
version: "2.1.4-699",
|
|
54941
55156
|
description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
|
|
54942
55157
|
type: "module",
|
|
54943
55158
|
main: "./dist/index.js",
|
|
@@ -61331,15 +61546,305 @@ var init_record_force = __esm({
|
|
|
61331
61546
|
}
|
|
61332
61547
|
});
|
|
61333
61548
|
|
|
61549
|
+
// ../../packages/oxagen/src/steering-repo/harness-files.ts
|
|
61550
|
+
function nameOf(path2) {
|
|
61551
|
+
const cut2 = path2.lastIndexOf("/");
|
|
61552
|
+
return cut2 < 0 ? path2 : path2.slice(cut2 + 1);
|
|
61553
|
+
}
|
|
61554
|
+
function isMarkdown(name) {
|
|
61555
|
+
return name.endsWith(".md") || name.endsWith(".mdc");
|
|
61556
|
+
}
|
|
61557
|
+
function instructionEntryOf(path2) {
|
|
61558
|
+
const name = nameOf(path2);
|
|
61559
|
+
const nested2 = NESTED.get(name) ?? SINGLE.get(name);
|
|
61560
|
+
if (nested2) return nested2;
|
|
61561
|
+
if (path2 === ".github/copilot-instructions.md")
|
|
61562
|
+
return ROOT_FILES.get(path2) ?? null;
|
|
61563
|
+
if (path2.startsWith(".github/instructions/") && name.endsWith(".instructions.md"))
|
|
61564
|
+
return COPILOT_RULES;
|
|
61565
|
+
if (!isMarkdown(name)) return null;
|
|
61566
|
+
const slashed = `/${path2}`;
|
|
61567
|
+
return RULE_FOLDERS.find(({ folder }) => slashed.includes(`/${folder}`))?.entry ?? null;
|
|
61568
|
+
}
|
|
61569
|
+
function classifyHarnessFile(path2) {
|
|
61570
|
+
for (const { folder, entry: entry2 } of SKILL_FOLDERS) {
|
|
61571
|
+
if (!path2.startsWith(folder)) continue;
|
|
61572
|
+
const rest = path2.slice(folder.length);
|
|
61573
|
+
const cut2 = rest.indexOf("/");
|
|
61574
|
+
if (cut2 <= 0) return null;
|
|
61575
|
+
return { ...entry2, path: path2, skillFolder: folder + rest.slice(0, cut2) };
|
|
61576
|
+
}
|
|
61577
|
+
const instruction = instructionEntryOf(path2);
|
|
61578
|
+
if (instruction) return { ...instruction, path: path2, skillFolder: null };
|
|
61579
|
+
const root = ROOT_FILES.get(path2);
|
|
61580
|
+
if (root) return { ...root, path: path2, skillFolder: null };
|
|
61581
|
+
for (const { folder, entry: entry2 } of MARKDOWN_FOLDERS) {
|
|
61582
|
+
if (path2.startsWith(folder) && nameOf(path2).endsWith(".md"))
|
|
61583
|
+
return { ...entry2, path: path2, skillFolder: null };
|
|
61584
|
+
}
|
|
61585
|
+
return null;
|
|
61586
|
+
}
|
|
61587
|
+
var HARNESSES2, HARNESS_FILE_KINDS, CLAUDE_MD, NESTED, SINGLE, RULE_FOLDERS, ROOT_FILES, COPILOT_RULES, MARKDOWN_FOLDERS, SKILL_FOLDERS, SKILL_FILE, HARNESS_FILE_CATALOGUE, WELL_KNOWN_FOLDERS;
|
|
61588
|
+
var init_harness_files = __esm({
|
|
61589
|
+
"../../packages/oxagen/src/steering-repo/harness-files.ts"() {
|
|
61590
|
+
"use strict";
|
|
61591
|
+
HARNESSES2 = [
|
|
61592
|
+
"claude-code",
|
|
61593
|
+
"codex",
|
|
61594
|
+
"cursor",
|
|
61595
|
+
"copilot",
|
|
61596
|
+
"windsurf",
|
|
61597
|
+
"cline",
|
|
61598
|
+
"gemini",
|
|
61599
|
+
"stella"
|
|
61600
|
+
];
|
|
61601
|
+
HARNESS_FILE_KINDS = [
|
|
61602
|
+
"instructions",
|
|
61603
|
+
"personal",
|
|
61604
|
+
"rule",
|
|
61605
|
+
"skill",
|
|
61606
|
+
"command",
|
|
61607
|
+
"subagent",
|
|
61608
|
+
"settings",
|
|
61609
|
+
"mcp-config"
|
|
61610
|
+
];
|
|
61611
|
+
CLAUDE_MD = {
|
|
61612
|
+
pattern: "CLAUDE.md",
|
|
61613
|
+
harnesses: ["claude-code", "stella"],
|
|
61614
|
+
kind: "instructions"
|
|
61615
|
+
};
|
|
61616
|
+
NESTED = /* @__PURE__ */ new Map([
|
|
61617
|
+
["CLAUDE.md", CLAUDE_MD],
|
|
61618
|
+
[
|
|
61619
|
+
"AGENTS.md",
|
|
61620
|
+
{ pattern: "AGENTS.md", harnesses: ["codex", "stella"], kind: "instructions" }
|
|
61621
|
+
],
|
|
61622
|
+
[
|
|
61623
|
+
"AGENTS.override.md",
|
|
61624
|
+
{ pattern: "AGENTS.override.md", harnesses: ["codex"], kind: "instructions" }
|
|
61625
|
+
],
|
|
61626
|
+
[
|
|
61627
|
+
"GEMINI.md",
|
|
61628
|
+
{ pattern: "GEMINI.md", harnesses: ["gemini"], kind: "instructions" }
|
|
61629
|
+
],
|
|
61630
|
+
[
|
|
61631
|
+
"CLAUDE.local.md",
|
|
61632
|
+
{ pattern: "CLAUDE.local.md", harnesses: ["claude-code"], kind: "personal" }
|
|
61633
|
+
]
|
|
61634
|
+
]);
|
|
61635
|
+
SINGLE = /* @__PURE__ */ new Map([
|
|
61636
|
+
[
|
|
61637
|
+
".cursorrules",
|
|
61638
|
+
{ pattern: ".cursorrules", harnesses: ["cursor"], kind: "instructions" }
|
|
61639
|
+
],
|
|
61640
|
+
[
|
|
61641
|
+
".windsurfrules",
|
|
61642
|
+
{ pattern: ".windsurfrules", harnesses: ["windsurf"], kind: "instructions" }
|
|
61643
|
+
],
|
|
61644
|
+
[
|
|
61645
|
+
".clinerules",
|
|
61646
|
+
{ pattern: ".clinerules", harnesses: ["cline"], kind: "instructions" }
|
|
61647
|
+
]
|
|
61648
|
+
]);
|
|
61649
|
+
RULE_FOLDERS = [
|
|
61650
|
+
{
|
|
61651
|
+
folder: ".cursor/rules/",
|
|
61652
|
+
entry: {
|
|
61653
|
+
pattern: ".cursor/rules/*.md, .cursor/rules/*.mdc",
|
|
61654
|
+
harnesses: ["cursor"],
|
|
61655
|
+
kind: "rule"
|
|
61656
|
+
}
|
|
61657
|
+
},
|
|
61658
|
+
{
|
|
61659
|
+
folder: ".windsurf/rules/",
|
|
61660
|
+
entry: {
|
|
61661
|
+
pattern: ".windsurf/rules/*.md",
|
|
61662
|
+
harnesses: ["windsurf"],
|
|
61663
|
+
kind: "rule"
|
|
61664
|
+
}
|
|
61665
|
+
},
|
|
61666
|
+
{
|
|
61667
|
+
folder: ".clinerules/",
|
|
61668
|
+
entry: { pattern: ".clinerules/*.md", harnesses: ["cline"], kind: "rule" }
|
|
61669
|
+
}
|
|
61670
|
+
];
|
|
61671
|
+
ROOT_FILES = /* @__PURE__ */ new Map([
|
|
61672
|
+
[
|
|
61673
|
+
".github/copilot-instructions.md",
|
|
61674
|
+
{
|
|
61675
|
+
pattern: ".github/copilot-instructions.md",
|
|
61676
|
+
harnesses: ["copilot"],
|
|
61677
|
+
kind: "instructions"
|
|
61678
|
+
}
|
|
61679
|
+
],
|
|
61680
|
+
[
|
|
61681
|
+
".claude/settings.json",
|
|
61682
|
+
{
|
|
61683
|
+
pattern: ".claude/settings.json",
|
|
61684
|
+
harnesses: ["claude-code"],
|
|
61685
|
+
kind: "settings"
|
|
61686
|
+
}
|
|
61687
|
+
],
|
|
61688
|
+
[
|
|
61689
|
+
".codex/config.toml",
|
|
61690
|
+
{
|
|
61691
|
+
pattern: ".codex/config.toml",
|
|
61692
|
+
harnesses: ["codex"],
|
|
61693
|
+
kind: "settings"
|
|
61694
|
+
}
|
|
61695
|
+
],
|
|
61696
|
+
[
|
|
61697
|
+
".mcp.json",
|
|
61698
|
+
{ pattern: ".mcp.json", harnesses: ["claude-code"], kind: "mcp-config" }
|
|
61699
|
+
],
|
|
61700
|
+
[
|
|
61701
|
+
".cursor/mcp.json",
|
|
61702
|
+
{
|
|
61703
|
+
pattern: ".cursor/mcp.json",
|
|
61704
|
+
harnesses: ["cursor"],
|
|
61705
|
+
kind: "mcp-config"
|
|
61706
|
+
}
|
|
61707
|
+
]
|
|
61708
|
+
]);
|
|
61709
|
+
COPILOT_RULES = {
|
|
61710
|
+
pattern: ".github/instructions/*.instructions.md",
|
|
61711
|
+
harnesses: ["copilot"],
|
|
61712
|
+
kind: "rule"
|
|
61713
|
+
};
|
|
61714
|
+
MARKDOWN_FOLDERS = [
|
|
61715
|
+
{
|
|
61716
|
+
folder: ".claude/commands/",
|
|
61717
|
+
entry: {
|
|
61718
|
+
pattern: ".claude/commands/*.md",
|
|
61719
|
+
harnesses: ["claude-code", "stella"],
|
|
61720
|
+
kind: "command"
|
|
61721
|
+
}
|
|
61722
|
+
},
|
|
61723
|
+
{
|
|
61724
|
+
folder: ".cursor/commands/",
|
|
61725
|
+
entry: {
|
|
61726
|
+
pattern: ".cursor/commands/*.md",
|
|
61727
|
+
harnesses: ["cursor"],
|
|
61728
|
+
kind: "command"
|
|
61729
|
+
}
|
|
61730
|
+
},
|
|
61731
|
+
{
|
|
61732
|
+
folder: ".claude/agents/",
|
|
61733
|
+
entry: {
|
|
61734
|
+
pattern: ".claude/agents/*.md",
|
|
61735
|
+
harnesses: ["claude-code", "cursor", "stella"],
|
|
61736
|
+
kind: "subagent"
|
|
61737
|
+
}
|
|
61738
|
+
}
|
|
61739
|
+
];
|
|
61740
|
+
SKILL_FOLDERS = [
|
|
61741
|
+
{
|
|
61742
|
+
folder: ".claude/skills/",
|
|
61743
|
+
entry: {
|
|
61744
|
+
pattern: ".claude/skills/<name>/",
|
|
61745
|
+
harnesses: ["claude-code", "cursor", "stella"],
|
|
61746
|
+
kind: "skill"
|
|
61747
|
+
}
|
|
61748
|
+
},
|
|
61749
|
+
{
|
|
61750
|
+
folder: ".agents/skills/",
|
|
61751
|
+
entry: {
|
|
61752
|
+
pattern: ".agents/skills/<name>/",
|
|
61753
|
+
harnesses: ["codex"],
|
|
61754
|
+
kind: "skill"
|
|
61755
|
+
}
|
|
61756
|
+
},
|
|
61757
|
+
{
|
|
61758
|
+
folder: ".cursor/skills/",
|
|
61759
|
+
entry: {
|
|
61760
|
+
pattern: ".cursor/skills/<name>/",
|
|
61761
|
+
harnesses: ["cursor"],
|
|
61762
|
+
kind: "skill"
|
|
61763
|
+
}
|
|
61764
|
+
}
|
|
61765
|
+
];
|
|
61766
|
+
SKILL_FILE = "SKILL.md";
|
|
61767
|
+
HARNESS_FILE_CATALOGUE = [
|
|
61768
|
+
...NESTED.values(),
|
|
61769
|
+
...SINGLE.values(),
|
|
61770
|
+
...RULE_FOLDERS.map((r) => r.entry),
|
|
61771
|
+
COPILOT_RULES,
|
|
61772
|
+
...SKILL_FOLDERS.map((s4) => s4.entry),
|
|
61773
|
+
...MARKDOWN_FOLDERS.map((m) => m.entry),
|
|
61774
|
+
...ROOT_FILES.values()
|
|
61775
|
+
];
|
|
61776
|
+
WELL_KNOWN_FOLDERS = [
|
|
61777
|
+
"",
|
|
61778
|
+
".github",
|
|
61779
|
+
".github/instructions",
|
|
61780
|
+
".claude",
|
|
61781
|
+
".claude/skills",
|
|
61782
|
+
".claude/commands",
|
|
61783
|
+
".claude/agents",
|
|
61784
|
+
".codex",
|
|
61785
|
+
".agents",
|
|
61786
|
+
".agents/skills",
|
|
61787
|
+
".cursor",
|
|
61788
|
+
".cursor/rules",
|
|
61789
|
+
".cursor/skills",
|
|
61790
|
+
".cursor/commands",
|
|
61791
|
+
".windsurf",
|
|
61792
|
+
".windsurf/rules",
|
|
61793
|
+
".clinerules"
|
|
61794
|
+
];
|
|
61795
|
+
}
|
|
61796
|
+
});
|
|
61797
|
+
|
|
61798
|
+
// ../../packages/oxagen/src/steering-repo/record-scope.ts
|
|
61799
|
+
var recordScopeSchema, recordLoadSchema;
|
|
61800
|
+
var init_record_scope = __esm({
|
|
61801
|
+
"../../packages/oxagen/src/steering-repo/record-scope.ts"() {
|
|
61802
|
+
"use strict";
|
|
61803
|
+
init_zod();
|
|
61804
|
+
recordScopeSchema = external_exports.enum([
|
|
61805
|
+
"workspace",
|
|
61806
|
+
"repository",
|
|
61807
|
+
"organization"
|
|
61808
|
+
]);
|
|
61809
|
+
recordLoadSchema = external_exports.enum([
|
|
61810
|
+
"always",
|
|
61811
|
+
"match",
|
|
61812
|
+
"relevant",
|
|
61813
|
+
"mention"
|
|
61814
|
+
]);
|
|
61815
|
+
}
|
|
61816
|
+
});
|
|
61817
|
+
|
|
61334
61818
|
// ../../packages/oxagen/src/contracts/steering.markdown_import.shared.ts
|
|
61335
61819
|
function markdownImportFileCount(rows) {
|
|
61336
|
-
|
|
61820
|
+
let count12 = rows.policies.filter((policy) => policy.action === "add").length;
|
|
61821
|
+
for (const row of rows.records) {
|
|
61822
|
+
if (row.action === "add") count12 += 1 + (row.files?.length ?? 0);
|
|
61823
|
+
}
|
|
61824
|
+
return count12;
|
|
61337
61825
|
}
|
|
61338
61826
|
function markdownImportTooManyFiles(count12) {
|
|
61339
61827
|
if (count12 <= STEERING_PR_MAX_FILES) return null;
|
|
61340
61828
|
return `The import marks ${count12} records and policy files add, and one steering PR holds at most ${STEERING_PR_MAX_FILES} files. Mark ${count12 - STEERING_PR_MAX_FILES} of them skip, or import the files in smaller sets.`;
|
|
61341
61829
|
}
|
|
61342
|
-
|
|
61830
|
+
function markdownImportSourceOf(path2) {
|
|
61831
|
+
const clean = path2.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
61832
|
+
const segments = clean.split("/");
|
|
61833
|
+
const starts = segments.map((segment, at) => segment.startsWith(".") ? at : -1).filter((at) => at >= 0);
|
|
61834
|
+
if (!starts.includes(0)) starts.push(0);
|
|
61835
|
+
for (const at of starts) {
|
|
61836
|
+
const rest = segments.slice(at).join("/");
|
|
61837
|
+
const file = classifyHarnessFile(rest);
|
|
61838
|
+
if (file === null) continue;
|
|
61839
|
+
if (file.kind === "skill" && rest !== `${file.skillFolder}/${SKILL_FILE}`)
|
|
61840
|
+
return null;
|
|
61841
|
+
const kind = markdownImportFileKindSchema.safeParse(file.kind);
|
|
61842
|
+
const harness = markdownImportHarnessSchema.safeParse(file.harnesses[0]);
|
|
61843
|
+
return kind.success && harness.success ? { harness: harness.data, kind: kind.data } : null;
|
|
61844
|
+
}
|
|
61845
|
+
return null;
|
|
61846
|
+
}
|
|
61847
|
+
var MARKDOWN_IMPORT_FILES_MAX, MARKDOWN_IMPORT_FILE_CHARS_MAX, MARKDOWN_IMPORT_STATEMENTS_MAX, MARKDOWN_IMPORT_KIND_REASON_MAX, MARKDOWN_IMPORT_FORCE_WORDS_MAX, MARKDOWN_IMPORT_ROWS_MAX, markdownImportPullRequestFilesSchema, markdownImportTargetSchema, markdownImportHarnessSchema, markdownImportFileKindSchema, markdownImportSourceSchema, MARKDOWN_IMPORT_SKILL_FILES_MAX, markdownImportSkillFileSchema, markdownImportDocumentSchema, markdownImportMatchSchema, markdownImportOriginSchema, markdownImportRecordSchema, markdownImportMemoryMatchReasonSchema, markdownImportMemoryMatchSchema, markdownImportMemorySchema, markdownImportPolicyStatementSchema, markdownImportPolicyIssueSchema, markdownImportPolicySchema, markdownImportFileSchema;
|
|
61343
61848
|
var init_steering_markdown_import_shared = __esm({
|
|
61344
61849
|
"../../packages/oxagen/src/contracts/steering.markdown_import.shared.ts"() {
|
|
61345
61850
|
"use strict";
|
|
@@ -61350,7 +61855,9 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
61350
61855
|
init_names();
|
|
61351
61856
|
init_record_effect();
|
|
61352
61857
|
init_record_force();
|
|
61858
|
+
init_harness_files();
|
|
61353
61859
|
init_record_kind();
|
|
61860
|
+
init_record_scope();
|
|
61354
61861
|
MARKDOWN_IMPORT_FILES_MAX = 25;
|
|
61355
61862
|
MARKDOWN_IMPORT_FILE_CHARS_MAX = 1e5;
|
|
61356
61863
|
MARKDOWN_IMPORT_STATEMENTS_MAX = 50;
|
|
@@ -61370,6 +61877,38 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
61370
61877
|
"memories",
|
|
61371
61878
|
"skip"
|
|
61372
61879
|
]);
|
|
61880
|
+
markdownImportHarnessSchema = external_exports.enum(HARNESSES2).exclude([
|
|
61881
|
+
"stella"
|
|
61882
|
+
]);
|
|
61883
|
+
markdownImportFileKindSchema = external_exports.enum(HARNESS_FILE_KINDS).extract([
|
|
61884
|
+
"instructions",
|
|
61885
|
+
"rule",
|
|
61886
|
+
"skill",
|
|
61887
|
+
"command",
|
|
61888
|
+
"subagent"
|
|
61889
|
+
]);
|
|
61890
|
+
markdownImportSourceSchema = external_exports.object({
|
|
61891
|
+
harness: markdownImportHarnessSchema.describe(
|
|
61892
|
+
"The harness whose format the file is written in"
|
|
61893
|
+
),
|
|
61894
|
+
kind: markdownImportFileKindSchema.describe(
|
|
61895
|
+
"The file's kind in the harness file catalogue"
|
|
61896
|
+
),
|
|
61897
|
+
path: repoPathSchema.max(1024).describe(
|
|
61898
|
+
"The file's path in the repository, such as apps/app/CLAUDE.md. For a skill folder, the path of its SKILL.md."
|
|
61899
|
+
),
|
|
61900
|
+
repository: repoRefSchema.optional().describe(
|
|
61901
|
+
"The linked repository, as <host>/<owner>/<name>. With it, every record gets scope repository and repos set to it."
|
|
61902
|
+
)
|
|
61903
|
+
}).strict();
|
|
61904
|
+
MARKDOWN_IMPORT_SKILL_FILES_MAX = 64;
|
|
61905
|
+
markdownImportSkillFileSchema = external_exports.object({
|
|
61906
|
+
path: external_exports.string().min(1).max(512).regex(
|
|
61907
|
+
/^(?!\/)(?!.*\/\/)(?!(?:.*\/)?\.\.?(?:\/|$))[^\0\\]+$/,
|
|
61908
|
+
"a skill file path is relative, uses /, and names no . or .. segment"
|
|
61909
|
+
).describe("The file's path inside the skill folder, such as scripts/run.sh"),
|
|
61910
|
+
content: external_exports.string().max(MARKDOWN_IMPORT_FILE_CHARS_MAX).describe("The file's text")
|
|
61911
|
+
}).strict();
|
|
61373
61912
|
markdownImportDocumentSchema = external_exports.object({
|
|
61374
61913
|
filename: external_exports.string().min(1).max(256).describe(
|
|
61375
61914
|
"The file's name, or its path relative to the folder imported, such as docs/release.md"
|
|
@@ -61377,8 +61916,40 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
61377
61916
|
content: external_exports.string().min(1).max(MARKDOWN_IMPORT_FILE_CHARS_MAX).describe("The file's Markdown text"),
|
|
61378
61917
|
target: markdownImportTargetSchema.optional().describe(
|
|
61379
61918
|
"records, policies, memories, or skip. Omit it to take the target the file's text implies."
|
|
61919
|
+
),
|
|
61920
|
+
source: markdownImportSourceSchema.optional().describe(
|
|
61921
|
+
"Where the file came from: its harness, its catalogue kind, its path, and the repository. Omit it to read the file as plain Markdown."
|
|
61922
|
+
),
|
|
61923
|
+
files: external_exports.array(markdownImportSkillFileSchema).max(MARKDOWN_IMPORT_SKILL_FILES_MAX).optional().describe(
|
|
61924
|
+
"A skill folder's other text files, by their path inside the folder. Only a source of kind skill carries them."
|
|
61380
61925
|
)
|
|
61381
|
-
}).strict()
|
|
61926
|
+
}).strict().superRefine((document, ctx) => {
|
|
61927
|
+
if (document.files !== void 0 && document.files.length > 0 && document.source?.kind !== "skill") {
|
|
61928
|
+
ctx.addIssue({
|
|
61929
|
+
code: external_exports.ZodIssueCode.custom,
|
|
61930
|
+
path: ["files"],
|
|
61931
|
+
message: "only a document whose source is a skill carries files"
|
|
61932
|
+
});
|
|
61933
|
+
}
|
|
61934
|
+
const paths = /* @__PURE__ */ new Set();
|
|
61935
|
+
for (const file of document.files ?? []) {
|
|
61936
|
+
if (paths.has(file.path)) {
|
|
61937
|
+
ctx.addIssue({
|
|
61938
|
+
code: external_exports.ZodIssueCode.custom,
|
|
61939
|
+
path: ["files"],
|
|
61940
|
+
message: `the skill names ${file.path} twice`
|
|
61941
|
+
});
|
|
61942
|
+
}
|
|
61943
|
+
paths.add(file.path);
|
|
61944
|
+
}
|
|
61945
|
+
if (paths.has(SKILL_FILE)) {
|
|
61946
|
+
ctx.addIssue({
|
|
61947
|
+
code: external_exports.ZodIssueCode.custom,
|
|
61948
|
+
path: ["files"],
|
|
61949
|
+
message: `${SKILL_FILE} is the document's content, not one of its files`
|
|
61950
|
+
});
|
|
61951
|
+
}
|
|
61952
|
+
});
|
|
61382
61953
|
markdownImportMatchSchema = external_exports.object({
|
|
61383
61954
|
lineage: external_exports.string().min(1),
|
|
61384
61955
|
/** Where the matched record lives, or null for a published record with no known path. */
|
|
@@ -61386,7 +61957,12 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
61386
61957
|
/** True for a record already published, false for another row of this import. */
|
|
61387
61958
|
published: external_exports.boolean()
|
|
61388
61959
|
}).strict();
|
|
61389
|
-
markdownImportOriginSchema = external_exports.enum([
|
|
61960
|
+
markdownImportOriginSchema = external_exports.enum([
|
|
61961
|
+
"frontmatter",
|
|
61962
|
+
"split",
|
|
61963
|
+
"rule",
|
|
61964
|
+
"skill"
|
|
61965
|
+
]);
|
|
61390
61966
|
markdownImportRecordSchema = external_exports.object({
|
|
61391
61967
|
file: external_exports.string().min(1).max(256).describe("The file the statement came from"),
|
|
61392
61968
|
line: external_exports.number().int().min(1).describe("The line of the file the statement starts on"),
|
|
@@ -61416,7 +61992,29 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
61416
61992
|
"add or skip. A duplicate defaults to skip. A conflict is null until a person chooses."
|
|
61417
61993
|
),
|
|
61418
61994
|
frontmatter: external_exports.string().max(MARKDOWN_IMPORT_FILE_CHARS_MAX).nullable().describe(
|
|
61419
|
-
"The file's frontmatter
|
|
61995
|
+
"The file's frontmatter YAML: kept for a frontmatter record so the commit keeps its other fields, and shown for a rule or a skill so a person sees what the source said. Null for a split statement, and for a rule or a skill whose file had none."
|
|
61996
|
+
),
|
|
61997
|
+
// The fields below are set only when the document named a source. A row
|
|
61998
|
+
// without them commits as every row did before: workspace scope, no
|
|
61999
|
+
// paths, and the load its force implies.
|
|
62000
|
+
scope: recordScopeSchema.optional().describe(
|
|
62001
|
+
"The record's scope. repository when the source named a repository, else absent, which commits as workspace."
|
|
62002
|
+
),
|
|
62003
|
+
repos: external_exports.array(repoRefSchema).min(1).max(16).optional().describe("The repositories a repository-scoped record reaches."),
|
|
62004
|
+
applies_to: external_exports.array(external_exports.string().min(1).max(512)).min(1).max(64).optional().describe(
|
|
62005
|
+
"The path globs the record is about: a nested file's folder, a Cursor rule's globs, a Copilot rule's applyTo, or a skill's paths."
|
|
62006
|
+
),
|
|
62007
|
+
load: recordLoadSchema.optional().describe(
|
|
62008
|
+
"When the record reaches a request: always, match, relevant, or mention. Absent, the record's force decides."
|
|
62009
|
+
),
|
|
62010
|
+
name: external_exports.string().regex(/^[a-z0-9][a-z0-9-]*$/).max(64).optional().describe(
|
|
62011
|
+
"A skill's folder name, from the source's name field or its file name. Set on a skill row only."
|
|
62012
|
+
),
|
|
62013
|
+
files: external_exports.array(markdownImportSkillFileSchema).max(MARKDOWN_IMPORT_SKILL_FILES_MAX).optional().describe(
|
|
62014
|
+
"A skill folder's other files, written beside its SKILL.md. Set on a skill row only."
|
|
62015
|
+
),
|
|
62016
|
+
dropped: external_exports.array(external_exports.string().min(1).max(200)).max(64).optional().describe(
|
|
62017
|
+
"What the source said that the record cannot hold, each as one line: a frontmatter field the record schema has no place for, a tools list moved to a Cedar policy, or a binary file left out."
|
|
61420
62018
|
)
|
|
61421
62019
|
}).strict().superRefine((row, ctx) => {
|
|
61422
62020
|
if (!forceAllowed(row.kind, row.force)) {
|
|
@@ -61440,11 +62038,46 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
61440
62038
|
message: "only a constraint carries an effect"
|
|
61441
62039
|
});
|
|
61442
62040
|
}
|
|
61443
|
-
if (row.origin === "frontmatter"
|
|
62041
|
+
if (row.origin === "frontmatter" && row.frontmatter === null) {
|
|
62042
|
+
ctx.addIssue({
|
|
62043
|
+
code: external_exports.ZodIssueCode.custom,
|
|
62044
|
+
path: ["frontmatter"],
|
|
62045
|
+
message: "a frontmatter record carries its frontmatter"
|
|
62046
|
+
});
|
|
62047
|
+
}
|
|
62048
|
+
if (row.origin === "split" && row.frontmatter !== null) {
|
|
61444
62049
|
ctx.addIssue({
|
|
61445
62050
|
code: external_exports.ZodIssueCode.custom,
|
|
61446
62051
|
path: ["frontmatter"],
|
|
61447
|
-
message: "a
|
|
62052
|
+
message: "a split statement carries no frontmatter"
|
|
62053
|
+
});
|
|
62054
|
+
}
|
|
62055
|
+
if (row.origin === "skill" && row.kind !== "skill") {
|
|
62056
|
+
ctx.addIssue({
|
|
62057
|
+
code: external_exports.ZodIssueCode.custom,
|
|
62058
|
+
path: ["kind"],
|
|
62059
|
+
message: "a whole skill, command, or subagent file is a skill"
|
|
62060
|
+
});
|
|
62061
|
+
}
|
|
62062
|
+
if (row.origin !== "skill" && (row.files !== void 0 || row.name !== void 0)) {
|
|
62063
|
+
ctx.addIssue({
|
|
62064
|
+
code: external_exports.ZodIssueCode.custom,
|
|
62065
|
+
path: ["files"],
|
|
62066
|
+
message: "only a skill row carries a name and files"
|
|
62067
|
+
});
|
|
62068
|
+
}
|
|
62069
|
+
if (row.scope === "repository" !== (row.repos !== void 0)) {
|
|
62070
|
+
ctx.addIssue({
|
|
62071
|
+
code: external_exports.ZodIssueCode.custom,
|
|
62072
|
+
path: ["repos"],
|
|
62073
|
+
message: "a repository-scoped row names its repos, and no other row does"
|
|
62074
|
+
});
|
|
62075
|
+
}
|
|
62076
|
+
if (row.load === "match" && row.applies_to === void 0) {
|
|
62077
|
+
ctx.addIssue({
|
|
62078
|
+
code: external_exports.ZodIssueCode.custom,
|
|
62079
|
+
path: ["applies_to"],
|
|
62080
|
+
message: "a row that loads on match names the paths it matches"
|
|
61448
62081
|
});
|
|
61449
62082
|
}
|
|
61450
62083
|
});
|
|
@@ -66184,10 +66817,10 @@ var require_resolve_block_map = __commonJS({
|
|
|
66184
66817
|
let offset = bm.offset;
|
|
66185
66818
|
let commentEnd = null;
|
|
66186
66819
|
for (const collItem of bm.items) {
|
|
66187
|
-
const { start, key, sep:
|
|
66820
|
+
const { start, key, sep: sep13, value } = collItem;
|
|
66188
66821
|
const keyProps = resolveProps.resolveProps(start, {
|
|
66189
66822
|
indicator: "explicit-key-ind",
|
|
66190
|
-
next: key ??
|
|
66823
|
+
next: key ?? sep13?.[0],
|
|
66191
66824
|
offset,
|
|
66192
66825
|
onError,
|
|
66193
66826
|
parentIndent: bm.indent,
|
|
@@ -66201,7 +66834,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
66201
66834
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
66202
66835
|
onError(offset, "BAD_INDENT", startColMsg);
|
|
66203
66836
|
}
|
|
66204
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
66837
|
+
if (!keyProps.anchor && !keyProps.tag && !sep13) {
|
|
66205
66838
|
commentEnd = keyProps.end;
|
|
66206
66839
|
if (keyProps.comment) {
|
|
66207
66840
|
if (map.comment)
|
|
@@ -66225,7 +66858,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
66225
66858
|
ctx.atKey = false;
|
|
66226
66859
|
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
|
|
66227
66860
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
66228
|
-
const valueProps = resolveProps.resolveProps(
|
|
66861
|
+
const valueProps = resolveProps.resolveProps(sep13 ?? [], {
|
|
66229
66862
|
indicator: "map-value-ind",
|
|
66230
66863
|
next: value,
|
|
66231
66864
|
offset: keyNode.range[2],
|
|
@@ -66241,7 +66874,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
66241
66874
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
66242
66875
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
66243
66876
|
}
|
|
66244
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset,
|
|
66877
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep13, null, valueProps, onError);
|
|
66245
66878
|
if (ctx.schema.compat)
|
|
66246
66879
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
|
66247
66880
|
offset = valueNode.range[2];
|
|
@@ -66332,7 +66965,7 @@ var require_resolve_end = __commonJS({
|
|
|
66332
66965
|
let comment = "";
|
|
66333
66966
|
if (end) {
|
|
66334
66967
|
let hasSpace = false;
|
|
66335
|
-
let
|
|
66968
|
+
let sep13 = "";
|
|
66336
66969
|
for (const token of end) {
|
|
66337
66970
|
const { source, type } = token;
|
|
66338
66971
|
switch (type) {
|
|
@@ -66346,13 +66979,13 @@ var require_resolve_end = __commonJS({
|
|
|
66346
66979
|
if (!comment)
|
|
66347
66980
|
comment = cb;
|
|
66348
66981
|
else
|
|
66349
|
-
comment +=
|
|
66350
|
-
|
|
66982
|
+
comment += sep13 + cb;
|
|
66983
|
+
sep13 = "";
|
|
66351
66984
|
break;
|
|
66352
66985
|
}
|
|
66353
66986
|
case "newline":
|
|
66354
66987
|
if (comment)
|
|
66355
|
-
|
|
66988
|
+
sep13 += source;
|
|
66356
66989
|
hasSpace = true;
|
|
66357
66990
|
break;
|
|
66358
66991
|
default:
|
|
@@ -66395,18 +67028,18 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
66395
67028
|
let offset = fc.offset + fc.start.source.length;
|
|
66396
67029
|
for (let i2 = 0; i2 < fc.items.length; ++i2) {
|
|
66397
67030
|
const collItem = fc.items[i2];
|
|
66398
|
-
const { start, key, sep:
|
|
67031
|
+
const { start, key, sep: sep13, value } = collItem;
|
|
66399
67032
|
const props = resolveProps.resolveProps(start, {
|
|
66400
67033
|
flow: fcName,
|
|
66401
67034
|
indicator: "explicit-key-ind",
|
|
66402
|
-
next: key ??
|
|
67035
|
+
next: key ?? sep13?.[0],
|
|
66403
67036
|
offset,
|
|
66404
67037
|
onError,
|
|
66405
67038
|
parentIndent: fc.indent,
|
|
66406
67039
|
startOnNewline: false
|
|
66407
67040
|
});
|
|
66408
67041
|
if (!props.found) {
|
|
66409
|
-
if (!props.anchor && !props.tag && !
|
|
67042
|
+
if (!props.anchor && !props.tag && !sep13 && !value) {
|
|
66410
67043
|
if (i2 === 0 && props.comma)
|
|
66411
67044
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
66412
67045
|
else if (i2 < fc.items.length - 1)
|
|
@@ -66460,8 +67093,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
66460
67093
|
}
|
|
66461
67094
|
}
|
|
66462
67095
|
}
|
|
66463
|
-
if (!isMap3 && !
|
|
66464
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
67096
|
+
if (!isMap3 && !sep13 && !props.found) {
|
|
67097
|
+
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep13, null, props, onError);
|
|
66465
67098
|
coll.items.push(valueNode);
|
|
66466
67099
|
offset = valueNode.range[2];
|
|
66467
67100
|
if (isBlock(value))
|
|
@@ -66473,7 +67106,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
66473
67106
|
if (isBlock(key))
|
|
66474
67107
|
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
66475
67108
|
ctx.atKey = false;
|
|
66476
|
-
const valueProps = resolveProps.resolveProps(
|
|
67109
|
+
const valueProps = resolveProps.resolveProps(sep13 ?? [], {
|
|
66477
67110
|
flow: fcName,
|
|
66478
67111
|
indicator: "map-value-ind",
|
|
66479
67112
|
next: value,
|
|
@@ -66484,8 +67117,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
66484
67117
|
});
|
|
66485
67118
|
if (valueProps.found) {
|
|
66486
67119
|
if (!isMap3 && !props.found && ctx.options.strict) {
|
|
66487
|
-
if (
|
|
66488
|
-
for (const st of
|
|
67120
|
+
if (sep13)
|
|
67121
|
+
for (const st of sep13) {
|
|
66489
67122
|
if (st === valueProps.found)
|
|
66490
67123
|
break;
|
|
66491
67124
|
if (st.type === "newline") {
|
|
@@ -66502,7 +67135,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
66502
67135
|
else
|
|
66503
67136
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
66504
67137
|
}
|
|
66505
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
67138
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep13, null, valueProps, onError) : null;
|
|
66506
67139
|
if (valueNode) {
|
|
66507
67140
|
if (isBlock(value))
|
|
66508
67141
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -66682,7 +67315,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
66682
67315
|
chompStart = i2 + 1;
|
|
66683
67316
|
}
|
|
66684
67317
|
let value = "";
|
|
66685
|
-
let
|
|
67318
|
+
let sep13 = "";
|
|
66686
67319
|
let prevMoreIndented = false;
|
|
66687
67320
|
for (let i2 = 0; i2 < contentStart; ++i2)
|
|
66688
67321
|
value += lines[i2][0].slice(trimIndent) + "\n";
|
|
@@ -66699,24 +67332,24 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
66699
67332
|
indent = "";
|
|
66700
67333
|
}
|
|
66701
67334
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
66702
|
-
value +=
|
|
66703
|
-
|
|
67335
|
+
value += sep13 + indent.slice(trimIndent) + content;
|
|
67336
|
+
sep13 = "\n";
|
|
66704
67337
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
66705
|
-
if (
|
|
66706
|
-
|
|
66707
|
-
else if (!prevMoreIndented &&
|
|
66708
|
-
|
|
66709
|
-
value +=
|
|
66710
|
-
|
|
67338
|
+
if (sep13 === " ")
|
|
67339
|
+
sep13 = "\n";
|
|
67340
|
+
else if (!prevMoreIndented && sep13 === "\n")
|
|
67341
|
+
sep13 = "\n\n";
|
|
67342
|
+
value += sep13 + indent.slice(trimIndent) + content;
|
|
67343
|
+
sep13 = "\n";
|
|
66711
67344
|
prevMoreIndented = true;
|
|
66712
67345
|
} else if (content === "") {
|
|
66713
|
-
if (
|
|
67346
|
+
if (sep13 === "\n")
|
|
66714
67347
|
value += "\n";
|
|
66715
67348
|
else
|
|
66716
|
-
|
|
67349
|
+
sep13 = "\n";
|
|
66717
67350
|
} else {
|
|
66718
|
-
value +=
|
|
66719
|
-
|
|
67351
|
+
value += sep13 + content;
|
|
67352
|
+
sep13 = " ";
|
|
66720
67353
|
prevMoreIndented = false;
|
|
66721
67354
|
}
|
|
66722
67355
|
}
|
|
@@ -66899,25 +67532,25 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
66899
67532
|
trimBoth = /^[ \t]+|[ \t]+$/g;
|
|
66900
67533
|
}
|
|
66901
67534
|
let res = match[1].replace(trimEnd, "");
|
|
66902
|
-
let
|
|
67535
|
+
let sep13 = " ";
|
|
66903
67536
|
let pos = line.lastIndex;
|
|
66904
67537
|
while (match = line.exec(source)) {
|
|
66905
67538
|
const lm = match[1].replace(trimBoth, "");
|
|
66906
67539
|
if (lm === "") {
|
|
66907
|
-
if (
|
|
66908
|
-
res +=
|
|
67540
|
+
if (sep13 === "\n")
|
|
67541
|
+
res += sep13;
|
|
66909
67542
|
else
|
|
66910
|
-
|
|
67543
|
+
sep13 = "\n";
|
|
66911
67544
|
} else {
|
|
66912
|
-
res +=
|
|
66913
|
-
|
|
67545
|
+
res += sep13 + lm;
|
|
67546
|
+
sep13 = " ";
|
|
66914
67547
|
}
|
|
66915
67548
|
pos = line.lastIndex;
|
|
66916
67549
|
}
|
|
66917
67550
|
const last = /[ \t]*(.*)/sy;
|
|
66918
67551
|
last.lastIndex = pos;
|
|
66919
67552
|
match = last.exec(source);
|
|
66920
|
-
return res +
|
|
67553
|
+
return res + sep13 + (match?.[1] ?? "");
|
|
66921
67554
|
}
|
|
66922
67555
|
function doubleQuotedValue(source, onError) {
|
|
66923
67556
|
let res = "";
|
|
@@ -67727,14 +68360,14 @@ var require_cst_stringify = __commonJS({
|
|
|
67727
68360
|
}
|
|
67728
68361
|
}
|
|
67729
68362
|
}
|
|
67730
|
-
function stringifyItem({ start, key, sep:
|
|
68363
|
+
function stringifyItem({ start, key, sep: sep13, value }) {
|
|
67731
68364
|
let res = "";
|
|
67732
68365
|
for (const st of start)
|
|
67733
68366
|
res += st.source;
|
|
67734
68367
|
if (key)
|
|
67735
68368
|
res += stringifyToken(key);
|
|
67736
|
-
if (
|
|
67737
|
-
for (const st of
|
|
68369
|
+
if (sep13)
|
|
68370
|
+
for (const st of sep13)
|
|
67738
68371
|
res += st.source;
|
|
67739
68372
|
if (value)
|
|
67740
68373
|
res += stringifyToken(value);
|
|
@@ -68901,18 +69534,18 @@ var require_parser = __commonJS({
|
|
|
68901
69534
|
if (this.type === "map-value-ind") {
|
|
68902
69535
|
const prev = getPrevProps(this.peek(2));
|
|
68903
69536
|
const start = getFirstKeyStartProps(prev);
|
|
68904
|
-
let
|
|
69537
|
+
let sep13;
|
|
68905
69538
|
if (scalar2.end) {
|
|
68906
|
-
|
|
68907
|
-
|
|
69539
|
+
sep13 = scalar2.end;
|
|
69540
|
+
sep13.push(this.sourceToken);
|
|
68908
69541
|
delete scalar2.end;
|
|
68909
69542
|
} else
|
|
68910
|
-
|
|
69543
|
+
sep13 = [this.sourceToken];
|
|
68911
69544
|
const map = {
|
|
68912
69545
|
type: "block-map",
|
|
68913
69546
|
offset: scalar2.offset,
|
|
68914
69547
|
indent: scalar2.indent,
|
|
68915
|
-
items: [{ start, key: scalar2, sep:
|
|
69548
|
+
items: [{ start, key: scalar2, sep: sep13 }]
|
|
68916
69549
|
};
|
|
68917
69550
|
this.onKeyLine = true;
|
|
68918
69551
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -69065,15 +69698,15 @@ var require_parser = __commonJS({
|
|
|
69065
69698
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
69066
69699
|
const start2 = getFirstKeyStartProps(it.start);
|
|
69067
69700
|
const key = it.key;
|
|
69068
|
-
const
|
|
69069
|
-
|
|
69701
|
+
const sep13 = it.sep;
|
|
69702
|
+
sep13.push(this.sourceToken);
|
|
69070
69703
|
delete it.key;
|
|
69071
69704
|
delete it.sep;
|
|
69072
69705
|
this.stack.push({
|
|
69073
69706
|
type: "block-map",
|
|
69074
69707
|
offset: this.offset,
|
|
69075
69708
|
indent: this.indent,
|
|
69076
|
-
items: [{ start: start2, key, sep:
|
|
69709
|
+
items: [{ start: start2, key, sep: sep13 }]
|
|
69077
69710
|
});
|
|
69078
69711
|
} else if (start.length > 0) {
|
|
69079
69712
|
it.sep = it.sep.concat(start, this.sourceToken);
|
|
@@ -69267,13 +69900,13 @@ var require_parser = __commonJS({
|
|
|
69267
69900
|
const prev = getPrevProps(parent);
|
|
69268
69901
|
const start = getFirstKeyStartProps(prev);
|
|
69269
69902
|
fixFlowSeqItems(fc);
|
|
69270
|
-
const
|
|
69271
|
-
|
|
69903
|
+
const sep13 = fc.end.splice(1, fc.end.length);
|
|
69904
|
+
sep13.push(this.sourceToken);
|
|
69272
69905
|
const map = {
|
|
69273
69906
|
type: "block-map",
|
|
69274
69907
|
offset: fc.offset,
|
|
69275
69908
|
indent: fc.indent,
|
|
69276
|
-
items: [{ start, key: fc, sep:
|
|
69909
|
+
items: [{ start, key: fc, sep: sep13 }]
|
|
69277
69910
|
};
|
|
69278
69911
|
this.onKeyLine = true;
|
|
69279
69912
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -71167,166 +71800,940 @@ var init_files = __esm({
|
|
|
71167
71800
|
}
|
|
71168
71801
|
});
|
|
71169
71802
|
|
|
71170
|
-
// ../../packages/
|
|
71171
|
-
|
|
71172
|
-
|
|
71173
|
-
|
|
71174
|
-
|
|
71175
|
-
|
|
71176
|
-
|
|
71177
|
-
|
|
71178
|
-
|
|
71803
|
+
// ../../packages/tacho/src/columns.ts
|
|
71804
|
+
var ENVELOPE_COLUMNS, TACHO_EVENT_COLUMNS;
|
|
71805
|
+
var init_columns = __esm({
|
|
71806
|
+
"../../packages/tacho/src/columns.ts"() {
|
|
71807
|
+
"use strict";
|
|
71808
|
+
init_chain();
|
|
71809
|
+
init_envelope();
|
|
71810
|
+
ENVELOPE_COLUMNS = [
|
|
71811
|
+
// identity (2.1)
|
|
71812
|
+
"host_enrollment_id",
|
|
71813
|
+
"agent_key",
|
|
71814
|
+
"agent_principal_id",
|
|
71815
|
+
"initiating_principal_id",
|
|
71816
|
+
"runtime",
|
|
71817
|
+
"harness",
|
|
71818
|
+
"harness_version",
|
|
71819
|
+
"wrapper_version",
|
|
71820
|
+
"wrapper_attestation",
|
|
71821
|
+
"fidelity",
|
|
71822
|
+
"enforcement_tier",
|
|
71823
|
+
"fleet_id",
|
|
71824
|
+
// anthropic observations (2.2)
|
|
71825
|
+
"anthropic_user_id_hash",
|
|
71826
|
+
"anthropic_account_uuid",
|
|
71827
|
+
"anthropic_account_id",
|
|
71828
|
+
"anthropic_org_uuid",
|
|
71829
|
+
"api_key_source",
|
|
71830
|
+
// session, causality, ordering (2.3)
|
|
71831
|
+
"session_uuid",
|
|
71832
|
+
"harness_session_id",
|
|
71833
|
+
"root_session_uuid",
|
|
71834
|
+
"parent_session_uuid",
|
|
71835
|
+
"subagent_id",
|
|
71836
|
+
"subagent_type",
|
|
71837
|
+
"spawn_depth",
|
|
71838
|
+
"spawn_tool_use_id",
|
|
71839
|
+
"seq",
|
|
71840
|
+
"event_id",
|
|
71841
|
+
"event_id_idem",
|
|
71842
|
+
"ts",
|
|
71843
|
+
"turn_seq",
|
|
71844
|
+
"prompt_id",
|
|
71845
|
+
"turn_id",
|
|
71846
|
+
"trace_id",
|
|
71847
|
+
"span_id",
|
|
71848
|
+
"parent_span_id",
|
|
71849
|
+
"harness_event_sequence",
|
|
71850
|
+
// kind and source (2.4)
|
|
71851
|
+
"kind",
|
|
71852
|
+
"source",
|
|
71853
|
+
"hook_event_name",
|
|
71854
|
+
"hook_source_kind",
|
|
71855
|
+
"otel_event_name",
|
|
71856
|
+
// context (2.5)
|
|
71857
|
+
"cwd",
|
|
71858
|
+
"project_dir",
|
|
71859
|
+
"git_branch",
|
|
71860
|
+
"git_head_sha",
|
|
71861
|
+
"git_remote_digest",
|
|
71862
|
+
"git_dirty",
|
|
71863
|
+
"worktree_path",
|
|
71864
|
+
"worktree_branch",
|
|
71865
|
+
"permission_mode",
|
|
71866
|
+
"effort",
|
|
71867
|
+
"context_model",
|
|
71868
|
+
"entrypoint",
|
|
71869
|
+
"query_source",
|
|
71870
|
+
"session_kind",
|
|
71871
|
+
"terminal_type",
|
|
71872
|
+
"app_version",
|
|
71873
|
+
"output_style",
|
|
71874
|
+
// host (2.14)
|
|
71875
|
+
"hostname_digest",
|
|
71876
|
+
"os_type",
|
|
71877
|
+
"os_version",
|
|
71878
|
+
"host_arch",
|
|
71879
|
+
"os_user_digest",
|
|
71880
|
+
"claude_pid",
|
|
71881
|
+
"claude_ppid",
|
|
71882
|
+
"claude_parent_process",
|
|
71883
|
+
"claude_execpath",
|
|
71884
|
+
"is_child_session",
|
|
71885
|
+
"bridge_session_id",
|
|
71886
|
+
"has_tty",
|
|
71887
|
+
// chain and content (2.13, 2.15)
|
|
71888
|
+
"prev_hash",
|
|
71889
|
+
"hash",
|
|
71890
|
+
"content_digest",
|
|
71891
|
+
"bytes_ref",
|
|
71892
|
+
"redactions",
|
|
71893
|
+
"raw_source_digest",
|
|
71894
|
+
"body",
|
|
71895
|
+
"attrs"
|
|
71896
|
+
];
|
|
71897
|
+
TACHO_EVENT_COLUMNS = [
|
|
71898
|
+
...ENVELOPE_COLUMNS,
|
|
71899
|
+
...BODY_MEMBER_NAMES
|
|
71900
|
+
];
|
|
71179
71901
|
}
|
|
71180
|
-
|
|
71902
|
+
});
|
|
71903
|
+
|
|
71904
|
+
// ../../packages/tacho/src/evidence/merkle.ts
|
|
71905
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
71906
|
+
function digestToBytes(digest7) {
|
|
71907
|
+
if (!SHA256_DIGEST_PATTERN.test(digest7)) {
|
|
71908
|
+
throw new TypeError(`not a sha256 digest: ${digest7}`);
|
|
71909
|
+
}
|
|
71910
|
+
return Buffer.from(digest7.slice("sha256:".length), "hex");
|
|
71181
71911
|
}
|
|
71182
|
-
function
|
|
71183
|
-
|
|
71912
|
+
function hash2(...parts) {
|
|
71913
|
+
const h = createHash17("sha256");
|
|
71914
|
+
for (const part2 of parts) h.update(part2);
|
|
71915
|
+
return h.digest();
|
|
71184
71916
|
}
|
|
71185
|
-
|
|
71186
|
-
|
|
71187
|
-
|
|
71917
|
+
function largestPowerOfTwoBelow(n4) {
|
|
71918
|
+
let k = 1;
|
|
71919
|
+
while (k * 2 < n4) k *= 2;
|
|
71920
|
+
return k;
|
|
71921
|
+
}
|
|
71922
|
+
function treeHash(leaves) {
|
|
71923
|
+
if (leaves.length === 0) return hash2();
|
|
71924
|
+
if (leaves.length === 1) return hash2(LEAF_PREFIX, leaves[0]);
|
|
71925
|
+
const k = largestPowerOfTwoBelow(leaves.length);
|
|
71926
|
+
return hash2(
|
|
71927
|
+
NODE_PREFIX,
|
|
71928
|
+
treeHash(leaves.slice(0, k)),
|
|
71929
|
+
treeHash(leaves.slice(k))
|
|
71930
|
+
);
|
|
71931
|
+
}
|
|
71932
|
+
function merkleRoot(digests) {
|
|
71933
|
+
const leaves = digests.map(digestToBytes);
|
|
71934
|
+
return `sha256:${treeHash(leaves).toString("hex")}`;
|
|
71935
|
+
}
|
|
71936
|
+
var LEAF_PREFIX, NODE_PREFIX;
|
|
71937
|
+
var init_merkle = __esm({
|
|
71938
|
+
"../../packages/tacho/src/evidence/merkle.ts"() {
|
|
71188
71939
|
"use strict";
|
|
71189
|
-
|
|
71190
|
-
|
|
71191
|
-
|
|
71192
|
-
ALWAYS_ON_BODY_WORDS_WARN = 120;
|
|
71193
|
-
SKILL_LINES_WARN = 500;
|
|
71194
|
-
FOLDER_FILES_WARN = 800;
|
|
71195
|
-
RECORD_BYTES_MAX = 256 * 1024;
|
|
71196
|
-
SKILL_ASSET_BYTES_MAX = 1024 * 1024;
|
|
71197
|
-
OPENAPI_BYTES_MAX = 25 * 1024 * 1024;
|
|
71198
|
-
DESCRIPTION_MAX = 200;
|
|
71199
|
-
SKILL_DESCRIPTION_MAX = 1024;
|
|
71940
|
+
init_digest();
|
|
71941
|
+
LEAF_PREFIX = Buffer.from([0]);
|
|
71942
|
+
NODE_PREFIX = Buffer.from([1]);
|
|
71200
71943
|
}
|
|
71201
71944
|
});
|
|
71202
71945
|
|
|
71203
|
-
// ../../packages/
|
|
71204
|
-
|
|
71205
|
-
|
|
71206
|
-
|
|
71207
|
-
|
|
71208
|
-
|
|
71209
|
-
|
|
71210
|
-
|
|
71211
|
-
|
|
71212
|
-
const lines = text5.split("\n");
|
|
71213
|
-
if (lines[0] !== "---") {
|
|
71214
|
-
return {
|
|
71215
|
-
ok: false,
|
|
71216
|
-
issue: {
|
|
71217
|
-
line: 1,
|
|
71218
|
-
field: null,
|
|
71219
|
-
message: "a record starts with --- on its own line"
|
|
71220
|
-
}
|
|
71221
|
-
};
|
|
71946
|
+
// ../../packages/tacho/src/evidence/archive-segment.ts
|
|
71947
|
+
var encoder3, decoder;
|
|
71948
|
+
var init_archive_segment = __esm({
|
|
71949
|
+
"../../packages/tacho/src/evidence/archive-segment.ts"() {
|
|
71950
|
+
"use strict";
|
|
71951
|
+
init_digest();
|
|
71952
|
+
init_merkle();
|
|
71953
|
+
encoder3 = new TextEncoder();
|
|
71954
|
+
decoder = new TextDecoder("utf-8", { fatal: true });
|
|
71222
71955
|
}
|
|
71223
|
-
|
|
71224
|
-
|
|
71225
|
-
|
|
71226
|
-
|
|
71227
|
-
|
|
71228
|
-
|
|
71229
|
-
|
|
71230
|
-
|
|
71231
|
-
|
|
71232
|
-
|
|
71956
|
+
});
|
|
71957
|
+
|
|
71958
|
+
// ../../packages/tacho/src/evidence/transcript-kinds.ts
|
|
71959
|
+
function isTranscriptKind(value) {
|
|
71960
|
+
return typeof value === "string" && TRANSCRIPT_KINDS.includes(value);
|
|
71961
|
+
}
|
|
71962
|
+
var TRANSCRIPT_KINDS;
|
|
71963
|
+
var init_transcript_kinds = __esm({
|
|
71964
|
+
"../../packages/tacho/src/evidence/transcript-kinds.ts"() {
|
|
71965
|
+
"use strict";
|
|
71966
|
+
TRANSCRIPT_KINDS = [
|
|
71967
|
+
/**
|
|
71968
|
+
* The prompt an operator typed to open a turn: a `turn_start` on the run's
|
|
71969
|
+
* own chain. The request half of a model call is the context the model was
|
|
71970
|
+
* sent, and answers no chip.
|
|
71971
|
+
*/
|
|
71972
|
+
"prompt",
|
|
71973
|
+
/**
|
|
71974
|
+
* What came back: a model call's response half or single receipt whose
|
|
71975
|
+
* body was kept, and a reply the harness reported with its words kept
|
|
71976
|
+
* (`turn_end`, or a message recorded as a response).
|
|
71977
|
+
*/
|
|
71978
|
+
"responses",
|
|
71979
|
+
/**
|
|
71980
|
+
* A model call that spent reasoning tokens (`thinking_tokens`). The text of
|
|
71981
|
+
* the reasoning shows where the recorder kept the stream; the count shows
|
|
71982
|
+
* wherever the provider reported it.
|
|
71983
|
+
*/
|
|
71984
|
+
"thinking",
|
|
71985
|
+
/** Either half of a tool call. */
|
|
71986
|
+
"tools",
|
|
71987
|
+
/** A decision a rule or a person made about a call: allow, deny, route. */
|
|
71988
|
+
"policy",
|
|
71989
|
+
/**
|
|
71990
|
+
* A frame that carried a cost record or token counts without one, or a
|
|
71991
|
+
* model call that recorded the reasoning effort it ran at.
|
|
71992
|
+
*/
|
|
71993
|
+
"usage",
|
|
71994
|
+
/** What was pulled into the model's context. */
|
|
71995
|
+
"recall",
|
|
71996
|
+
/**
|
|
71997
|
+
* The run's own stop: the wrapped agent's `agent_stop` on the run's own
|
|
71998
|
+
* chain, or the ledger event that closes an attempt before its seal. The
|
|
71999
|
+
* chain's checkpoints and gaps are read on the Chain tab, not here.
|
|
72000
|
+
*/
|
|
72001
|
+
"seal",
|
|
72002
|
+
/** A call that did not do what it was asked to. */
|
|
72003
|
+
"errors"
|
|
72004
|
+
];
|
|
71233
72005
|
}
|
|
71234
|
-
|
|
71235
|
-
|
|
71236
|
-
|
|
71237
|
-
|
|
71238
|
-
|
|
71239
|
-
|
|
71240
|
-
|
|
71241
|
-
|
|
72006
|
+
});
|
|
72007
|
+
|
|
72008
|
+
// ../../packages/tacho/src/evidence/attestation.ts
|
|
72009
|
+
import {
|
|
72010
|
+
createPrivateKey as createPrivateKey2,
|
|
72011
|
+
createPublicKey as createPublicKey4,
|
|
72012
|
+
sign as sign3,
|
|
72013
|
+
verify as verify5
|
|
72014
|
+
} from "node:crypto";
|
|
72015
|
+
function attestationBytes(payload) {
|
|
72016
|
+
return Buffer.from(jcs(payload), "utf8");
|
|
71242
72017
|
}
|
|
71243
|
-
function
|
|
71244
|
-
|
|
71245
|
-
|
|
71246
|
-
|
|
71247
|
-
|
|
71248
|
-
|
|
71249
|
-
|
|
71250
|
-
|
|
71251
|
-
|
|
71252
|
-
|
|
72018
|
+
function verifyAttestation(attestation, publicKeyPem) {
|
|
72019
|
+
if (attestation.alg !== "ed25519") return false;
|
|
72020
|
+
if (attestation.key_id !== keyIdForPublicKey(publicKeyPem)) return false;
|
|
72021
|
+
try {
|
|
72022
|
+
return verify5(
|
|
72023
|
+
null,
|
|
72024
|
+
attestationBytes(attestation.payload),
|
|
72025
|
+
createPublicKey4(publicKeyPem),
|
|
72026
|
+
Buffer.from(attestation.sig, "base64")
|
|
72027
|
+
);
|
|
72028
|
+
} catch {
|
|
72029
|
+
return false;
|
|
72030
|
+
}
|
|
72031
|
+
}
|
|
72032
|
+
var init_attestation = __esm({
|
|
72033
|
+
"../../packages/tacho/src/evidence/attestation.ts"() {
|
|
72034
|
+
"use strict";
|
|
72035
|
+
init_digest();
|
|
72036
|
+
init_key_id();
|
|
72037
|
+
}
|
|
72038
|
+
});
|
|
72039
|
+
|
|
72040
|
+
// ../../packages/tacho/src/evidence/run-export.ts
|
|
72041
|
+
function normalizeInstant(value) {
|
|
72042
|
+
const m = /^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2})(?:\.(\d+))?(Z|[+-]\d{2}(?::?\d{2})?)$/.exec(
|
|
72043
|
+
value
|
|
72044
|
+
);
|
|
72045
|
+
if (!m) return value;
|
|
72046
|
+
const [, day, time, frac, zone] = m;
|
|
72047
|
+
const ms = (frac ?? "").slice(0, 3).padEnd(3, "0");
|
|
72048
|
+
let offset = zone;
|
|
72049
|
+
if (zone !== "Z") {
|
|
72050
|
+
const digits = zone.slice(1).replace(":", "");
|
|
72051
|
+
offset = `${zone[0]}${digits.slice(0, 2)}:${(digits.slice(2) || "00").padEnd(2, "0")}`;
|
|
72052
|
+
}
|
|
72053
|
+
const instant3 = /* @__PURE__ */ new Date(`${day}T${time}.${ms}${offset}`);
|
|
72054
|
+
return Number.isNaN(instant3.getTime()) ? value : instant3.toISOString();
|
|
72055
|
+
}
|
|
72056
|
+
function wrappedFrameOf(event, bytesRef) {
|
|
72057
|
+
const body2 = asRecord2(event["body"]) ?? {};
|
|
72058
|
+
const content = asRecord2(event["content"]);
|
|
72059
|
+
const turn = asRecord2(event["turn"]);
|
|
72060
|
+
const text5 = (value) => typeof value === "string" ? value : "";
|
|
72061
|
+
const count12 = (value) => typeof value === "number" ? value : null;
|
|
72062
|
+
return {
|
|
72063
|
+
event_id: event["event_id"] ?? null,
|
|
72064
|
+
seq: event["seq"] ?? null,
|
|
72065
|
+
ts: event["ts"] ?? null,
|
|
72066
|
+
kind: event["kind"] ?? null,
|
|
72067
|
+
prev_hash: event["prev_hash"] ?? null,
|
|
72068
|
+
hash: event["hash"] ?? null,
|
|
72069
|
+
content: {
|
|
72070
|
+
digest: content?.["digest"] ?? null,
|
|
72071
|
+
bytes_ref: bytesRef,
|
|
72072
|
+
redactions: content?.["redactions"] ?? []
|
|
71253
72073
|
},
|
|
71254
|
-
|
|
71255
|
-
|
|
71256
|
-
|
|
71257
|
-
|
|
71258
|
-
|
|
71259
|
-
|
|
71260
|
-
|
|
72074
|
+
body: event["body"] ?? null,
|
|
72075
|
+
tool_name: text5(body2["tool_name"]),
|
|
72076
|
+
tool_status: text5(body2["tool_status"]),
|
|
72077
|
+
tool_use_id: text5(body2["tool_use_id"]),
|
|
72078
|
+
model: text5(body2["model"]),
|
|
72079
|
+
provider: text5(body2["provider"]),
|
|
72080
|
+
policy_decision: text5(body2["policy_decision"]),
|
|
72081
|
+
cost_usd_micros: count12(body2["cost_usd_micros"]),
|
|
72082
|
+
turn_seq: count12(turn?.["turn_seq"]),
|
|
72083
|
+
event
|
|
72084
|
+
};
|
|
72085
|
+
}
|
|
72086
|
+
function asRecord2(value) {
|
|
72087
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
72088
|
+
}
|
|
72089
|
+
function tally(counts) {
|
|
72090
|
+
return [...counts.entries()].map(([kind, { count: count12, frames }]) => ({ kind, count: count12, frames })).sort((a, b5) => a.kind.localeCompare(b5.kind));
|
|
72091
|
+
}
|
|
72092
|
+
function summarizeRunExportRedactions(envelopes) {
|
|
72093
|
+
const redacted = /* @__PURE__ */ new Map();
|
|
72094
|
+
const withheld = /* @__PURE__ */ new Map();
|
|
72095
|
+
const bump = (map, kind, count12) => {
|
|
72096
|
+
const entry2 = map.get(kind) ?? { count: 0, frames: 0 };
|
|
72097
|
+
entry2.count += count12;
|
|
72098
|
+
entry2.frames += 1;
|
|
72099
|
+
map.set(kind, entry2);
|
|
72100
|
+
};
|
|
72101
|
+
let total2 = 0;
|
|
72102
|
+
for (const envelope2 of envelopes) {
|
|
72103
|
+
const frame = asRecord2(envelope2);
|
|
72104
|
+
if (!frame) continue;
|
|
72105
|
+
const content = asRecord2(frame["content"]);
|
|
72106
|
+
const list = content?.["redactions"];
|
|
72107
|
+
if (Array.isArray(list)) {
|
|
72108
|
+
const perReason = /* @__PURE__ */ new Map();
|
|
72109
|
+
for (const item of list) {
|
|
72110
|
+
const reason3 = asRecord2(item)?.["reason"];
|
|
72111
|
+
const kind = typeof reason3 === "string" ? reason3 : "unknown";
|
|
72112
|
+
perReason.set(kind, (perReason.get(kind) ?? 0) + 1);
|
|
71261
72113
|
}
|
|
71262
|
-
|
|
71263
|
-
|
|
71264
|
-
|
|
71265
|
-
field: null,
|
|
71266
|
-
message: `the frontmatter uses the YAML tag ${node2.tag}. Remove it.`
|
|
71267
|
-
});
|
|
72114
|
+
for (const [kind, count12] of perReason) {
|
|
72115
|
+
bump(redacted, kind, count12);
|
|
72116
|
+
total2 += count12;
|
|
71268
72117
|
}
|
|
71269
72118
|
}
|
|
72119
|
+
if (typeof content?.["bytes_ref"] === "string") {
|
|
72120
|
+
bump(withheld, WITHHELD_BODY, 1);
|
|
72121
|
+
}
|
|
72122
|
+
if (typeof frame["encrypted_payload_ref"] === "string") {
|
|
72123
|
+
bump(withheld, WITHHELD_ENCRYPTED_PAYLOAD, 1);
|
|
72124
|
+
}
|
|
72125
|
+
}
|
|
72126
|
+
return {
|
|
72127
|
+
format: RUN_EXPORT_REDACTIONS_FORMAT,
|
|
72128
|
+
redacted: tally(redacted),
|
|
72129
|
+
redacted_total: total2,
|
|
72130
|
+
withheld: tally(withheld)
|
|
72131
|
+
};
|
|
72132
|
+
}
|
|
72133
|
+
function digestOf2(frame) {
|
|
72134
|
+
const value = frame["event_digest"] ?? frame["hash"];
|
|
72135
|
+
return typeof value === "string" && DIGEST2.test(value) ? value : null;
|
|
72136
|
+
}
|
|
72137
|
+
function safeDigestJcs(value) {
|
|
72138
|
+
try {
|
|
72139
|
+
return digestJcs(value);
|
|
72140
|
+
} catch {
|
|
72141
|
+
return null;
|
|
72142
|
+
}
|
|
72143
|
+
}
|
|
72144
|
+
function checkWrappedFrame(frame, attemptId) {
|
|
72145
|
+
if (frame["event"] === void 0 || frame["event"] === null) {
|
|
72146
|
+
return { digest: "not_carried", reasons: [] };
|
|
72147
|
+
}
|
|
72148
|
+
const event = asRecord2(frame["event"]);
|
|
72149
|
+
if (!event) {
|
|
72150
|
+
return { digest: "broken", reasons: ["event is not a JSON object"] };
|
|
72151
|
+
}
|
|
72152
|
+
const reasons = [];
|
|
72153
|
+
if (event["session_uuid"] !== attemptId) {
|
|
72154
|
+
reasons.push(
|
|
72155
|
+
`the event belongs to session ${String(event["session_uuid"])}, not ${attemptId}`
|
|
72156
|
+
);
|
|
72157
|
+
}
|
|
72158
|
+
let holds2;
|
|
72159
|
+
try {
|
|
72160
|
+
holds2 = eventHashHolds(event, frame["hash"]);
|
|
72161
|
+
} catch {
|
|
72162
|
+
holds2 = false;
|
|
72163
|
+
}
|
|
72164
|
+
if (!holds2) {
|
|
72165
|
+
reasons.push("the event does not hash to hash");
|
|
72166
|
+
}
|
|
72167
|
+
const content = asRecord2(frame["content"]);
|
|
72168
|
+
const bytesRef = typeof content?.["bytes_ref"] === "string" ? content["bytes_ref"] : null;
|
|
72169
|
+
const expected = wrappedFrameOf(event, bytesRef);
|
|
72170
|
+
const differs2 = [
|
|
72171
|
+
.../* @__PURE__ */ new Set([...Object.keys(expected), ...Object.keys(frame)])
|
|
72172
|
+
].filter((name) => name !== "event").filter((name) => {
|
|
72173
|
+
const shown2 = frame[name];
|
|
72174
|
+
const read2 = expected[name];
|
|
72175
|
+
if (shown2 === void 0 || read2 === void 0) return true;
|
|
72176
|
+
return jcs(shown2) !== jcs(read2);
|
|
72177
|
+
}).sort();
|
|
72178
|
+
if (differs2.length > 0) {
|
|
72179
|
+
const verb = differs2.length === 1 ? "differs" : "differ";
|
|
72180
|
+
reasons.push(`${differs2.join(", ")} ${verb} from the hashed event`);
|
|
72181
|
+
}
|
|
72182
|
+
return { digest: reasons.length > 0 ? "broken" : "held", reasons };
|
|
72183
|
+
}
|
|
72184
|
+
function checkLedgerFrame(frame) {
|
|
72185
|
+
const reasons = [];
|
|
72186
|
+
const payloadDigest = frame["payload_digest"];
|
|
72187
|
+
let digest7 = "held";
|
|
72188
|
+
if (frame["payload_inline"] !== null && frame["payload_inline"] !== void 0) {
|
|
72189
|
+
const recomputed2 = safeDigestJcs(frame["payload_inline"]);
|
|
72190
|
+
if (recomputed2 !== payloadDigest) {
|
|
72191
|
+
digest7 = "broken";
|
|
72192
|
+
reasons.push("payload does not hash to payload_digest");
|
|
72193
|
+
}
|
|
72194
|
+
} else if (typeof frame["encrypted_payload_ref"] !== "string") {
|
|
72195
|
+
digest7 = "broken";
|
|
72196
|
+
reasons.push("frame carries neither a payload nor an encrypted reference");
|
|
72197
|
+
}
|
|
72198
|
+
const recomputed = safeDigestJcs({
|
|
72199
|
+
attempt_seq: frame["attempt_seq"] ?? null,
|
|
72200
|
+
event_schema_version: frame["event_schema_version"] ?? null,
|
|
72201
|
+
event_type: frame["event_type"] ?? null,
|
|
72202
|
+
stage: frame["stage"] ?? null,
|
|
72203
|
+
payload_digest: payloadDigest ?? null,
|
|
72204
|
+
observed_at: typeof frame["observed_at"] === "string" ? normalizeInstant(frame["observed_at"]) : frame["observed_at"] ?? null
|
|
71270
72205
|
});
|
|
71271
|
-
|
|
72206
|
+
if (recomputed !== frame["event_digest"]) {
|
|
72207
|
+
digest7 = "broken";
|
|
72208
|
+
reasons.push("identity fields do not hash to event_digest");
|
|
72209
|
+
}
|
|
72210
|
+
return { digest: digest7, reasons };
|
|
71272
72211
|
}
|
|
71273
|
-
function
|
|
71274
|
-
|
|
71275
|
-
|
|
71276
|
-
|
|
71277
|
-
|
|
71278
|
-
|
|
72212
|
+
function parseJson2(text5, name, checks) {
|
|
72213
|
+
try {
|
|
72214
|
+
return JSON.parse(text5);
|
|
72215
|
+
} catch {
|
|
72216
|
+
checks.push({ name, status: "broken", detail: `${name} is not JSON` });
|
|
72217
|
+
return null;
|
|
72218
|
+
}
|
|
72219
|
+
}
|
|
72220
|
+
function verifyRunExport(files3) {
|
|
72221
|
+
const checks = [];
|
|
72222
|
+
const hold = (name, ok2, held, broken) => checks.push({
|
|
72223
|
+
name,
|
|
72224
|
+
status: ok2 ? "held" : "broken",
|
|
72225
|
+
detail: ok2 ? held : broken
|
|
71279
72226
|
});
|
|
71280
|
-
const
|
|
71281
|
-
|
|
72227
|
+
const manifest = parseJson2(
|
|
72228
|
+
files3["manifest.json"],
|
|
72229
|
+
"manifest",
|
|
72230
|
+
checks
|
|
72231
|
+
);
|
|
72232
|
+
const attestationFile = parseJson2(
|
|
72233
|
+
files3["attestation.json"],
|
|
72234
|
+
"attestation",
|
|
72235
|
+
checks
|
|
72236
|
+
);
|
|
72237
|
+
const raw = files3["frames.ndjson"];
|
|
72238
|
+
const text5 = raw.endsWith("\n") ? raw.slice(0, -1) : raw;
|
|
72239
|
+
const lines = text5.length === 0 ? [] : text5.split("\n");
|
|
72240
|
+
const frames = [];
|
|
72241
|
+
const verdicts = [];
|
|
72242
|
+
lines.forEach((line, i2) => {
|
|
72243
|
+
let parsed2 = null;
|
|
72244
|
+
try {
|
|
72245
|
+
parsed2 = asRecord2(JSON.parse(line));
|
|
72246
|
+
} catch {
|
|
72247
|
+
parsed2 = null;
|
|
72248
|
+
}
|
|
72249
|
+
frames.push(parsed2 ?? {});
|
|
72250
|
+
if (!parsed2) {
|
|
72251
|
+
verdicts.push({
|
|
72252
|
+
line: i2 + 1,
|
|
72253
|
+
attempt_id: "",
|
|
72254
|
+
seq: null,
|
|
72255
|
+
status: "broken",
|
|
72256
|
+
digest: "broken",
|
|
72257
|
+
link: "broken",
|
|
72258
|
+
reasons: ["line is not a JSON object"]
|
|
72259
|
+
});
|
|
72260
|
+
}
|
|
72261
|
+
});
|
|
72262
|
+
if (!manifest || !attestationFile) {
|
|
71282
72263
|
return {
|
|
71283
72264
|
ok: false,
|
|
71284
|
-
|
|
71285
|
-
|
|
71286
|
-
|
|
71287
|
-
|
|
71288
|
-
|
|
71289
|
-
}
|
|
71290
|
-
]
|
|
72265
|
+
run_id: manifest?.run_id ?? null,
|
|
72266
|
+
format: manifest?.format ?? null,
|
|
72267
|
+
frames: verdicts,
|
|
72268
|
+
checks,
|
|
72269
|
+
redactions: null
|
|
71291
72270
|
};
|
|
71292
72271
|
}
|
|
71293
|
-
|
|
71294
|
-
|
|
71295
|
-
|
|
71296
|
-
|
|
71297
|
-
|
|
71298
|
-
|
|
71299
|
-
|
|
71300
|
-
|
|
71301
|
-
|
|
71302
|
-
|
|
71303
|
-
|
|
71304
|
-
|
|
71305
|
-
|
|
71306
|
-
|
|
71307
|
-
|
|
72272
|
+
hold(
|
|
72273
|
+
"format",
|
|
72274
|
+
ACCEPTED_FORMATS.has(manifest.format),
|
|
72275
|
+
manifest.format,
|
|
72276
|
+
`unknown bundle format ${String(manifest.format)}`
|
|
72277
|
+
);
|
|
72278
|
+
hold(
|
|
72279
|
+
"source",
|
|
72280
|
+
typeof manifest.run_id === "string" && (manifest.source === "ledger" && manifest.run_id.startsWith("arun_") || manifest.source === "tacho" && manifest.run_id.startsWith("tse_")),
|
|
72281
|
+
"the source matches the run identifier",
|
|
72282
|
+
"the source is invalid or does not match the run identifier"
|
|
72283
|
+
);
|
|
72284
|
+
const byLine = new Map(verdicts.map((v) => [v.line, v]));
|
|
72285
|
+
let offset = 0;
|
|
72286
|
+
for (const attempt of manifest.attempts ?? []) {
|
|
72287
|
+
let prevHash = null;
|
|
72288
|
+
let prevSeq = null;
|
|
72289
|
+
let stream = EMPTY_EVENT_STREAM_DIGEST;
|
|
72290
|
+
const end = Math.min(offset + attempt.frame_count, frames.length);
|
|
72291
|
+
for (let i2 = offset; i2 < end; i2 += 1) {
|
|
72292
|
+
const line = i2 + 1;
|
|
72293
|
+
if (byLine.has(line)) continue;
|
|
72294
|
+
const frame = frames[i2];
|
|
72295
|
+
const reasons = [];
|
|
72296
|
+
let digest7;
|
|
72297
|
+
let link = "held";
|
|
72298
|
+
let seq = null;
|
|
72299
|
+
if (manifest.source === "ledger") {
|
|
72300
|
+
const own = checkLedgerFrame(frame);
|
|
72301
|
+
digest7 = own.digest;
|
|
72302
|
+
reasons.push(...own.reasons);
|
|
72303
|
+
const attemptSeq = frame["attempt_seq"];
|
|
72304
|
+
seq = typeof attemptSeq === "number" ? attemptSeq : null;
|
|
72305
|
+
const expected = prevSeq === null ? 1 : prevSeq + 1;
|
|
72306
|
+
if (seq !== expected) {
|
|
72307
|
+
link = "broken";
|
|
72308
|
+
reasons.push(`attempt_seq ${String(seq)} where ${expected} was due`);
|
|
71308
72309
|
}
|
|
71309
|
-
|
|
71310
|
-
|
|
72310
|
+
prevSeq = seq;
|
|
72311
|
+
stream = digestJcs({
|
|
72312
|
+
previous: stream,
|
|
72313
|
+
entry: [
|
|
72314
|
+
frame["attempt_seq"] ?? null,
|
|
72315
|
+
frame["event_schema_version"] ?? null,
|
|
72316
|
+
frame["event_type"] ?? null,
|
|
72317
|
+
frame["payload_digest"] ?? null
|
|
72318
|
+
]
|
|
72319
|
+
});
|
|
72320
|
+
} else {
|
|
72321
|
+
const own = checkWrappedFrame(frame, attempt.attempt_id);
|
|
72322
|
+
digest7 = own.digest;
|
|
72323
|
+
reasons.push(...own.reasons);
|
|
72324
|
+
const rawSeq = frame["seq"];
|
|
72325
|
+
seq = typeof rawSeq === "number" ? rawSeq : null;
|
|
72326
|
+
const expectedPrev = prevHash ?? (seq === 0 ? GENESIS_PREV_HASH2 : null);
|
|
72327
|
+
if (expectedPrev !== null && frame["prev_hash"] !== expectedPrev) {
|
|
72328
|
+
link = "broken";
|
|
72329
|
+
reasons.push(
|
|
72330
|
+
prevHash === null ? 'genesis prev_hash is not sha256("")' : "prev_hash is not the previous frame's hash"
|
|
72331
|
+
);
|
|
72332
|
+
}
|
|
72333
|
+
if (prevSeq !== null && seq !== prevSeq + 1) {
|
|
72334
|
+
link = "broken";
|
|
72335
|
+
reasons.push(`seq ${String(seq)} where ${prevSeq + 1} was due`);
|
|
72336
|
+
}
|
|
72337
|
+
prevSeq = seq;
|
|
72338
|
+
prevHash = typeof frame["hash"] === "string" ? frame["hash"] : null;
|
|
72339
|
+
}
|
|
72340
|
+
if (digestOf2(frame) === null) {
|
|
72341
|
+
digest7 = "broken";
|
|
72342
|
+
reasons.push("frame carries no sha256 digest");
|
|
72343
|
+
}
|
|
72344
|
+
verdicts.push({
|
|
72345
|
+
line,
|
|
72346
|
+
attempt_id: attempt.attempt_id,
|
|
72347
|
+
seq,
|
|
72348
|
+
status: digest7 === "broken" || link === "broken" ? "broken" : "held",
|
|
72349
|
+
digest: digest7,
|
|
72350
|
+
link,
|
|
72351
|
+
reasons
|
|
72352
|
+
});
|
|
72353
|
+
}
|
|
72354
|
+
if (manifest.source === "ledger" && typeof attempt.event_stream_digest === "string") {
|
|
72355
|
+
hold(
|
|
72356
|
+
`stream ${attempt.attempt_id}`,
|
|
72357
|
+
stream === attempt.event_stream_digest,
|
|
72358
|
+
"the frames fold to the sealed event_stream_digest",
|
|
72359
|
+
`the frames fold to ${stream}, the seal recorded ${attempt.event_stream_digest}`
|
|
72360
|
+
);
|
|
72361
|
+
}
|
|
72362
|
+
offset += attempt.frame_count;
|
|
71311
72363
|
}
|
|
71312
|
-
|
|
71313
|
-
|
|
71314
|
-
|
|
71315
|
-
|
|
72364
|
+
for (let i2 = offset; i2 < frames.length; i2 += 1) {
|
|
72365
|
+
if (byLine.has(i2 + 1)) continue;
|
|
72366
|
+
verdicts.push({
|
|
72367
|
+
line: i2 + 1,
|
|
72368
|
+
attempt_id: "",
|
|
72369
|
+
seq: null,
|
|
72370
|
+
status: "broken",
|
|
72371
|
+
digest: "broken",
|
|
72372
|
+
link: "broken",
|
|
72373
|
+
reasons: ["frame lies outside every attested attempt"]
|
|
72374
|
+
});
|
|
72375
|
+
}
|
|
72376
|
+
verdicts.sort((a, b5) => a.line - b5.line);
|
|
72377
|
+
hold(
|
|
72378
|
+
"frame count",
|
|
72379
|
+
frames.length === manifest.frame_count,
|
|
72380
|
+
`${frames.length} frames`,
|
|
72381
|
+
`${frames.length} frames where the manifest says ${manifest.frame_count}`
|
|
72382
|
+
);
|
|
72383
|
+
const digests = frames.map(digestOf2);
|
|
72384
|
+
const allDigests = digests.every((d) => d !== null);
|
|
72385
|
+
const root = allDigests ? merkleRoot(digests) : null;
|
|
72386
|
+
hold(
|
|
72387
|
+
"merkle root",
|
|
72388
|
+
root === manifest.merkle_root,
|
|
72389
|
+
`root ${manifest.merkle_root}`,
|
|
72390
|
+
`frames hash to ${root ?? "nothing"}, the manifest says ${manifest.merkle_root}`
|
|
72391
|
+
);
|
|
72392
|
+
const pem = attestationFile.public_key_pem;
|
|
72393
|
+
let keyId = null;
|
|
72394
|
+
try {
|
|
72395
|
+
keyId = keyIdForPublicKey(pem);
|
|
72396
|
+
} catch {
|
|
72397
|
+
keyId = null;
|
|
72398
|
+
}
|
|
72399
|
+
hold(
|
|
72400
|
+
"attester key",
|
|
72401
|
+
keyId !== null && keyId === attestationFile.key_id && keyId === manifest.attester_key_id,
|
|
72402
|
+
`key ${String(keyId)}`,
|
|
72403
|
+
"the bundled public key does not match the recorded key id"
|
|
72404
|
+
);
|
|
72405
|
+
let covered = 0;
|
|
72406
|
+
const attestations = attestationFile.attestations ?? [];
|
|
72407
|
+
attestations.forEach((a, i2) => {
|
|
72408
|
+
const attemptId = a.payload?.attempt_id ?? `#${i2 + 1}`;
|
|
72409
|
+
hold(
|
|
72410
|
+
`signature ${attemptId}`,
|
|
72411
|
+
keyId !== null && verifyAttestation(a, pem),
|
|
72412
|
+
"Ed25519 signature verifies",
|
|
72413
|
+
"the attestation signature does not verify"
|
|
72414
|
+
);
|
|
72415
|
+
const slice = digests.slice(
|
|
72416
|
+
covered,
|
|
72417
|
+
covered + (a.payload?.frame_count ?? 0)
|
|
72418
|
+
);
|
|
72419
|
+
if (manifest.source === "tacho") {
|
|
72420
|
+
const exportedDigest = digestBytes(
|
|
72421
|
+
lines.slice(covered, covered + (a.payload?.frame_count ?? 0)).join("\n")
|
|
72422
|
+
);
|
|
72423
|
+
hold(
|
|
72424
|
+
`exported content ${attemptId}`,
|
|
72425
|
+
exportedDigest === a.payload?.archive_segment_digest,
|
|
72426
|
+
"the exported frame bytes match the signed segment digest",
|
|
72427
|
+
"the exported frame bytes do not match the signed segment digest"
|
|
72428
|
+
);
|
|
72429
|
+
}
|
|
72430
|
+
hold(
|
|
72431
|
+
`run identity ${attemptId}`,
|
|
72432
|
+
a.payload?.run_id === manifest.run_id,
|
|
72433
|
+
"the attestation names this run",
|
|
72434
|
+
"the manifest run differs from the signed run"
|
|
72435
|
+
);
|
|
72436
|
+
covered += a.payload?.frame_count ?? 0;
|
|
72437
|
+
const attemptRoot = slice.every((d) => d !== null) ? merkleRoot(slice) : null;
|
|
72438
|
+
hold(
|
|
72439
|
+
`attested root ${attemptId}`,
|
|
72440
|
+
attemptRoot === a.payload?.merkle_root,
|
|
72441
|
+
"the attempt's frames hash to the signed root",
|
|
72442
|
+
`the attempt's frames hash to ${attemptRoot ?? "nothing"}, the attestation signed ${String(a.payload?.merkle_root)}`
|
|
72443
|
+
);
|
|
72444
|
+
});
|
|
72445
|
+
hold(
|
|
72446
|
+
"coverage",
|
|
72447
|
+
covered === frames.length && attestations.length > 0,
|
|
72448
|
+
"the attestations cover every frame",
|
|
72449
|
+
`the attestations cover ${covered} of ${frames.length} frames`
|
|
72450
|
+
);
|
|
72451
|
+
let redactions = null;
|
|
72452
|
+
const redactionsText = files3["redactions.json"];
|
|
72453
|
+
if (redactionsText !== void 0) {
|
|
72454
|
+
redactions = parseJson2(
|
|
72455
|
+
redactionsText,
|
|
72456
|
+
"redactions",
|
|
72457
|
+
checks
|
|
72458
|
+
);
|
|
72459
|
+
if (redactions) {
|
|
72460
|
+
const recomputed = summarizeRunExportRedactions(frames);
|
|
72461
|
+
hold(
|
|
72462
|
+
"redactions",
|
|
72463
|
+
digestJcs(recomputed) === digestJcs(redactions),
|
|
72464
|
+
`${recomputed.redacted_total} redaction(s) summarised`,
|
|
72465
|
+
"redactions.json does not match what the frames record"
|
|
72466
|
+
);
|
|
71316
72467
|
}
|
|
72468
|
+
} else if (manifest.format !== FORMAT_1) {
|
|
72469
|
+
hold("redactions", false, "", "redactions.json is missing");
|
|
71317
72470
|
}
|
|
72471
|
+
const ok = verdicts.length === frames.length && verdicts.every((v) => v.status === "held") && checks.every((c) => c.status === "held");
|
|
71318
72472
|
return {
|
|
71319
|
-
ok
|
|
71320
|
-
|
|
71321
|
-
|
|
71322
|
-
|
|
71323
|
-
|
|
72473
|
+
ok,
|
|
72474
|
+
run_id: manifest.run_id,
|
|
72475
|
+
format: manifest.format,
|
|
72476
|
+
frames: verdicts,
|
|
72477
|
+
checks,
|
|
72478
|
+
redactions
|
|
71324
72479
|
};
|
|
71325
72480
|
}
|
|
71326
|
-
|
|
71327
|
-
|
|
71328
|
-
|
|
71329
|
-
|
|
72481
|
+
var RUN_EXPORT_FORMAT, FORMAT_1, ACCEPTED_FORMATS, RUN_EXPORT_REDACTIONS_FORMAT, GENESIS_PREV_HASH2, EMPTY_EVENT_STREAM_DIGEST, DIGEST2, WITHHELD_BODY, WITHHELD_ENCRYPTED_PAYLOAD;
|
|
72482
|
+
var init_run_export = __esm({
|
|
72483
|
+
"../../packages/tacho/src/evidence/run-export.ts"() {
|
|
72484
|
+
"use strict";
|
|
72485
|
+
init_chain();
|
|
72486
|
+
init_digest();
|
|
72487
|
+
init_key_id();
|
|
72488
|
+
init_attestation();
|
|
72489
|
+
init_merkle();
|
|
72490
|
+
RUN_EXPORT_FORMAT = "oxagen.run-export/3";
|
|
72491
|
+
FORMAT_1 = "oxagen.run-export/1";
|
|
72492
|
+
ACCEPTED_FORMATS = /* @__PURE__ */ new Set([
|
|
72493
|
+
FORMAT_1,
|
|
72494
|
+
"oxagen.run-export/2",
|
|
72495
|
+
RUN_EXPORT_FORMAT
|
|
72496
|
+
]);
|
|
72497
|
+
RUN_EXPORT_REDACTIONS_FORMAT = "oxagen.run-export.redactions/1";
|
|
72498
|
+
GENESIS_PREV_HASH2 = digestBytes("");
|
|
72499
|
+
EMPTY_EVENT_STREAM_DIGEST = digestJcs([]);
|
|
72500
|
+
DIGEST2 = /^sha256:[0-9a-f]{64}$/;
|
|
72501
|
+
WITHHELD_BODY = "frame_body";
|
|
72502
|
+
WITHHELD_ENCRYPTED_PAYLOAD = "encrypted_payload";
|
|
72503
|
+
}
|
|
72504
|
+
});
|
|
72505
|
+
|
|
72506
|
+
// ../../packages/tacho/src/evidence/index.ts
|
|
72507
|
+
var init_evidence = __esm({
|
|
72508
|
+
"../../packages/tacho/src/evidence/index.ts"() {
|
|
72509
|
+
"use strict";
|
|
72510
|
+
init_archive_segment();
|
|
72511
|
+
init_merkle();
|
|
72512
|
+
init_redaction();
|
|
72513
|
+
init_retention();
|
|
72514
|
+
init_replay_grade();
|
|
72515
|
+
init_transcript_kinds();
|
|
72516
|
+
init_attestation();
|
|
72517
|
+
init_frame_body();
|
|
72518
|
+
init_run_export();
|
|
72519
|
+
}
|
|
72520
|
+
});
|
|
72521
|
+
|
|
72522
|
+
// ../../packages/tacho/src/session-subject.ts
|
|
72523
|
+
var ENRICHMENT_BUDGET_NOTE, ENRICHMENT_LIMIT_NOTE, PARTIAL_NOTE_HEAD, PARTIAL_NOTE_TAIL, escapeRegExp2, NOTE_SOURCE, TRAILING_NOTES, GITHUB_REF_SOURCE;
|
|
72524
|
+
var init_session_subject = __esm({
|
|
72525
|
+
"../../packages/tacho/src/session-subject.ts"() {
|
|
72526
|
+
"use strict";
|
|
72527
|
+
ENRICHMENT_BUDGET_NOTE = " The account covers only the start of the run: its enrichment budget ran out before the rest was read.";
|
|
72528
|
+
ENRICHMENT_LIMIT_NOTE = " The account covers only the start of the run because its transcript reached a read limit.";
|
|
72529
|
+
PARTIAL_NOTE_HEAD = "Evidence is partial: ";
|
|
72530
|
+
PARTIAL_NOTE_TAIL = " recorded bodies were unavailable.";
|
|
72531
|
+
escapeRegExp2 = (text5) => text5.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
72532
|
+
NOTE_SOURCE = [
|
|
72533
|
+
`${escapeRegExp2(PARTIAL_NOTE_HEAD)}\\d+${escapeRegExp2(PARTIAL_NOTE_TAIL)}`,
|
|
72534
|
+
escapeRegExp2(ENRICHMENT_BUDGET_NOTE.trim()),
|
|
72535
|
+
escapeRegExp2(ENRICHMENT_LIMIT_NOTE.trim())
|
|
72536
|
+
].join("|");
|
|
72537
|
+
TRAILING_NOTES = new RegExp(
|
|
72538
|
+
`(?:^|\\s)((?:${NOTE_SOURCE})(?:\\s(?:${NOTE_SOURCE}))*)$`,
|
|
72539
|
+
"u"
|
|
72540
|
+
);
|
|
72541
|
+
GITHUB_REF_SOURCE = String.raw`\bhttps?:\/\/(?:www\.)?github\.com\/[\w.-]+\/[\w.-]+\/(pull|issues)\/(\d+)\S*`;
|
|
72542
|
+
}
|
|
72543
|
+
});
|
|
72544
|
+
|
|
72545
|
+
// ../../packages/tacho/src/session-title.ts
|
|
72546
|
+
var init_session_title = __esm({
|
|
72547
|
+
"../../packages/tacho/src/session-title.ts"() {
|
|
72548
|
+
"use strict";
|
|
72549
|
+
init_session_subject();
|
|
72550
|
+
}
|
|
72551
|
+
});
|
|
72552
|
+
|
|
72553
|
+
// ../../packages/tacho/src/index.ts
|
|
72554
|
+
var init_src4 = __esm({
|
|
72555
|
+
"../../packages/tacho/src/index.ts"() {
|
|
72556
|
+
"use strict";
|
|
72557
|
+
init_chain();
|
|
72558
|
+
init_columns();
|
|
72559
|
+
init_digest();
|
|
72560
|
+
init_envelope();
|
|
72561
|
+
init_harness_limits();
|
|
72562
|
+
init_ids();
|
|
72563
|
+
init_interjection();
|
|
72564
|
+
init_record_basis();
|
|
72565
|
+
init_remote();
|
|
72566
|
+
init_timestamp();
|
|
72567
|
+
init_wire();
|
|
72568
|
+
init_evidence();
|
|
72569
|
+
init_llm_call_dedupe();
|
|
72570
|
+
init_session_subject();
|
|
72571
|
+
init_session_title();
|
|
72572
|
+
init_context_window();
|
|
72573
|
+
}
|
|
72574
|
+
});
|
|
72575
|
+
|
|
72576
|
+
// ../../packages/oxagen/src/steering-repo/tokens.ts
|
|
72577
|
+
function utf8Length(text5) {
|
|
72578
|
+
let bytes = 0;
|
|
72579
|
+
for (const char of text5) {
|
|
72580
|
+
const code = char.codePointAt(0);
|
|
72581
|
+
if (code < 128) bytes += 1;
|
|
72582
|
+
else if (code < 2048) bytes += 2;
|
|
72583
|
+
else if (code < 65536) bytes += 3;
|
|
72584
|
+
else bytes += 4;
|
|
72585
|
+
}
|
|
72586
|
+
return bytes;
|
|
72587
|
+
}
|
|
72588
|
+
function countTokens(text5) {
|
|
72589
|
+
return Math.ceil(utf8Length(text5) / 4);
|
|
72590
|
+
}
|
|
72591
|
+
var DEFAULT_ALWAYS_ON_TOKENS, DEFAULT_WORKSPACE_DEFINITION_BUDGET, DEFAULT_SERVER_DEFINITION_BUDGET, ALWAYS_ON_BODY_WORDS_WARN, SKILL_LINES_WARN, FOLDER_FILES_WARN, RECORD_BYTES_MAX, SKILL_ASSET_BYTES_MAX, OPENAPI_BYTES_MAX, DESCRIPTION_MAX, SKILL_DESCRIPTION_MAX;
|
|
72592
|
+
var init_tokens = __esm({
|
|
72593
|
+
"../../packages/oxagen/src/steering-repo/tokens.ts"() {
|
|
72594
|
+
"use strict";
|
|
72595
|
+
init_src4();
|
|
72596
|
+
DEFAULT_ALWAYS_ON_TOKENS = LARGEST_PREFIX_BUDGET_TOKENS;
|
|
72597
|
+
DEFAULT_WORKSPACE_DEFINITION_BUDGET = 2e4;
|
|
72598
|
+
DEFAULT_SERVER_DEFINITION_BUDGET = 8e3;
|
|
72599
|
+
ALWAYS_ON_BODY_WORDS_WARN = 120;
|
|
72600
|
+
SKILL_LINES_WARN = 500;
|
|
72601
|
+
FOLDER_FILES_WARN = 800;
|
|
72602
|
+
RECORD_BYTES_MAX = 256 * 1024;
|
|
72603
|
+
SKILL_ASSET_BYTES_MAX = 1024 * 1024;
|
|
72604
|
+
OPENAPI_BYTES_MAX = 25 * 1024 * 1024;
|
|
72605
|
+
DESCRIPTION_MAX = 200;
|
|
72606
|
+
SKILL_DESCRIPTION_MAX = 1024;
|
|
72607
|
+
}
|
|
72608
|
+
});
|
|
72609
|
+
|
|
72610
|
+
// ../../packages/oxagen/src/steering-repo/record.ts
|
|
72611
|
+
function effectiveLoad(record) {
|
|
72612
|
+
if (record.load) return record.load;
|
|
72613
|
+
return record.force === "must" || record.force === "should" ? "always" : "relevant";
|
|
72614
|
+
}
|
|
72615
|
+
function isAlwaysOn(record) {
|
|
72616
|
+
return record.status === "active" && (record.force === "must" || record.force === "should") && effectiveLoad(record) === "always";
|
|
72617
|
+
}
|
|
72618
|
+
function splitRecordFile(text5) {
|
|
72619
|
+
const lines = text5.split("\n");
|
|
72620
|
+
if (lines[0] !== "---") {
|
|
72621
|
+
return {
|
|
72622
|
+
ok: false,
|
|
72623
|
+
issue: {
|
|
72624
|
+
line: 1,
|
|
72625
|
+
field: null,
|
|
72626
|
+
message: "a record starts with --- on its own line"
|
|
72627
|
+
}
|
|
72628
|
+
};
|
|
72629
|
+
}
|
|
72630
|
+
const close = lines.indexOf("---", 1);
|
|
72631
|
+
if (close < 0) {
|
|
72632
|
+
return {
|
|
72633
|
+
ok: false,
|
|
72634
|
+
issue: {
|
|
72635
|
+
line: 1,
|
|
72636
|
+
field: null,
|
|
72637
|
+
message: "the frontmatter has no closing --- line"
|
|
72638
|
+
}
|
|
72639
|
+
};
|
|
72640
|
+
}
|
|
72641
|
+
return {
|
|
72642
|
+
ok: true,
|
|
72643
|
+
parts: {
|
|
72644
|
+
frontmatter: lines.slice(1, close).join("\n"),
|
|
72645
|
+
body: lines.slice(close + 1).join("\n"),
|
|
72646
|
+
body_line: close + 2
|
|
72647
|
+
}
|
|
72648
|
+
};
|
|
72649
|
+
}
|
|
72650
|
+
function strictSubsetIssues(doc, lineOf) {
|
|
72651
|
+
const issues = [];
|
|
72652
|
+
const at = (range) => range ? lineOf(range[0]) : null;
|
|
72653
|
+
(0, import_yaml.visit)(doc, {
|
|
72654
|
+
Alias(_key, node2) {
|
|
72655
|
+
issues.push({
|
|
72656
|
+
line: at(node2.range),
|
|
72657
|
+
field: null,
|
|
72658
|
+
message: "the frontmatter uses a YAML alias. Write the value out."
|
|
72659
|
+
});
|
|
72660
|
+
},
|
|
72661
|
+
Node(_key, node2) {
|
|
72662
|
+
if (node2.anchor) {
|
|
72663
|
+
issues.push({
|
|
72664
|
+
line: at(node2.range),
|
|
72665
|
+
field: null,
|
|
72666
|
+
message: "the frontmatter uses a YAML anchor. Write the value out."
|
|
72667
|
+
});
|
|
72668
|
+
}
|
|
72669
|
+
if (node2.tag) {
|
|
72670
|
+
issues.push({
|
|
72671
|
+
line: at(node2.range),
|
|
72672
|
+
field: null,
|
|
72673
|
+
message: `the frontmatter uses the YAML tag ${node2.tag}. Remove it.`
|
|
72674
|
+
});
|
|
72675
|
+
}
|
|
72676
|
+
}
|
|
72677
|
+
});
|
|
72678
|
+
return issues;
|
|
72679
|
+
}
|
|
72680
|
+
function parseFrontmatter(yamlText, firstLine3 = 2) {
|
|
72681
|
+
const counter = new import_yaml.LineCounter();
|
|
72682
|
+
const lineOf = (offset) => counter.linePos(offset).line + firstLine3 - 1;
|
|
72683
|
+
const docs = (0, import_yaml.parseAllDocuments)(yamlText, {
|
|
72684
|
+
lineCounter: counter,
|
|
72685
|
+
uniqueKeys: true
|
|
72686
|
+
});
|
|
72687
|
+
const doc = docs[0];
|
|
72688
|
+
if (docs.length !== 1 || doc === void 0) {
|
|
72689
|
+
return {
|
|
72690
|
+
ok: false,
|
|
72691
|
+
issues: [
|
|
72692
|
+
{
|
|
72693
|
+
line: firstLine3,
|
|
72694
|
+
field: null,
|
|
72695
|
+
message: docs.length === 0 ? "the frontmatter is empty" : "the frontmatter holds more than one YAML document"
|
|
72696
|
+
}
|
|
72697
|
+
]
|
|
72698
|
+
};
|
|
72699
|
+
}
|
|
72700
|
+
const issues = doc.errors.map((error) => ({
|
|
72701
|
+
line: error.linePos ? error.linePos[0].line + firstLine3 - 1 : null,
|
|
72702
|
+
field: null,
|
|
72703
|
+
message: error.message.split("\n", 1)[0]
|
|
72704
|
+
}));
|
|
72705
|
+
issues.push(...strictSubsetIssues(doc, lineOf));
|
|
72706
|
+
if (issues.length > 0) return { ok: false, issues };
|
|
72707
|
+
if (!(0, import_yaml.isMap)(doc.contents)) {
|
|
72708
|
+
return {
|
|
72709
|
+
ok: false,
|
|
72710
|
+
issues: [
|
|
72711
|
+
{
|
|
72712
|
+
line: firstLine3,
|
|
72713
|
+
field: null,
|
|
72714
|
+
message: "the frontmatter is not a mapping of fields"
|
|
72715
|
+
}
|
|
72716
|
+
]
|
|
72717
|
+
};
|
|
72718
|
+
}
|
|
72719
|
+
const key_lines = /* @__PURE__ */ new Map();
|
|
72720
|
+
for (const pair of doc.contents.items) {
|
|
72721
|
+
if ((0, import_yaml.isScalar)(pair.key) && pair.key.range) {
|
|
72722
|
+
key_lines.set(String(pair.key.value), lineOf(pair.key.range[0]));
|
|
72723
|
+
}
|
|
72724
|
+
}
|
|
72725
|
+
return {
|
|
72726
|
+
ok: true,
|
|
72727
|
+
frontmatter: {
|
|
72728
|
+
value: doc.toJS({ maxAliasCount: 0 }),
|
|
72729
|
+
key_lines
|
|
72730
|
+
}
|
|
72731
|
+
};
|
|
72732
|
+
}
|
|
72733
|
+
function readSteeringRecord(text5) {
|
|
72734
|
+
const encoding = encodingIssues(text5);
|
|
72735
|
+
if (encoding.length > 0) return { ok: false, issues: encoding };
|
|
72736
|
+
const split = splitRecordFile(text5);
|
|
71330
72737
|
if (!split.ok) return { ok: false, issues: [split.issue] };
|
|
71331
72738
|
const { frontmatter, body: body2, body_line } = split.parts;
|
|
71332
72739
|
const parsed2 = parseFrontmatter(frontmatter);
|
|
@@ -71365,7 +72772,7 @@ function stampRecord(frontmatter, body2) {
|
|
|
71365
72772
|
const id2 = `rec_${recordSlug(String(frontmatter.lineage))}_${seed.slice(7, 19)}`;
|
|
71366
72773
|
return { id: id2, hash: digest6({ ...preimage, id: id2 }) };
|
|
71367
72774
|
}
|
|
71368
|
-
var import_yaml,
|
|
72775
|
+
var import_yaml, recordStatusSchema, recordOriginSchema, provenanceMemorySchema, recordProvenanceSchema, recordDateSchema, decisionStatusSchema, decisionSourceSchema, decisionFieldsSchema, declassificationShared, textDeclassificationSchema, standingDeclassificationSchema, declassificationFieldsSchema, recordShape, STEERING_RECORD_FIELDS, steeringRecordSchema;
|
|
71369
72776
|
var init_record = __esm({
|
|
71370
72777
|
"../../packages/oxagen/src/steering-repo/record.ts"() {
|
|
71371
72778
|
"use strict";
|
|
@@ -71380,22 +72787,13 @@ var init_record = __esm({
|
|
|
71380
72787
|
init_record_effect();
|
|
71381
72788
|
init_record_force();
|
|
71382
72789
|
init_record_kind();
|
|
72790
|
+
init_record_scope();
|
|
71383
72791
|
init_record_effect();
|
|
71384
72792
|
init_record_force();
|
|
71385
72793
|
init_record_kind();
|
|
71386
|
-
|
|
71387
|
-
"workspace",
|
|
71388
|
-
"repository",
|
|
71389
|
-
"organization"
|
|
71390
|
-
]);
|
|
72794
|
+
init_record_scope();
|
|
71391
72795
|
recordStatusSchema = external_exports.enum(["active", "archived"]);
|
|
71392
72796
|
recordOriginSchema = external_exports.enum(["user", "inferred"]);
|
|
71393
|
-
recordLoadSchema = external_exports.enum([
|
|
71394
|
-
"always",
|
|
71395
|
-
"match",
|
|
71396
|
-
"relevant",
|
|
71397
|
-
"mention"
|
|
71398
|
-
]);
|
|
71399
72797
|
provenanceMemorySchema = external_exports.object({
|
|
71400
72798
|
agent: external_exports.string().nullable(),
|
|
71401
72799
|
run: external_exports.string().nullable(),
|
|
@@ -71706,7 +73104,7 @@ function classifyServer(parts) {
|
|
|
71706
73104
|
return "unknown";
|
|
71707
73105
|
}
|
|
71708
73106
|
function classifySteeringRepoPath(path2) {
|
|
71709
|
-
const root =
|
|
73107
|
+
const root = ROOT_FILES2[path2];
|
|
71710
73108
|
if (root) return root;
|
|
71711
73109
|
const parts = path2.split("/");
|
|
71712
73110
|
if (parts.some((part2) => part2 === "" || part2 === "." || part2 === "..")) {
|
|
@@ -71739,7 +73137,7 @@ function recordLineageFromPath(path2) {
|
|
|
71739
73137
|
return parts[parts.length - 1].slice(0, -3);
|
|
71740
73138
|
return null;
|
|
71741
73139
|
}
|
|
71742
|
-
var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_FILE,
|
|
73140
|
+
var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_FILE, ROOT_FILES2, SERVER_FILES, WORKSPACE_LINK_PATH;
|
|
71743
73141
|
var init_paths2 = __esm({
|
|
71744
73142
|
"../../packages/oxagen/src/steering-repo/paths.ts"() {
|
|
71745
73143
|
"use strict";
|
|
@@ -71762,7 +73160,7 @@ var init_paths2 = __esm({
|
|
|
71762
73160
|
TOOLS_TOML_NAME = "tools.toml";
|
|
71763
73161
|
TOOLS_LOCK_NAME = "tools.lock.json";
|
|
71764
73162
|
LEDGER_FILE = /^(\d{4}(?:-\d{2}(?:-\d{2})?|-W\d{2})?)(?:\.(\d{3}))?\.jsonl$/;
|
|
71765
|
-
|
|
73163
|
+
ROOT_FILES2 = {
|
|
71766
73164
|
[AGENTS_MD_PATH]: "agents-md",
|
|
71767
73165
|
[CLAUDE_MD_PATH]: "claude-md",
|
|
71768
73166
|
[README_PATH]: "readme",
|
|
@@ -72107,1174 +73505,402 @@ var init_codegraph_settings = __esm({
|
|
|
72107
73505
|
"A commit that changes more files than this teaches no co-change."
|
|
72108
73506
|
),
|
|
72109
73507
|
30
|
|
72110
|
-
),
|
|
72111
|
-
bot_authors: setting(
|
|
72112
|
-
uniqueArray(external_exports.string().min(1).max(200), "bot_authors").describe(
|
|
72113
|
-
"Authors whose commits history ignores."
|
|
72114
|
-
),
|
|
72115
|
-
CODEGRAPH_BOT_AUTHORS_DEFAULT
|
|
72116
|
-
),
|
|
72117
|
-
co_change_half_life_days: setting(
|
|
72118
|
-
external_exports.number().int().min(1).describe("A co-change counts half as much after this many days."),
|
|
72119
|
-
365
|
|
72120
|
-
),
|
|
72121
|
-
cross_repo_window_hours: setting(
|
|
72122
|
-
external_exports.number().int().min(1).describe("Commits in two repositories this close together can pair."),
|
|
72123
|
-
24
|
|
72124
|
-
),
|
|
72125
|
-
owner_features: setting(
|
|
72126
|
-
external_exports.boolean().describe("Compute owners from history."),
|
|
72127
|
-
true
|
|
72128
|
-
)
|
|
72129
|
-
}).strict();
|
|
72130
|
-
CODEGRAPH_HISTORY_DEFAULTS = {
|
|
72131
|
-
change_size_cutoff_files: 30,
|
|
72132
|
-
bot_authors: CODEGRAPH_BOT_AUTHORS_DEFAULT,
|
|
72133
|
-
co_change_half_life_days: 365,
|
|
72134
|
-
cross_repo_window_hours: 24,
|
|
72135
|
-
owner_features: true
|
|
72136
|
-
};
|
|
72137
|
-
codegraphDecisionsSchema = external_exports.object({
|
|
72138
|
-
importance_threshold: setting(
|
|
72139
|
-
share().describe(
|
|
72140
|
-
"A signal at or above this importance suggests a decision record. The M4 backtest sets it."
|
|
72141
|
-
),
|
|
72142
|
-
0.7
|
|
72143
|
-
),
|
|
72144
|
-
grouping_window_days: setting(
|
|
72145
|
-
external_exports.number().int().min(1).describe("Signals on one topic within this many days group into one."),
|
|
72146
|
-
7
|
|
72147
|
-
),
|
|
72148
|
-
stale_proposal_days: setting(
|
|
72149
|
-
external_exports.number().int().min(1).describe("A proposal untouched this many days is stale."),
|
|
72150
|
-
30
|
|
72151
|
-
),
|
|
72152
|
-
package_categories: uniqueArray(
|
|
72153
|
-
external_exports.string().min(1).max(100),
|
|
72154
|
-
"package_categories"
|
|
72155
|
-
).optional().describe(
|
|
72156
|
-
"The package categories signals weigh. Unset: the curated list."
|
|
72157
|
-
)
|
|
72158
|
-
}).strict();
|
|
72159
|
-
CODEGRAPH_DECISIONS_DEFAULTS = {
|
|
72160
|
-
importance_threshold: 0.7,
|
|
72161
|
-
grouping_window_days: 7,
|
|
72162
|
-
stale_proposal_days: 30
|
|
72163
|
-
};
|
|
72164
|
-
codegraphHostDefaultSchema = external_exports.enum([
|
|
72165
|
-
"sandbox",
|
|
72166
|
-
"ask",
|
|
72167
|
-
"approval"
|
|
72168
|
-
]);
|
|
72169
|
-
CODEGRAPH_HOST_DEFAULTS = {
|
|
72170
|
-
"read-only": "sandbox",
|
|
72171
|
-
test: "sandbox",
|
|
72172
|
-
build: "sandbox",
|
|
72173
|
-
"local-write": "ask",
|
|
72174
|
-
"remote-write": "approval",
|
|
72175
|
-
destructive: "approval",
|
|
72176
|
-
unknown: "approval"
|
|
72177
|
-
};
|
|
72178
|
-
codegraphScriptsSchema = external_exports.object({
|
|
72179
|
-
host_defaults: external_exports.object({
|
|
72180
|
-
"read-only": setting(
|
|
72181
|
-
codegraphHostDefaultSchema,
|
|
72182
|
-
CODEGRAPH_HOST_DEFAULTS["read-only"]
|
|
72183
|
-
),
|
|
72184
|
-
test: setting(codegraphHostDefaultSchema, CODEGRAPH_HOST_DEFAULTS.test),
|
|
72185
|
-
build: setting(
|
|
72186
|
-
codegraphHostDefaultSchema,
|
|
72187
|
-
CODEGRAPH_HOST_DEFAULTS.build
|
|
72188
|
-
),
|
|
72189
|
-
"local-write": setting(
|
|
72190
|
-
codegraphHostDefaultSchema,
|
|
72191
|
-
CODEGRAPH_HOST_DEFAULTS["local-write"]
|
|
72192
|
-
),
|
|
72193
|
-
"remote-write": setting(
|
|
72194
|
-
codegraphHostDefaultSchema,
|
|
72195
|
-
CODEGRAPH_HOST_DEFAULTS["remote-write"]
|
|
72196
|
-
),
|
|
72197
|
-
destructive: setting(
|
|
72198
|
-
codegraphHostDefaultSchema,
|
|
72199
|
-
CODEGRAPH_HOST_DEFAULTS.destructive
|
|
72200
|
-
),
|
|
72201
|
-
unknown: setting(
|
|
72202
|
-
codegraphHostDefaultSchema,
|
|
72203
|
-
CODEGRAPH_HOST_DEFAULTS.unknown
|
|
72204
|
-
)
|
|
72205
|
-
}).strict().optional().describe(
|
|
72206
|
-
"What a host does with a script of each effect class: run it in a sandbox, ask first, or wait for approval."
|
|
72207
|
-
),
|
|
72208
|
-
trusted_policies: uniqueArray(
|
|
72209
|
-
external_exports.string().min(1).max(200),
|
|
72210
|
-
"trusted_policies"
|
|
72211
|
-
).optional().describe("Script policies the workspace trusts. Unset: none.")
|
|
72212
|
-
}).strict();
|
|
72213
|
-
CODEGRAPH_SCRIPTS_DEFAULTS = {
|
|
72214
|
-
host_defaults: CODEGRAPH_HOST_DEFAULTS,
|
|
72215
|
-
trusted_policies: []
|
|
72216
|
-
};
|
|
72217
|
-
codegraphDomainIdSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9_.-]{0,127}$/, "a domain id is lowercase");
|
|
72218
|
-
codegraphBoundariesSchema = external_exports.object({
|
|
72219
|
-
allowed_crossings: uniqueArray(
|
|
72220
|
-
external_exports.object({
|
|
72221
|
-
from: codegraphDomainIdSchema,
|
|
72222
|
-
to: codegraphDomainIdSchema
|
|
72223
|
-
}).strict(),
|
|
72224
|
-
"allowed_crossings"
|
|
72225
|
-
).optional().describe(
|
|
72226
|
-
"The domain crossings code may make. Unset: the table the current build found."
|
|
72227
|
-
)
|
|
72228
|
-
}).strict();
|
|
72229
|
-
CODEGRAPH_BOUNDARIES_DEFAULTS = {};
|
|
72230
|
-
codegraphBudgetsSchema = external_exports.object({
|
|
72231
|
-
answer_budget_tokens: setting(
|
|
72232
|
-
external_exports.number().int().min(1).describe(
|
|
72233
|
-
"The default token budget of one answer. The spending cap is on the AI models and keys screen."
|
|
72234
|
-
),
|
|
72235
|
-
4e3
|
|
72236
|
-
)
|
|
72237
|
-
}).strict();
|
|
72238
|
-
CODEGRAPH_BUDGETS_DEFAULTS = {
|
|
72239
|
-
answer_budget_tokens: 4e3
|
|
72240
|
-
};
|
|
72241
|
-
codegraphFreshnessSchema = external_exports.object({
|
|
72242
|
-
lag_window_minutes: setting(
|
|
72243
|
-
external_exports.number().int().min(1).describe(
|
|
72244
|
-
"The freshness check fails when the graph lags the code this long."
|
|
72245
|
-
),
|
|
72246
|
-
30
|
|
72247
|
-
),
|
|
72248
|
-
revision_retention_days: setting(
|
|
72249
|
-
external_exports.number().int().min(1).describe("Days a default-branch revision is kept."),
|
|
72250
|
-
90
|
|
72251
|
-
),
|
|
72252
|
-
pr_copy_retention_days: setting(
|
|
72253
|
-
external_exports.number().int().min(0).describe("Days a PR copy is kept after the PR closes."),
|
|
72254
|
-
7
|
|
72255
|
-
)
|
|
72256
|
-
}).strict();
|
|
72257
|
-
CODEGRAPH_FRESHNESS_DEFAULTS = {
|
|
72258
|
-
lag_window_minutes: 30,
|
|
72259
|
-
revision_retention_days: 90,
|
|
72260
|
-
pr_copy_retention_days: 7
|
|
72261
|
-
};
|
|
72262
|
-
CODEGRAPH_SETTINGS_GROUPS = [
|
|
72263
|
-
{
|
|
72264
|
-
group: "sources",
|
|
72265
|
-
id: "codegraph-sources/v1",
|
|
72266
|
-
title: "Code graph sources",
|
|
72267
|
-
description: "codegraph/sources.toml: the source tags each linked code repository carries.",
|
|
72268
|
-
schema: codegraphSourcesSchema,
|
|
72269
|
-
defaults: CODEGRAPH_SOURCES_DEFAULTS,
|
|
72270
|
-
timing: "next_build"
|
|
72271
|
-
},
|
|
72272
|
-
{
|
|
72273
|
-
group: "indexing",
|
|
72274
|
-
id: "codegraph-indexing/v1",
|
|
72275
|
-
title: "Code graph indexing",
|
|
72276
|
-
description: "codegraph/indexing.toml: the file size limit, skipped paths, live cloud inventory, and per-repository SCIP and version lookup.",
|
|
72277
|
-
schema: codegraphIndexingSchema,
|
|
72278
|
-
defaults: CODEGRAPH_INDEXING_DEFAULTS,
|
|
72279
|
-
timing: "next_build"
|
|
72280
|
-
},
|
|
72281
|
-
{
|
|
72282
|
-
group: "models",
|
|
72283
|
-
id: "codegraph-models/v1",
|
|
72284
|
-
title: "Code graph AI models and keys",
|
|
72285
|
-
description: "codegraph/models.toml: the key source, the model for each task, call mode, providers, and escalation limits. The key itself is never stored here.",
|
|
72286
|
-
schema: codegraphModelsSchema,
|
|
72287
|
-
defaults: CODEGRAPH_MODELS_DEFAULTS,
|
|
72288
|
-
timing: "next_build"
|
|
72289
|
-
},
|
|
72290
|
-
{
|
|
72291
|
-
group: "embeddings",
|
|
72292
|
-
id: "codegraph-embeddings/v1",
|
|
72293
|
-
title: "Code graph embeddings",
|
|
72294
|
-
description: "codegraph/embeddings.toml: whether builds embed cards, and with the Oxagen provider or the workspace's own endpoint.",
|
|
72295
|
-
schema: codegraphEmbeddingsSchema,
|
|
72296
|
-
defaults: CODEGRAPH_EMBEDDINGS_DEFAULTS,
|
|
72297
|
-
timing: "next_build"
|
|
72298
|
-
},
|
|
72299
|
-
{
|
|
72300
|
-
group: "local",
|
|
72301
|
-
id: "codegraph-local/v1",
|
|
72302
|
-
title: "Code graph local graphs",
|
|
72303
|
-
description: "codegraph/local.toml: whether operators may build local graphs, the watch debounce, the memory limit, and local SCIP.",
|
|
72304
|
-
schema: codegraphLocalSchema,
|
|
72305
|
-
defaults: CODEGRAPH_LOCAL_DEFAULTS,
|
|
72306
|
-
timing: "next_build"
|
|
72307
|
-
},
|
|
72308
|
-
{
|
|
72309
|
-
group: "confidence",
|
|
72310
|
-
id: "codegraph-confidence/v1",
|
|
72311
|
-
title: "Code graph confidence",
|
|
72312
|
-
description: "codegraph/confidence.toml: the confidence of each provenance, the default minConfidence, and the agent link limits.",
|
|
72313
|
-
schema: codegraphConfidenceSchema,
|
|
72314
|
-
defaults: CODEGRAPH_CONFIDENCE_DEFAULTS,
|
|
72315
|
-
timing: "next_call"
|
|
72316
|
-
},
|
|
72317
|
-
{
|
|
72318
|
-
group: "domains",
|
|
72319
|
-
id: "codegraph-domains/v1",
|
|
72320
|
-
title: "Code graph domains",
|
|
72321
|
-
description: "codegraph/domains.toml: the tag score, the close-call margin and limit, and the regrouping threshold.",
|
|
72322
|
-
schema: codegraphDomainsSchema,
|
|
72323
|
-
defaults: CODEGRAPH_DOMAINS_DEFAULTS,
|
|
72324
|
-
timing: "next_build"
|
|
72325
|
-
},
|
|
72326
|
-
{
|
|
72327
|
-
group: "history",
|
|
72328
|
-
id: "codegraph-history/v1",
|
|
72329
|
-
title: "Code graph history",
|
|
72330
|
-
description: "codegraph/history.toml: the change-size cutoff, bot authors, co-change half-life, cross-repository window, and owner features.",
|
|
72331
|
-
schema: codegraphHistorySchema,
|
|
72332
|
-
defaults: CODEGRAPH_HISTORY_DEFAULTS,
|
|
72333
|
-
timing: "next_build"
|
|
72334
|
-
},
|
|
72335
|
-
{
|
|
72336
|
-
group: "decisions",
|
|
72337
|
-
id: "codegraph-decisions/v1",
|
|
72338
|
-
title: "Code graph decision records",
|
|
72339
|
-
description: "codegraph/decisions.toml: the importance threshold, grouping window, stale-proposal age, and package categories.",
|
|
72340
|
-
schema: codegraphDecisionsSchema,
|
|
72341
|
-
defaults: CODEGRAPH_DECISIONS_DEFAULTS,
|
|
72342
|
-
timing: "next_build"
|
|
72343
|
-
},
|
|
72344
|
-
{
|
|
72345
|
-
group: "scripts",
|
|
72346
|
-
id: "codegraph-scripts/v1",
|
|
72347
|
-
title: "Code graph scripts",
|
|
72348
|
-
description: "codegraph/scripts.toml: the host default for each effect class and the trusted script policies.",
|
|
72349
|
-
schema: codegraphScriptsSchema,
|
|
72350
|
-
defaults: CODEGRAPH_SCRIPTS_DEFAULTS,
|
|
72351
|
-
timing: "next_call"
|
|
72352
|
-
},
|
|
72353
|
-
{
|
|
72354
|
-
group: "boundaries",
|
|
72355
|
-
id: "codegraph-boundaries/v1",
|
|
72356
|
-
title: "Code graph boundaries",
|
|
72357
|
-
description: "codegraph/boundaries.toml: the crossings allowed between domains.",
|
|
72358
|
-
schema: codegraphBoundariesSchema,
|
|
72359
|
-
defaults: CODEGRAPH_BOUNDARIES_DEFAULTS,
|
|
72360
|
-
timing: "next_call"
|
|
72361
|
-
},
|
|
72362
|
-
{
|
|
72363
|
-
group: "budgets",
|
|
72364
|
-
id: "codegraph-budgets/v1",
|
|
72365
|
-
title: "Code graph budgets",
|
|
72366
|
-
description: "codegraph/budgets.toml: the default answer budget.",
|
|
72367
|
-
schema: codegraphBudgetsSchema,
|
|
72368
|
-
defaults: CODEGRAPH_BUDGETS_DEFAULTS,
|
|
72369
|
-
timing: "next_call"
|
|
72370
|
-
},
|
|
72371
|
-
{
|
|
72372
|
-
group: "freshness",
|
|
72373
|
-
id: "codegraph-freshness/v1",
|
|
72374
|
-
title: "Code graph freshness and retention",
|
|
72375
|
-
description: "codegraph/freshness.toml: the CI check's lag window and how long revisions and PR copies are kept.",
|
|
72376
|
-
schema: codegraphFreshnessSchema,
|
|
72377
|
-
defaults: CODEGRAPH_FRESHNESS_DEFAULTS,
|
|
72378
|
-
timing: "next_build"
|
|
72379
|
-
}
|
|
72380
|
-
];
|
|
72381
|
-
}
|
|
72382
|
-
});
|
|
72383
|
-
|
|
72384
|
-
// ../../packages/oxagen/src/steering-repo/governance.ts
|
|
72385
|
-
var ledgerRotationSchema, governanceSchema;
|
|
72386
|
-
var init_governance = __esm({
|
|
72387
|
-
"../../packages/oxagen/src/steering-repo/governance.ts"() {
|
|
72388
|
-
"use strict";
|
|
72389
|
-
init_zod();
|
|
72390
|
-
init_context_steering_shared();
|
|
72391
|
-
init_common();
|
|
72392
|
-
init_json_schema();
|
|
72393
|
-
init_tokens();
|
|
72394
|
-
ledgerRotationSchema = external_exports.enum(["day", "week", "month", "year"]);
|
|
72395
|
-
governanceSchema = withRules(
|
|
72396
|
-
external_exports.object({
|
|
72397
|
-
schema: external_exports.literal("governance/v1"),
|
|
72398
|
-
mode: governanceModeSchema,
|
|
72399
|
-
steering: external_exports.object({
|
|
72400
|
-
always_on_tokens: external_exports.union([external_exports.number().int().positive(), external_exports.literal("off")]).optional().describe(
|
|
72401
|
-
"The always-on budget per code repository, or off. Unset inherits Oxagen's default, which only warns."
|
|
72402
|
-
)
|
|
72403
|
-
}).strict().optional(),
|
|
72404
|
-
ledger: external_exports.object({
|
|
72405
|
-
rotate: ledgerRotationSchema.optional(),
|
|
72406
|
-
max_lines: external_exports.number().int().positive().optional().describe("A new file starts here even mid-period.")
|
|
72407
|
-
}).strict().optional(),
|
|
72408
|
-
// `recall_unreviewed` left the memory table on 2026-09-30, because
|
|
72409
|
-
// Oxagen no longer recalls a memory that waits for review (ADR-238).
|
|
72410
|
-
memory: external_exports.object({
|
|
72411
|
-
batch_size: external_exports.number().int().positive().optional().describe("Memories per memory PR."),
|
|
72412
|
-
retire_after_days: external_exports.number().int().positive().optional(),
|
|
72413
|
-
auto_merge: external_exports.boolean().optional().describe("Allowed in solo mode only.")
|
|
72414
|
-
}).strict().optional(),
|
|
72415
|
-
reviewers: external_exports.array(
|
|
72416
|
-
external_exports.object({
|
|
72417
|
-
paths: external_exports.array(external_exports.string().min(1)).min(1),
|
|
72418
|
-
group: organizationSlugSchema
|
|
72419
|
-
}).strict()
|
|
72420
|
-
).optional().describe(
|
|
72421
|
-
"Route the folders a pull request changes to a reviewer group."
|
|
72422
|
-
)
|
|
72423
|
-
}).strict(),
|
|
72424
|
-
[
|
|
72425
|
-
{
|
|
72426
|
-
kind: "equals",
|
|
72427
|
-
when: { field: "mode", isNot: "solo" },
|
|
72428
|
-
path: ["memory", "auto_merge"],
|
|
72429
|
-
value: false
|
|
72430
|
-
}
|
|
72431
|
-
]
|
|
72432
|
-
);
|
|
72433
|
-
}
|
|
72434
|
-
});
|
|
72435
|
-
|
|
72436
|
-
// ../../packages/oxagen/src/steering-repo/health.ts
|
|
72437
|
-
var REPO_HEALTH_STATES, repoHealthSchema, settingsDifferenceSchema;
|
|
72438
|
-
var init_health = __esm({
|
|
72439
|
-
"../../packages/oxagen/src/steering-repo/health.ts"() {
|
|
72440
|
-
"use strict";
|
|
72441
|
-
init_zod();
|
|
72442
|
-
init_common();
|
|
72443
|
-
REPO_HEALTH_STATES = [
|
|
72444
|
-
"healthy",
|
|
72445
|
-
"drifted",
|
|
72446
|
-
"disconnected",
|
|
72447
|
-
"diverged"
|
|
72448
|
-
];
|
|
72449
|
-
repoHealthSchema = external_exports.enum(REPO_HEALTH_STATES);
|
|
72450
|
-
settingsDifferenceSchema = external_exports.object({
|
|
72451
|
-
setting: external_exports.string().min(1).describe(
|
|
72452
|
-
"The setting's path in the baseline, such as rulesets.oxagen_merges."
|
|
72453
|
-
),
|
|
72454
|
-
expected: external_exports.unknown(),
|
|
72455
|
-
actual: external_exports.unknown(),
|
|
72456
|
-
changed_by: external_exports.string().nullable(),
|
|
72457
|
-
changed_at: instantSchema2.nullable()
|
|
72458
|
-
}).strict();
|
|
72459
|
-
}
|
|
72460
|
-
});
|
|
72461
|
-
|
|
72462
|
-
// ../../packages/oxagen/src/steering-repo/promotion.ts
|
|
72463
|
-
var promotionChangeSchema, branchSchema, promotionSchema;
|
|
72464
|
-
var init_promotion = __esm({
|
|
72465
|
-
"../../packages/oxagen/src/steering-repo/promotion.ts"() {
|
|
72466
|
-
"use strict";
|
|
72467
|
-
init_zod();
|
|
72468
|
-
init_src3();
|
|
72469
|
-
init_context_steering_shared();
|
|
72470
|
-
init_common();
|
|
72471
|
-
init_names();
|
|
72472
|
-
promotionChangeSchema = external_exports.object({
|
|
72473
|
-
path: repoPathSchema,
|
|
72474
|
-
action: external_exports.enum(["added", "modified", "removed"]),
|
|
72475
|
-
lineage: lineageSchema.optional(),
|
|
72476
|
-
id: recordIdSchema.optional(),
|
|
72477
|
-
hash: sha256Schema2.optional(),
|
|
72478
|
-
replaces: recordIdSchema.optional().describe(
|
|
72479
|
-
"The id this record had before a format change, such as the v0.1 conversion."
|
|
72480
|
-
)
|
|
72481
|
-
}).strict();
|
|
72482
|
-
branchSchema = external_exports.string().regex(new RegExp(`^(?:${BRANCH_PREFIXES.join("|")})/.+$`)).describe("Starts with the top-level folder the change touches.");
|
|
72483
|
-
promotionSchema = external_exports.object({
|
|
72484
|
-
schema: external_exports.literal("promotion/v1"),
|
|
72485
|
-
seq: external_exports.number().int().min(1).describe("The line's place in the whole chain, across files."),
|
|
72486
|
-
at: instantSchema2,
|
|
72487
|
-
pull_request: external_exports.object({
|
|
72488
|
-
provider: repositoryProviderSchema,
|
|
72489
|
-
number: external_exports.number().int().positive()
|
|
72490
|
-
}).strict(),
|
|
72491
|
-
branch: branchSchema,
|
|
72492
|
-
mode: governanceModeSchema,
|
|
72493
|
-
approved_by: external_exports.array(actorSchema),
|
|
72494
|
-
merged_by: actorSchema,
|
|
72495
|
-
without_review: external_exports.boolean().describe(
|
|
72496
|
-
"True when the owner, or a role with merge_pr_without_review, merged without an approval."
|
|
72497
|
-
),
|
|
72498
|
-
changes: external_exports.array(promotionChangeSchema).min(1),
|
|
72499
|
-
prev: sha256Schema2.nullable().describe(
|
|
72500
|
-
"The hash of the line before, or null on the first line of the chain."
|
|
72501
|
-
),
|
|
72502
|
-
hash: sha256Schema2.describe(
|
|
72503
|
-
"sha256 over the RFC 8785 canonical JSON of this line without hash."
|
|
72504
|
-
)
|
|
72505
|
-
}).strict();
|
|
72506
|
-
}
|
|
72507
|
-
});
|
|
72508
|
-
|
|
72509
|
-
// ../../packages/tacho/src/columns.ts
|
|
72510
|
-
var ENVELOPE_COLUMNS, TACHO_EVENT_COLUMNS;
|
|
72511
|
-
var init_columns = __esm({
|
|
72512
|
-
"../../packages/tacho/src/columns.ts"() {
|
|
72513
|
-
"use strict";
|
|
72514
|
-
init_chain();
|
|
72515
|
-
init_envelope();
|
|
72516
|
-
ENVELOPE_COLUMNS = [
|
|
72517
|
-
// identity (2.1)
|
|
72518
|
-
"host_enrollment_id",
|
|
72519
|
-
"agent_key",
|
|
72520
|
-
"agent_principal_id",
|
|
72521
|
-
"initiating_principal_id",
|
|
72522
|
-
"runtime",
|
|
72523
|
-
"harness",
|
|
72524
|
-
"harness_version",
|
|
72525
|
-
"wrapper_version",
|
|
72526
|
-
"wrapper_attestation",
|
|
72527
|
-
"fidelity",
|
|
72528
|
-
"enforcement_tier",
|
|
72529
|
-
"fleet_id",
|
|
72530
|
-
// anthropic observations (2.2)
|
|
72531
|
-
"anthropic_user_id_hash",
|
|
72532
|
-
"anthropic_account_uuid",
|
|
72533
|
-
"anthropic_account_id",
|
|
72534
|
-
"anthropic_org_uuid",
|
|
72535
|
-
"api_key_source",
|
|
72536
|
-
// session, causality, ordering (2.3)
|
|
72537
|
-
"session_uuid",
|
|
72538
|
-
"harness_session_id",
|
|
72539
|
-
"root_session_uuid",
|
|
72540
|
-
"parent_session_uuid",
|
|
72541
|
-
"subagent_id",
|
|
72542
|
-
"subagent_type",
|
|
72543
|
-
"spawn_depth",
|
|
72544
|
-
"spawn_tool_use_id",
|
|
72545
|
-
"seq",
|
|
72546
|
-
"event_id",
|
|
72547
|
-
"event_id_idem",
|
|
72548
|
-
"ts",
|
|
72549
|
-
"turn_seq",
|
|
72550
|
-
"prompt_id",
|
|
72551
|
-
"turn_id",
|
|
72552
|
-
"trace_id",
|
|
72553
|
-
"span_id",
|
|
72554
|
-
"parent_span_id",
|
|
72555
|
-
"harness_event_sequence",
|
|
72556
|
-
// kind and source (2.4)
|
|
72557
|
-
"kind",
|
|
72558
|
-
"source",
|
|
72559
|
-
"hook_event_name",
|
|
72560
|
-
"hook_source_kind",
|
|
72561
|
-
"otel_event_name",
|
|
72562
|
-
// context (2.5)
|
|
72563
|
-
"cwd",
|
|
72564
|
-
"project_dir",
|
|
72565
|
-
"git_branch",
|
|
72566
|
-
"git_head_sha",
|
|
72567
|
-
"git_remote_digest",
|
|
72568
|
-
"git_dirty",
|
|
72569
|
-
"worktree_path",
|
|
72570
|
-
"worktree_branch",
|
|
72571
|
-
"permission_mode",
|
|
72572
|
-
"effort",
|
|
72573
|
-
"context_model",
|
|
72574
|
-
"entrypoint",
|
|
72575
|
-
"query_source",
|
|
72576
|
-
"session_kind",
|
|
72577
|
-
"terminal_type",
|
|
72578
|
-
"app_version",
|
|
72579
|
-
"output_style",
|
|
72580
|
-
// host (2.14)
|
|
72581
|
-
"hostname_digest",
|
|
72582
|
-
"os_type",
|
|
72583
|
-
"os_version",
|
|
72584
|
-
"host_arch",
|
|
72585
|
-
"os_user_digest",
|
|
72586
|
-
"claude_pid",
|
|
72587
|
-
"claude_ppid",
|
|
72588
|
-
"claude_parent_process",
|
|
72589
|
-
"claude_execpath",
|
|
72590
|
-
"is_child_session",
|
|
72591
|
-
"bridge_session_id",
|
|
72592
|
-
"has_tty",
|
|
72593
|
-
// chain and content (2.13, 2.15)
|
|
72594
|
-
"prev_hash",
|
|
72595
|
-
"hash",
|
|
72596
|
-
"content_digest",
|
|
72597
|
-
"bytes_ref",
|
|
72598
|
-
"redactions",
|
|
72599
|
-
"raw_source_digest",
|
|
72600
|
-
"body",
|
|
72601
|
-
"attrs"
|
|
72602
|
-
];
|
|
72603
|
-
TACHO_EVENT_COLUMNS = [
|
|
72604
|
-
...ENVELOPE_COLUMNS,
|
|
72605
|
-
...BODY_MEMBER_NAMES
|
|
72606
|
-
];
|
|
72607
|
-
}
|
|
72608
|
-
});
|
|
72609
|
-
|
|
72610
|
-
// ../../packages/tacho/src/evidence/merkle.ts
|
|
72611
|
-
import { createHash as createHash17 } from "node:crypto";
|
|
72612
|
-
function digestToBytes(digest7) {
|
|
72613
|
-
if (!SHA256_DIGEST_PATTERN.test(digest7)) {
|
|
72614
|
-
throw new TypeError(`not a sha256 digest: ${digest7}`);
|
|
72615
|
-
}
|
|
72616
|
-
return Buffer.from(digest7.slice("sha256:".length), "hex");
|
|
72617
|
-
}
|
|
72618
|
-
function hash2(...parts) {
|
|
72619
|
-
const h = createHash17("sha256");
|
|
72620
|
-
for (const part2 of parts) h.update(part2);
|
|
72621
|
-
return h.digest();
|
|
72622
|
-
}
|
|
72623
|
-
function largestPowerOfTwoBelow(n4) {
|
|
72624
|
-
let k = 1;
|
|
72625
|
-
while (k * 2 < n4) k *= 2;
|
|
72626
|
-
return k;
|
|
72627
|
-
}
|
|
72628
|
-
function treeHash(leaves) {
|
|
72629
|
-
if (leaves.length === 0) return hash2();
|
|
72630
|
-
if (leaves.length === 1) return hash2(LEAF_PREFIX, leaves[0]);
|
|
72631
|
-
const k = largestPowerOfTwoBelow(leaves.length);
|
|
72632
|
-
return hash2(
|
|
72633
|
-
NODE_PREFIX,
|
|
72634
|
-
treeHash(leaves.slice(0, k)),
|
|
72635
|
-
treeHash(leaves.slice(k))
|
|
72636
|
-
);
|
|
72637
|
-
}
|
|
72638
|
-
function merkleRoot(digests) {
|
|
72639
|
-
const leaves = digests.map(digestToBytes);
|
|
72640
|
-
return `sha256:${treeHash(leaves).toString("hex")}`;
|
|
72641
|
-
}
|
|
72642
|
-
var LEAF_PREFIX, NODE_PREFIX;
|
|
72643
|
-
var init_merkle = __esm({
|
|
72644
|
-
"../../packages/tacho/src/evidence/merkle.ts"() {
|
|
72645
|
-
"use strict";
|
|
72646
|
-
init_digest();
|
|
72647
|
-
LEAF_PREFIX = Buffer.from([0]);
|
|
72648
|
-
NODE_PREFIX = Buffer.from([1]);
|
|
72649
|
-
}
|
|
72650
|
-
});
|
|
72651
|
-
|
|
72652
|
-
// ../../packages/tacho/src/evidence/archive-segment.ts
|
|
72653
|
-
var encoder3, decoder;
|
|
72654
|
-
var init_archive_segment = __esm({
|
|
72655
|
-
"../../packages/tacho/src/evidence/archive-segment.ts"() {
|
|
72656
|
-
"use strict";
|
|
72657
|
-
init_digest();
|
|
72658
|
-
init_merkle();
|
|
72659
|
-
encoder3 = new TextEncoder();
|
|
72660
|
-
decoder = new TextDecoder("utf-8", { fatal: true });
|
|
72661
|
-
}
|
|
72662
|
-
});
|
|
72663
|
-
|
|
72664
|
-
// ../../packages/tacho/src/evidence/transcript-kinds.ts
|
|
72665
|
-
function isTranscriptKind(value) {
|
|
72666
|
-
return typeof value === "string" && TRANSCRIPT_KINDS.includes(value);
|
|
72667
|
-
}
|
|
72668
|
-
var TRANSCRIPT_KINDS;
|
|
72669
|
-
var init_transcript_kinds = __esm({
|
|
72670
|
-
"../../packages/tacho/src/evidence/transcript-kinds.ts"() {
|
|
72671
|
-
"use strict";
|
|
72672
|
-
TRANSCRIPT_KINDS = [
|
|
72673
|
-
/**
|
|
72674
|
-
* The prompt an operator typed to open a turn: a `turn_start` on the run's
|
|
72675
|
-
* own chain. The request half of a model call is the context the model was
|
|
72676
|
-
* sent, and answers no chip.
|
|
72677
|
-
*/
|
|
72678
|
-
"prompt",
|
|
72679
|
-
/**
|
|
72680
|
-
* What came back: a model call's response half or single receipt whose
|
|
72681
|
-
* body was kept, and a reply the harness reported with its words kept
|
|
72682
|
-
* (`turn_end`, or a message recorded as a response).
|
|
72683
|
-
*/
|
|
72684
|
-
"responses",
|
|
72685
|
-
/**
|
|
72686
|
-
* A model call that spent reasoning tokens (`thinking_tokens`). The text of
|
|
72687
|
-
* the reasoning shows where the recorder kept the stream; the count shows
|
|
72688
|
-
* wherever the provider reported it.
|
|
72689
|
-
*/
|
|
72690
|
-
"thinking",
|
|
72691
|
-
/** Either half of a tool call. */
|
|
72692
|
-
"tools",
|
|
72693
|
-
/** A decision a rule or a person made about a call: allow, deny, route. */
|
|
72694
|
-
"policy",
|
|
72695
|
-
/**
|
|
72696
|
-
* A frame that carried a cost record or token counts without one, or a
|
|
72697
|
-
* model call that recorded the reasoning effort it ran at.
|
|
72698
|
-
*/
|
|
72699
|
-
"usage",
|
|
72700
|
-
/** What was pulled into the model's context. */
|
|
72701
|
-
"recall",
|
|
72702
|
-
/**
|
|
72703
|
-
* The run's own stop: the wrapped agent's `agent_stop` on the run's own
|
|
72704
|
-
* chain, or the ledger event that closes an attempt before its seal. The
|
|
72705
|
-
* chain's checkpoints and gaps are read on the Chain tab, not here.
|
|
72706
|
-
*/
|
|
72707
|
-
"seal",
|
|
72708
|
-
/** A call that did not do what it was asked to. */
|
|
72709
|
-
"errors"
|
|
72710
|
-
];
|
|
72711
|
-
}
|
|
72712
|
-
});
|
|
72713
|
-
|
|
72714
|
-
// ../../packages/tacho/src/evidence/attestation.ts
|
|
72715
|
-
import {
|
|
72716
|
-
createPrivateKey as createPrivateKey2,
|
|
72717
|
-
createPublicKey as createPublicKey4,
|
|
72718
|
-
sign as sign3,
|
|
72719
|
-
verify as verify5
|
|
72720
|
-
} from "node:crypto";
|
|
72721
|
-
function attestationBytes(payload) {
|
|
72722
|
-
return Buffer.from(jcs(payload), "utf8");
|
|
72723
|
-
}
|
|
72724
|
-
function verifyAttestation(attestation, publicKeyPem) {
|
|
72725
|
-
if (attestation.alg !== "ed25519") return false;
|
|
72726
|
-
if (attestation.key_id !== keyIdForPublicKey(publicKeyPem)) return false;
|
|
72727
|
-
try {
|
|
72728
|
-
return verify5(
|
|
72729
|
-
null,
|
|
72730
|
-
attestationBytes(attestation.payload),
|
|
72731
|
-
createPublicKey4(publicKeyPem),
|
|
72732
|
-
Buffer.from(attestation.sig, "base64")
|
|
72733
|
-
);
|
|
72734
|
-
} catch {
|
|
72735
|
-
return false;
|
|
72736
|
-
}
|
|
72737
|
-
}
|
|
72738
|
-
var init_attestation = __esm({
|
|
72739
|
-
"../../packages/tacho/src/evidence/attestation.ts"() {
|
|
72740
|
-
"use strict";
|
|
72741
|
-
init_digest();
|
|
72742
|
-
init_key_id();
|
|
72743
|
-
}
|
|
72744
|
-
});
|
|
72745
|
-
|
|
72746
|
-
// ../../packages/tacho/src/evidence/run-export.ts
|
|
72747
|
-
function normalizeInstant(value) {
|
|
72748
|
-
const m = /^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2})(?:\.(\d+))?(Z|[+-]\d{2}(?::?\d{2})?)$/.exec(
|
|
72749
|
-
value
|
|
72750
|
-
);
|
|
72751
|
-
if (!m) return value;
|
|
72752
|
-
const [, day, time, frac, zone] = m;
|
|
72753
|
-
const ms = (frac ?? "").slice(0, 3).padEnd(3, "0");
|
|
72754
|
-
let offset = zone;
|
|
72755
|
-
if (zone !== "Z") {
|
|
72756
|
-
const digits = zone.slice(1).replace(":", "");
|
|
72757
|
-
offset = `${zone[0]}${digits.slice(0, 2)}:${(digits.slice(2) || "00").padEnd(2, "0")}`;
|
|
72758
|
-
}
|
|
72759
|
-
const instant3 = /* @__PURE__ */ new Date(`${day}T${time}.${ms}${offset}`);
|
|
72760
|
-
return Number.isNaN(instant3.getTime()) ? value : instant3.toISOString();
|
|
72761
|
-
}
|
|
72762
|
-
function wrappedFrameOf(event, bytesRef) {
|
|
72763
|
-
const body2 = asRecord2(event["body"]) ?? {};
|
|
72764
|
-
const content = asRecord2(event["content"]);
|
|
72765
|
-
const turn = asRecord2(event["turn"]);
|
|
72766
|
-
const text5 = (value) => typeof value === "string" ? value : "";
|
|
72767
|
-
const count12 = (value) => typeof value === "number" ? value : null;
|
|
72768
|
-
return {
|
|
72769
|
-
event_id: event["event_id"] ?? null,
|
|
72770
|
-
seq: event["seq"] ?? null,
|
|
72771
|
-
ts: event["ts"] ?? null,
|
|
72772
|
-
kind: event["kind"] ?? null,
|
|
72773
|
-
prev_hash: event["prev_hash"] ?? null,
|
|
72774
|
-
hash: event["hash"] ?? null,
|
|
72775
|
-
content: {
|
|
72776
|
-
digest: content?.["digest"] ?? null,
|
|
72777
|
-
bytes_ref: bytesRef,
|
|
72778
|
-
redactions: content?.["redactions"] ?? []
|
|
72779
|
-
},
|
|
72780
|
-
body: event["body"] ?? null,
|
|
72781
|
-
tool_name: text5(body2["tool_name"]),
|
|
72782
|
-
tool_status: text5(body2["tool_status"]),
|
|
72783
|
-
tool_use_id: text5(body2["tool_use_id"]),
|
|
72784
|
-
model: text5(body2["model"]),
|
|
72785
|
-
provider: text5(body2["provider"]),
|
|
72786
|
-
policy_decision: text5(body2["policy_decision"]),
|
|
72787
|
-
cost_usd_micros: count12(body2["cost_usd_micros"]),
|
|
72788
|
-
turn_seq: count12(turn?.["turn_seq"]),
|
|
72789
|
-
event
|
|
72790
|
-
};
|
|
72791
|
-
}
|
|
72792
|
-
function asRecord2(value) {
|
|
72793
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
72794
|
-
}
|
|
72795
|
-
function tally(counts) {
|
|
72796
|
-
return [...counts.entries()].map(([kind, { count: count12, frames }]) => ({ kind, count: count12, frames })).sort((a, b5) => a.kind.localeCompare(b5.kind));
|
|
72797
|
-
}
|
|
72798
|
-
function summarizeRunExportRedactions(envelopes) {
|
|
72799
|
-
const redacted = /* @__PURE__ */ new Map();
|
|
72800
|
-
const withheld = /* @__PURE__ */ new Map();
|
|
72801
|
-
const bump = (map, kind, count12) => {
|
|
72802
|
-
const entry2 = map.get(kind) ?? { count: 0, frames: 0 };
|
|
72803
|
-
entry2.count += count12;
|
|
72804
|
-
entry2.frames += 1;
|
|
72805
|
-
map.set(kind, entry2);
|
|
72806
|
-
};
|
|
72807
|
-
let total2 = 0;
|
|
72808
|
-
for (const envelope2 of envelopes) {
|
|
72809
|
-
const frame = asRecord2(envelope2);
|
|
72810
|
-
if (!frame) continue;
|
|
72811
|
-
const content = asRecord2(frame["content"]);
|
|
72812
|
-
const list = content?.["redactions"];
|
|
72813
|
-
if (Array.isArray(list)) {
|
|
72814
|
-
const perReason = /* @__PURE__ */ new Map();
|
|
72815
|
-
for (const item of list) {
|
|
72816
|
-
const reason3 = asRecord2(item)?.["reason"];
|
|
72817
|
-
const kind = typeof reason3 === "string" ? reason3 : "unknown";
|
|
72818
|
-
perReason.set(kind, (perReason.get(kind) ?? 0) + 1);
|
|
72819
|
-
}
|
|
72820
|
-
for (const [kind, count12] of perReason) {
|
|
72821
|
-
bump(redacted, kind, count12);
|
|
72822
|
-
total2 += count12;
|
|
72823
|
-
}
|
|
72824
|
-
}
|
|
72825
|
-
if (typeof content?.["bytes_ref"] === "string") {
|
|
72826
|
-
bump(withheld, WITHHELD_BODY, 1);
|
|
72827
|
-
}
|
|
72828
|
-
if (typeof frame["encrypted_payload_ref"] === "string") {
|
|
72829
|
-
bump(withheld, WITHHELD_ENCRYPTED_PAYLOAD, 1);
|
|
72830
|
-
}
|
|
72831
|
-
}
|
|
72832
|
-
return {
|
|
72833
|
-
format: RUN_EXPORT_REDACTIONS_FORMAT,
|
|
72834
|
-
redacted: tally(redacted),
|
|
72835
|
-
redacted_total: total2,
|
|
72836
|
-
withheld: tally(withheld)
|
|
72837
|
-
};
|
|
72838
|
-
}
|
|
72839
|
-
function digestOf2(frame) {
|
|
72840
|
-
const value = frame["event_digest"] ?? frame["hash"];
|
|
72841
|
-
return typeof value === "string" && DIGEST2.test(value) ? value : null;
|
|
72842
|
-
}
|
|
72843
|
-
function safeDigestJcs(value) {
|
|
72844
|
-
try {
|
|
72845
|
-
return digestJcs(value);
|
|
72846
|
-
} catch {
|
|
72847
|
-
return null;
|
|
72848
|
-
}
|
|
72849
|
-
}
|
|
72850
|
-
function checkWrappedFrame(frame, attemptId) {
|
|
72851
|
-
if (frame["event"] === void 0 || frame["event"] === null) {
|
|
72852
|
-
return { digest: "not_carried", reasons: [] };
|
|
72853
|
-
}
|
|
72854
|
-
const event = asRecord2(frame["event"]);
|
|
72855
|
-
if (!event) {
|
|
72856
|
-
return { digest: "broken", reasons: ["event is not a JSON object"] };
|
|
72857
|
-
}
|
|
72858
|
-
const reasons = [];
|
|
72859
|
-
if (event["session_uuid"] !== attemptId) {
|
|
72860
|
-
reasons.push(
|
|
72861
|
-
`the event belongs to session ${String(event["session_uuid"])}, not ${attemptId}`
|
|
72862
|
-
);
|
|
72863
|
-
}
|
|
72864
|
-
let holds2;
|
|
72865
|
-
try {
|
|
72866
|
-
holds2 = eventHashHolds(event, frame["hash"]);
|
|
72867
|
-
} catch {
|
|
72868
|
-
holds2 = false;
|
|
72869
|
-
}
|
|
72870
|
-
if (!holds2) {
|
|
72871
|
-
reasons.push("the event does not hash to hash");
|
|
72872
|
-
}
|
|
72873
|
-
const content = asRecord2(frame["content"]);
|
|
72874
|
-
const bytesRef = typeof content?.["bytes_ref"] === "string" ? content["bytes_ref"] : null;
|
|
72875
|
-
const expected = wrappedFrameOf(event, bytesRef);
|
|
72876
|
-
const differs2 = [
|
|
72877
|
-
.../* @__PURE__ */ new Set([...Object.keys(expected), ...Object.keys(frame)])
|
|
72878
|
-
].filter((name) => name !== "event").filter((name) => {
|
|
72879
|
-
const shown2 = frame[name];
|
|
72880
|
-
const read2 = expected[name];
|
|
72881
|
-
if (shown2 === void 0 || read2 === void 0) return true;
|
|
72882
|
-
return jcs(shown2) !== jcs(read2);
|
|
72883
|
-
}).sort();
|
|
72884
|
-
if (differs2.length > 0) {
|
|
72885
|
-
const verb = differs2.length === 1 ? "differs" : "differ";
|
|
72886
|
-
reasons.push(`${differs2.join(", ")} ${verb} from the hashed event`);
|
|
72887
|
-
}
|
|
72888
|
-
return { digest: reasons.length > 0 ? "broken" : "held", reasons };
|
|
72889
|
-
}
|
|
72890
|
-
function checkLedgerFrame(frame) {
|
|
72891
|
-
const reasons = [];
|
|
72892
|
-
const payloadDigest = frame["payload_digest"];
|
|
72893
|
-
let digest7 = "held";
|
|
72894
|
-
if (frame["payload_inline"] !== null && frame["payload_inline"] !== void 0) {
|
|
72895
|
-
const recomputed2 = safeDigestJcs(frame["payload_inline"]);
|
|
72896
|
-
if (recomputed2 !== payloadDigest) {
|
|
72897
|
-
digest7 = "broken";
|
|
72898
|
-
reasons.push("payload does not hash to payload_digest");
|
|
72899
|
-
}
|
|
72900
|
-
} else if (typeof frame["encrypted_payload_ref"] !== "string") {
|
|
72901
|
-
digest7 = "broken";
|
|
72902
|
-
reasons.push("frame carries neither a payload nor an encrypted reference");
|
|
72903
|
-
}
|
|
72904
|
-
const recomputed = safeDigestJcs({
|
|
72905
|
-
attempt_seq: frame["attempt_seq"] ?? null,
|
|
72906
|
-
event_schema_version: frame["event_schema_version"] ?? null,
|
|
72907
|
-
event_type: frame["event_type"] ?? null,
|
|
72908
|
-
stage: frame["stage"] ?? null,
|
|
72909
|
-
payload_digest: payloadDigest ?? null,
|
|
72910
|
-
observed_at: typeof frame["observed_at"] === "string" ? normalizeInstant(frame["observed_at"]) : frame["observed_at"] ?? null
|
|
72911
|
-
});
|
|
72912
|
-
if (recomputed !== frame["event_digest"]) {
|
|
72913
|
-
digest7 = "broken";
|
|
72914
|
-
reasons.push("identity fields do not hash to event_digest");
|
|
72915
|
-
}
|
|
72916
|
-
return { digest: digest7, reasons };
|
|
72917
|
-
}
|
|
72918
|
-
function parseJson2(text5, name, checks) {
|
|
72919
|
-
try {
|
|
72920
|
-
return JSON.parse(text5);
|
|
72921
|
-
} catch {
|
|
72922
|
-
checks.push({ name, status: "broken", detail: `${name} is not JSON` });
|
|
72923
|
-
return null;
|
|
72924
|
-
}
|
|
72925
|
-
}
|
|
72926
|
-
function verifyRunExport(files3) {
|
|
72927
|
-
const checks = [];
|
|
72928
|
-
const hold = (name, ok2, held, broken) => checks.push({
|
|
72929
|
-
name,
|
|
72930
|
-
status: ok2 ? "held" : "broken",
|
|
72931
|
-
detail: ok2 ? held : broken
|
|
72932
|
-
});
|
|
72933
|
-
const manifest = parseJson2(
|
|
72934
|
-
files3["manifest.json"],
|
|
72935
|
-
"manifest",
|
|
72936
|
-
checks
|
|
72937
|
-
);
|
|
72938
|
-
const attestationFile = parseJson2(
|
|
72939
|
-
files3["attestation.json"],
|
|
72940
|
-
"attestation",
|
|
72941
|
-
checks
|
|
72942
|
-
);
|
|
72943
|
-
const raw = files3["frames.ndjson"];
|
|
72944
|
-
const text5 = raw.endsWith("\n") ? raw.slice(0, -1) : raw;
|
|
72945
|
-
const lines = text5.length === 0 ? [] : text5.split("\n");
|
|
72946
|
-
const frames = [];
|
|
72947
|
-
const verdicts = [];
|
|
72948
|
-
lines.forEach((line, i2) => {
|
|
72949
|
-
let parsed2 = null;
|
|
72950
|
-
try {
|
|
72951
|
-
parsed2 = asRecord2(JSON.parse(line));
|
|
72952
|
-
} catch {
|
|
72953
|
-
parsed2 = null;
|
|
72954
|
-
}
|
|
72955
|
-
frames.push(parsed2 ?? {});
|
|
72956
|
-
if (!parsed2) {
|
|
72957
|
-
verdicts.push({
|
|
72958
|
-
line: i2 + 1,
|
|
72959
|
-
attempt_id: "",
|
|
72960
|
-
seq: null,
|
|
72961
|
-
status: "broken",
|
|
72962
|
-
digest: "broken",
|
|
72963
|
-
link: "broken",
|
|
72964
|
-
reasons: ["line is not a JSON object"]
|
|
72965
|
-
});
|
|
72966
|
-
}
|
|
72967
|
-
});
|
|
72968
|
-
if (!manifest || !attestationFile) {
|
|
72969
|
-
return {
|
|
72970
|
-
ok: false,
|
|
72971
|
-
run_id: manifest?.run_id ?? null,
|
|
72972
|
-
format: manifest?.format ?? null,
|
|
72973
|
-
frames: verdicts,
|
|
72974
|
-
checks,
|
|
72975
|
-
redactions: null
|
|
72976
|
-
};
|
|
72977
|
-
}
|
|
72978
|
-
hold(
|
|
72979
|
-
"format",
|
|
72980
|
-
ACCEPTED_FORMATS.has(manifest.format),
|
|
72981
|
-
manifest.format,
|
|
72982
|
-
`unknown bundle format ${String(manifest.format)}`
|
|
72983
|
-
);
|
|
72984
|
-
hold(
|
|
72985
|
-
"source",
|
|
72986
|
-
typeof manifest.run_id === "string" && (manifest.source === "ledger" && manifest.run_id.startsWith("arun_") || manifest.source === "tacho" && manifest.run_id.startsWith("tse_")),
|
|
72987
|
-
"the source matches the run identifier",
|
|
72988
|
-
"the source is invalid or does not match the run identifier"
|
|
72989
|
-
);
|
|
72990
|
-
const byLine = new Map(verdicts.map((v) => [v.line, v]));
|
|
72991
|
-
let offset = 0;
|
|
72992
|
-
for (const attempt of manifest.attempts ?? []) {
|
|
72993
|
-
let prevHash = null;
|
|
72994
|
-
let prevSeq = null;
|
|
72995
|
-
let stream = EMPTY_EVENT_STREAM_DIGEST;
|
|
72996
|
-
const end = Math.min(offset + attempt.frame_count, frames.length);
|
|
72997
|
-
for (let i2 = offset; i2 < end; i2 += 1) {
|
|
72998
|
-
const line = i2 + 1;
|
|
72999
|
-
if (byLine.has(line)) continue;
|
|
73000
|
-
const frame = frames[i2];
|
|
73001
|
-
const reasons = [];
|
|
73002
|
-
let digest7;
|
|
73003
|
-
let link = "held";
|
|
73004
|
-
let seq = null;
|
|
73005
|
-
if (manifest.source === "ledger") {
|
|
73006
|
-
const own = checkLedgerFrame(frame);
|
|
73007
|
-
digest7 = own.digest;
|
|
73008
|
-
reasons.push(...own.reasons);
|
|
73009
|
-
const attemptSeq = frame["attempt_seq"];
|
|
73010
|
-
seq = typeof attemptSeq === "number" ? attemptSeq : null;
|
|
73011
|
-
const expected = prevSeq === null ? 1 : prevSeq + 1;
|
|
73012
|
-
if (seq !== expected) {
|
|
73013
|
-
link = "broken";
|
|
73014
|
-
reasons.push(`attempt_seq ${String(seq)} where ${expected} was due`);
|
|
73015
|
-
}
|
|
73016
|
-
prevSeq = seq;
|
|
73017
|
-
stream = digestJcs({
|
|
73018
|
-
previous: stream,
|
|
73019
|
-
entry: [
|
|
73020
|
-
frame["attempt_seq"] ?? null,
|
|
73021
|
-
frame["event_schema_version"] ?? null,
|
|
73022
|
-
frame["event_type"] ?? null,
|
|
73023
|
-
frame["payload_digest"] ?? null
|
|
73024
|
-
]
|
|
73025
|
-
});
|
|
73026
|
-
} else {
|
|
73027
|
-
const own = checkWrappedFrame(frame, attempt.attempt_id);
|
|
73028
|
-
digest7 = own.digest;
|
|
73029
|
-
reasons.push(...own.reasons);
|
|
73030
|
-
const rawSeq = frame["seq"];
|
|
73031
|
-
seq = typeof rawSeq === "number" ? rawSeq : null;
|
|
73032
|
-
const expectedPrev = prevHash ?? (seq === 0 ? GENESIS_PREV_HASH2 : null);
|
|
73033
|
-
if (expectedPrev !== null && frame["prev_hash"] !== expectedPrev) {
|
|
73034
|
-
link = "broken";
|
|
73035
|
-
reasons.push(
|
|
73036
|
-
prevHash === null ? 'genesis prev_hash is not sha256("")' : "prev_hash is not the previous frame's hash"
|
|
73037
|
-
);
|
|
73038
|
-
}
|
|
73039
|
-
if (prevSeq !== null && seq !== prevSeq + 1) {
|
|
73040
|
-
link = "broken";
|
|
73041
|
-
reasons.push(`seq ${String(seq)} where ${prevSeq + 1} was due`);
|
|
73042
|
-
}
|
|
73043
|
-
prevSeq = seq;
|
|
73044
|
-
prevHash = typeof frame["hash"] === "string" ? frame["hash"] : null;
|
|
73045
|
-
}
|
|
73046
|
-
if (digestOf2(frame) === null) {
|
|
73047
|
-
digest7 = "broken";
|
|
73048
|
-
reasons.push("frame carries no sha256 digest");
|
|
73049
|
-
}
|
|
73050
|
-
verdicts.push({
|
|
73051
|
-
line,
|
|
73052
|
-
attempt_id: attempt.attempt_id,
|
|
73053
|
-
seq,
|
|
73054
|
-
status: digest7 === "broken" || link === "broken" ? "broken" : "held",
|
|
73055
|
-
digest: digest7,
|
|
73056
|
-
link,
|
|
73057
|
-
reasons
|
|
73058
|
-
});
|
|
73059
|
-
}
|
|
73060
|
-
if (manifest.source === "ledger" && typeof attempt.event_stream_digest === "string") {
|
|
73061
|
-
hold(
|
|
73062
|
-
`stream ${attempt.attempt_id}`,
|
|
73063
|
-
stream === attempt.event_stream_digest,
|
|
73064
|
-
"the frames fold to the sealed event_stream_digest",
|
|
73065
|
-
`the frames fold to ${stream}, the seal recorded ${attempt.event_stream_digest}`
|
|
73066
|
-
);
|
|
73067
|
-
}
|
|
73068
|
-
offset += attempt.frame_count;
|
|
73069
|
-
}
|
|
73070
|
-
for (let i2 = offset; i2 < frames.length; i2 += 1) {
|
|
73071
|
-
if (byLine.has(i2 + 1)) continue;
|
|
73072
|
-
verdicts.push({
|
|
73073
|
-
line: i2 + 1,
|
|
73074
|
-
attempt_id: "",
|
|
73075
|
-
seq: null,
|
|
73076
|
-
status: "broken",
|
|
73077
|
-
digest: "broken",
|
|
73078
|
-
link: "broken",
|
|
73079
|
-
reasons: ["frame lies outside every attested attempt"]
|
|
73080
|
-
});
|
|
73081
|
-
}
|
|
73082
|
-
verdicts.sort((a, b5) => a.line - b5.line);
|
|
73083
|
-
hold(
|
|
73084
|
-
"frame count",
|
|
73085
|
-
frames.length === manifest.frame_count,
|
|
73086
|
-
`${frames.length} frames`,
|
|
73087
|
-
`${frames.length} frames where the manifest says ${manifest.frame_count}`
|
|
73088
|
-
);
|
|
73089
|
-
const digests = frames.map(digestOf2);
|
|
73090
|
-
const allDigests = digests.every((d) => d !== null);
|
|
73091
|
-
const root = allDigests ? merkleRoot(digests) : null;
|
|
73092
|
-
hold(
|
|
73093
|
-
"merkle root",
|
|
73094
|
-
root === manifest.merkle_root,
|
|
73095
|
-
`root ${manifest.merkle_root}`,
|
|
73096
|
-
`frames hash to ${root ?? "nothing"}, the manifest says ${manifest.merkle_root}`
|
|
73097
|
-
);
|
|
73098
|
-
const pem = attestationFile.public_key_pem;
|
|
73099
|
-
let keyId = null;
|
|
73100
|
-
try {
|
|
73101
|
-
keyId = keyIdForPublicKey(pem);
|
|
73102
|
-
} catch {
|
|
73103
|
-
keyId = null;
|
|
73104
|
-
}
|
|
73105
|
-
hold(
|
|
73106
|
-
"attester key",
|
|
73107
|
-
keyId !== null && keyId === attestationFile.key_id && keyId === manifest.attester_key_id,
|
|
73108
|
-
`key ${String(keyId)}`,
|
|
73109
|
-
"the bundled public key does not match the recorded key id"
|
|
73110
|
-
);
|
|
73111
|
-
let covered = 0;
|
|
73112
|
-
const attestations = attestationFile.attestations ?? [];
|
|
73113
|
-
attestations.forEach((a, i2) => {
|
|
73114
|
-
const attemptId = a.payload?.attempt_id ?? `#${i2 + 1}`;
|
|
73115
|
-
hold(
|
|
73116
|
-
`signature ${attemptId}`,
|
|
73117
|
-
keyId !== null && verifyAttestation(a, pem),
|
|
73118
|
-
"Ed25519 signature verifies",
|
|
73119
|
-
"the attestation signature does not verify"
|
|
73120
|
-
);
|
|
73121
|
-
const slice = digests.slice(
|
|
73122
|
-
covered,
|
|
73123
|
-
covered + (a.payload?.frame_count ?? 0)
|
|
73124
|
-
);
|
|
73125
|
-
if (manifest.source === "tacho") {
|
|
73126
|
-
const exportedDigest = digestBytes(
|
|
73127
|
-
lines.slice(covered, covered + (a.payload?.frame_count ?? 0)).join("\n")
|
|
73128
|
-
);
|
|
73129
|
-
hold(
|
|
73130
|
-
`exported content ${attemptId}`,
|
|
73131
|
-
exportedDigest === a.payload?.archive_segment_digest,
|
|
73132
|
-
"the exported frame bytes match the signed segment digest",
|
|
73133
|
-
"the exported frame bytes do not match the signed segment digest"
|
|
73134
|
-
);
|
|
73135
|
-
}
|
|
73136
|
-
hold(
|
|
73137
|
-
`run identity ${attemptId}`,
|
|
73138
|
-
a.payload?.run_id === manifest.run_id,
|
|
73139
|
-
"the attestation names this run",
|
|
73140
|
-
"the manifest run differs from the signed run"
|
|
73141
|
-
);
|
|
73142
|
-
covered += a.payload?.frame_count ?? 0;
|
|
73143
|
-
const attemptRoot = slice.every((d) => d !== null) ? merkleRoot(slice) : null;
|
|
73144
|
-
hold(
|
|
73145
|
-
`attested root ${attemptId}`,
|
|
73146
|
-
attemptRoot === a.payload?.merkle_root,
|
|
73147
|
-
"the attempt's frames hash to the signed root",
|
|
73148
|
-
`the attempt's frames hash to ${attemptRoot ?? "nothing"}, the attestation signed ${String(a.payload?.merkle_root)}`
|
|
73149
|
-
);
|
|
73150
|
-
});
|
|
73151
|
-
hold(
|
|
73152
|
-
"coverage",
|
|
73153
|
-
covered === frames.length && attestations.length > 0,
|
|
73154
|
-
"the attestations cover every frame",
|
|
73155
|
-
`the attestations cover ${covered} of ${frames.length} frames`
|
|
73156
|
-
);
|
|
73157
|
-
let redactions = null;
|
|
73158
|
-
const redactionsText = files3["redactions.json"];
|
|
73159
|
-
if (redactionsText !== void 0) {
|
|
73160
|
-
redactions = parseJson2(
|
|
73161
|
-
redactionsText,
|
|
73162
|
-
"redactions",
|
|
73163
|
-
checks
|
|
73164
|
-
);
|
|
73165
|
-
if (redactions) {
|
|
73166
|
-
const recomputed = summarizeRunExportRedactions(frames);
|
|
73167
|
-
hold(
|
|
73168
|
-
"redactions",
|
|
73169
|
-
digestJcs(recomputed) === digestJcs(redactions),
|
|
73170
|
-
`${recomputed.redacted_total} redaction(s) summarised`,
|
|
73171
|
-
"redactions.json does not match what the frames record"
|
|
73172
|
-
);
|
|
73173
|
-
}
|
|
73174
|
-
} else if (manifest.format !== FORMAT_1) {
|
|
73175
|
-
hold("redactions", false, "", "redactions.json is missing");
|
|
73176
|
-
}
|
|
73177
|
-
const ok = verdicts.length === frames.length && verdicts.every((v) => v.status === "held") && checks.every((c) => c.status === "held");
|
|
73178
|
-
return {
|
|
73179
|
-
ok,
|
|
73180
|
-
run_id: manifest.run_id,
|
|
73181
|
-
format: manifest.format,
|
|
73182
|
-
frames: verdicts,
|
|
73183
|
-
checks,
|
|
73184
|
-
redactions
|
|
73185
|
-
};
|
|
73186
|
-
}
|
|
73187
|
-
var RUN_EXPORT_FORMAT, FORMAT_1, ACCEPTED_FORMATS, RUN_EXPORT_REDACTIONS_FORMAT, GENESIS_PREV_HASH2, EMPTY_EVENT_STREAM_DIGEST, DIGEST2, WITHHELD_BODY, WITHHELD_ENCRYPTED_PAYLOAD;
|
|
73188
|
-
var init_run_export = __esm({
|
|
73189
|
-
"../../packages/tacho/src/evidence/run-export.ts"() {
|
|
73190
|
-
"use strict";
|
|
73191
|
-
init_chain();
|
|
73192
|
-
init_digest();
|
|
73193
|
-
init_key_id();
|
|
73194
|
-
init_attestation();
|
|
73195
|
-
init_merkle();
|
|
73196
|
-
RUN_EXPORT_FORMAT = "oxagen.run-export/3";
|
|
73197
|
-
FORMAT_1 = "oxagen.run-export/1";
|
|
73198
|
-
ACCEPTED_FORMATS = /* @__PURE__ */ new Set([
|
|
73199
|
-
FORMAT_1,
|
|
73200
|
-
"oxagen.run-export/2",
|
|
73201
|
-
RUN_EXPORT_FORMAT
|
|
73508
|
+
),
|
|
73509
|
+
bot_authors: setting(
|
|
73510
|
+
uniqueArray(external_exports.string().min(1).max(200), "bot_authors").describe(
|
|
73511
|
+
"Authors whose commits history ignores."
|
|
73512
|
+
),
|
|
73513
|
+
CODEGRAPH_BOT_AUTHORS_DEFAULT
|
|
73514
|
+
),
|
|
73515
|
+
co_change_half_life_days: setting(
|
|
73516
|
+
external_exports.number().int().min(1).describe("A co-change counts half as much after this many days."),
|
|
73517
|
+
365
|
|
73518
|
+
),
|
|
73519
|
+
cross_repo_window_hours: setting(
|
|
73520
|
+
external_exports.number().int().min(1).describe("Commits in two repositories this close together can pair."),
|
|
73521
|
+
24
|
|
73522
|
+
),
|
|
73523
|
+
owner_features: setting(
|
|
73524
|
+
external_exports.boolean().describe("Compute owners from history."),
|
|
73525
|
+
true
|
|
73526
|
+
)
|
|
73527
|
+
}).strict();
|
|
73528
|
+
CODEGRAPH_HISTORY_DEFAULTS = {
|
|
73529
|
+
change_size_cutoff_files: 30,
|
|
73530
|
+
bot_authors: CODEGRAPH_BOT_AUTHORS_DEFAULT,
|
|
73531
|
+
co_change_half_life_days: 365,
|
|
73532
|
+
cross_repo_window_hours: 24,
|
|
73533
|
+
owner_features: true
|
|
73534
|
+
};
|
|
73535
|
+
codegraphDecisionsSchema = external_exports.object({
|
|
73536
|
+
importance_threshold: setting(
|
|
73537
|
+
share().describe(
|
|
73538
|
+
"A signal at or above this importance suggests a decision record. The M4 backtest sets it."
|
|
73539
|
+
),
|
|
73540
|
+
0.7
|
|
73541
|
+
),
|
|
73542
|
+
grouping_window_days: setting(
|
|
73543
|
+
external_exports.number().int().min(1).describe("Signals on one topic within this many days group into one."),
|
|
73544
|
+
7
|
|
73545
|
+
),
|
|
73546
|
+
stale_proposal_days: setting(
|
|
73547
|
+
external_exports.number().int().min(1).describe("A proposal untouched this many days is stale."),
|
|
73548
|
+
30
|
|
73549
|
+
),
|
|
73550
|
+
package_categories: uniqueArray(
|
|
73551
|
+
external_exports.string().min(1).max(100),
|
|
73552
|
+
"package_categories"
|
|
73553
|
+
).optional().describe(
|
|
73554
|
+
"The package categories signals weigh. Unset: the curated list."
|
|
73555
|
+
)
|
|
73556
|
+
}).strict();
|
|
73557
|
+
CODEGRAPH_DECISIONS_DEFAULTS = {
|
|
73558
|
+
importance_threshold: 0.7,
|
|
73559
|
+
grouping_window_days: 7,
|
|
73560
|
+
stale_proposal_days: 30
|
|
73561
|
+
};
|
|
73562
|
+
codegraphHostDefaultSchema = external_exports.enum([
|
|
73563
|
+
"sandbox",
|
|
73564
|
+
"ask",
|
|
73565
|
+
"approval"
|
|
73202
73566
|
]);
|
|
73203
|
-
|
|
73204
|
-
|
|
73205
|
-
|
|
73206
|
-
|
|
73207
|
-
|
|
73208
|
-
|
|
73209
|
-
|
|
73210
|
-
|
|
73211
|
-
|
|
73212
|
-
|
|
73213
|
-
|
|
73214
|
-
|
|
73215
|
-
|
|
73216
|
-
|
|
73217
|
-
|
|
73218
|
-
|
|
73219
|
-
|
|
73220
|
-
|
|
73221
|
-
|
|
73222
|
-
|
|
73223
|
-
|
|
73224
|
-
|
|
73567
|
+
CODEGRAPH_HOST_DEFAULTS = {
|
|
73568
|
+
"read-only": "sandbox",
|
|
73569
|
+
test: "sandbox",
|
|
73570
|
+
build: "sandbox",
|
|
73571
|
+
"local-write": "ask",
|
|
73572
|
+
"remote-write": "approval",
|
|
73573
|
+
destructive: "approval",
|
|
73574
|
+
unknown: "approval"
|
|
73575
|
+
};
|
|
73576
|
+
codegraphScriptsSchema = external_exports.object({
|
|
73577
|
+
host_defaults: external_exports.object({
|
|
73578
|
+
"read-only": setting(
|
|
73579
|
+
codegraphHostDefaultSchema,
|
|
73580
|
+
CODEGRAPH_HOST_DEFAULTS["read-only"]
|
|
73581
|
+
),
|
|
73582
|
+
test: setting(codegraphHostDefaultSchema, CODEGRAPH_HOST_DEFAULTS.test),
|
|
73583
|
+
build: setting(
|
|
73584
|
+
codegraphHostDefaultSchema,
|
|
73585
|
+
CODEGRAPH_HOST_DEFAULTS.build
|
|
73586
|
+
),
|
|
73587
|
+
"local-write": setting(
|
|
73588
|
+
codegraphHostDefaultSchema,
|
|
73589
|
+
CODEGRAPH_HOST_DEFAULTS["local-write"]
|
|
73590
|
+
),
|
|
73591
|
+
"remote-write": setting(
|
|
73592
|
+
codegraphHostDefaultSchema,
|
|
73593
|
+
CODEGRAPH_HOST_DEFAULTS["remote-write"]
|
|
73594
|
+
),
|
|
73595
|
+
destructive: setting(
|
|
73596
|
+
codegraphHostDefaultSchema,
|
|
73597
|
+
CODEGRAPH_HOST_DEFAULTS.destructive
|
|
73598
|
+
),
|
|
73599
|
+
unknown: setting(
|
|
73600
|
+
codegraphHostDefaultSchema,
|
|
73601
|
+
CODEGRAPH_HOST_DEFAULTS.unknown
|
|
73602
|
+
)
|
|
73603
|
+
}).strict().optional().describe(
|
|
73604
|
+
"What a host does with a script of each effect class: run it in a sandbox, ask first, or wait for approval."
|
|
73605
|
+
),
|
|
73606
|
+
trusted_policies: uniqueArray(
|
|
73607
|
+
external_exports.string().min(1).max(200),
|
|
73608
|
+
"trusted_policies"
|
|
73609
|
+
).optional().describe("Script policies the workspace trusts. Unset: none.")
|
|
73610
|
+
}).strict();
|
|
73611
|
+
CODEGRAPH_SCRIPTS_DEFAULTS = {
|
|
73612
|
+
host_defaults: CODEGRAPH_HOST_DEFAULTS,
|
|
73613
|
+
trusted_policies: []
|
|
73614
|
+
};
|
|
73615
|
+
codegraphDomainIdSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9_.-]{0,127}$/, "a domain id is lowercase");
|
|
73616
|
+
codegraphBoundariesSchema = external_exports.object({
|
|
73617
|
+
allowed_crossings: uniqueArray(
|
|
73618
|
+
external_exports.object({
|
|
73619
|
+
from: codegraphDomainIdSchema,
|
|
73620
|
+
to: codegraphDomainIdSchema
|
|
73621
|
+
}).strict(),
|
|
73622
|
+
"allowed_crossings"
|
|
73623
|
+
).optional().describe(
|
|
73624
|
+
"The domain crossings code may make. Unset: the table the current build found."
|
|
73625
|
+
)
|
|
73626
|
+
}).strict();
|
|
73627
|
+
CODEGRAPH_BOUNDARIES_DEFAULTS = {};
|
|
73628
|
+
codegraphBudgetsSchema = external_exports.object({
|
|
73629
|
+
answer_budget_tokens: setting(
|
|
73630
|
+
external_exports.number().int().min(1).describe(
|
|
73631
|
+
"The default token budget of one answer. The spending cap is on the AI models and keys screen."
|
|
73632
|
+
),
|
|
73633
|
+
4e3
|
|
73634
|
+
)
|
|
73635
|
+
}).strict();
|
|
73636
|
+
CODEGRAPH_BUDGETS_DEFAULTS = {
|
|
73637
|
+
answer_budget_tokens: 4e3
|
|
73638
|
+
};
|
|
73639
|
+
codegraphFreshnessSchema = external_exports.object({
|
|
73640
|
+
lag_window_minutes: setting(
|
|
73641
|
+
external_exports.number().int().min(1).describe(
|
|
73642
|
+
"The freshness check fails when the graph lags the code this long."
|
|
73643
|
+
),
|
|
73644
|
+
30
|
|
73645
|
+
),
|
|
73646
|
+
revision_retention_days: setting(
|
|
73647
|
+
external_exports.number().int().min(1).describe("Days a default-branch revision is kept."),
|
|
73648
|
+
90
|
|
73649
|
+
),
|
|
73650
|
+
pr_copy_retention_days: setting(
|
|
73651
|
+
external_exports.number().int().min(0).describe("Days a PR copy is kept after the PR closes."),
|
|
73652
|
+
7
|
|
73653
|
+
)
|
|
73654
|
+
}).strict();
|
|
73655
|
+
CODEGRAPH_FRESHNESS_DEFAULTS = {
|
|
73656
|
+
lag_window_minutes: 30,
|
|
73657
|
+
revision_retention_days: 90,
|
|
73658
|
+
pr_copy_retention_days: 7
|
|
73659
|
+
};
|
|
73660
|
+
CODEGRAPH_SETTINGS_GROUPS = [
|
|
73661
|
+
{
|
|
73662
|
+
group: "sources",
|
|
73663
|
+
id: "codegraph-sources/v1",
|
|
73664
|
+
title: "Code graph sources",
|
|
73665
|
+
description: "codegraph/sources.toml: the source tags each linked code repository carries.",
|
|
73666
|
+
schema: codegraphSourcesSchema,
|
|
73667
|
+
defaults: CODEGRAPH_SOURCES_DEFAULTS,
|
|
73668
|
+
timing: "next_build"
|
|
73669
|
+
},
|
|
73670
|
+
{
|
|
73671
|
+
group: "indexing",
|
|
73672
|
+
id: "codegraph-indexing/v1",
|
|
73673
|
+
title: "Code graph indexing",
|
|
73674
|
+
description: "codegraph/indexing.toml: the file size limit, skipped paths, live cloud inventory, and per-repository SCIP and version lookup.",
|
|
73675
|
+
schema: codegraphIndexingSchema,
|
|
73676
|
+
defaults: CODEGRAPH_INDEXING_DEFAULTS,
|
|
73677
|
+
timing: "next_build"
|
|
73678
|
+
},
|
|
73679
|
+
{
|
|
73680
|
+
group: "models",
|
|
73681
|
+
id: "codegraph-models/v1",
|
|
73682
|
+
title: "Code graph AI models and keys",
|
|
73683
|
+
description: "codegraph/models.toml: the key source, the model for each task, call mode, providers, and escalation limits. The key itself is never stored here.",
|
|
73684
|
+
schema: codegraphModelsSchema,
|
|
73685
|
+
defaults: CODEGRAPH_MODELS_DEFAULTS,
|
|
73686
|
+
timing: "next_build"
|
|
73687
|
+
},
|
|
73688
|
+
{
|
|
73689
|
+
group: "embeddings",
|
|
73690
|
+
id: "codegraph-embeddings/v1",
|
|
73691
|
+
title: "Code graph embeddings",
|
|
73692
|
+
description: "codegraph/embeddings.toml: whether builds embed cards, and with the Oxagen provider or the workspace's own endpoint.",
|
|
73693
|
+
schema: codegraphEmbeddingsSchema,
|
|
73694
|
+
defaults: CODEGRAPH_EMBEDDINGS_DEFAULTS,
|
|
73695
|
+
timing: "next_build"
|
|
73696
|
+
},
|
|
73697
|
+
{
|
|
73698
|
+
group: "local",
|
|
73699
|
+
id: "codegraph-local/v1",
|
|
73700
|
+
title: "Code graph local graphs",
|
|
73701
|
+
description: "codegraph/local.toml: whether operators may build local graphs, the watch debounce, the memory limit, and local SCIP.",
|
|
73702
|
+
schema: codegraphLocalSchema,
|
|
73703
|
+
defaults: CODEGRAPH_LOCAL_DEFAULTS,
|
|
73704
|
+
timing: "next_build"
|
|
73705
|
+
},
|
|
73706
|
+
{
|
|
73707
|
+
group: "confidence",
|
|
73708
|
+
id: "codegraph-confidence/v1",
|
|
73709
|
+
title: "Code graph confidence",
|
|
73710
|
+
description: "codegraph/confidence.toml: the confidence of each provenance, the default minConfidence, and the agent link limits.",
|
|
73711
|
+
schema: codegraphConfidenceSchema,
|
|
73712
|
+
defaults: CODEGRAPH_CONFIDENCE_DEFAULTS,
|
|
73713
|
+
timing: "next_call"
|
|
73714
|
+
},
|
|
73715
|
+
{
|
|
73716
|
+
group: "domains",
|
|
73717
|
+
id: "codegraph-domains/v1",
|
|
73718
|
+
title: "Code graph domains",
|
|
73719
|
+
description: "codegraph/domains.toml: the tag score, the close-call margin and limit, and the regrouping threshold.",
|
|
73720
|
+
schema: codegraphDomainsSchema,
|
|
73721
|
+
defaults: CODEGRAPH_DOMAINS_DEFAULTS,
|
|
73722
|
+
timing: "next_build"
|
|
73723
|
+
},
|
|
73724
|
+
{
|
|
73725
|
+
group: "history",
|
|
73726
|
+
id: "codegraph-history/v1",
|
|
73727
|
+
title: "Code graph history",
|
|
73728
|
+
description: "codegraph/history.toml: the change-size cutoff, bot authors, co-change half-life, cross-repository window, and owner features.",
|
|
73729
|
+
schema: codegraphHistorySchema,
|
|
73730
|
+
defaults: CODEGRAPH_HISTORY_DEFAULTS,
|
|
73731
|
+
timing: "next_build"
|
|
73732
|
+
},
|
|
73733
|
+
{
|
|
73734
|
+
group: "decisions",
|
|
73735
|
+
id: "codegraph-decisions/v1",
|
|
73736
|
+
title: "Code graph decision records",
|
|
73737
|
+
description: "codegraph/decisions.toml: the importance threshold, grouping window, stale-proposal age, and package categories.",
|
|
73738
|
+
schema: codegraphDecisionsSchema,
|
|
73739
|
+
defaults: CODEGRAPH_DECISIONS_DEFAULTS,
|
|
73740
|
+
timing: "next_build"
|
|
73741
|
+
},
|
|
73742
|
+
{
|
|
73743
|
+
group: "scripts",
|
|
73744
|
+
id: "codegraph-scripts/v1",
|
|
73745
|
+
title: "Code graph scripts",
|
|
73746
|
+
description: "codegraph/scripts.toml: the host default for each effect class and the trusted script policies.",
|
|
73747
|
+
schema: codegraphScriptsSchema,
|
|
73748
|
+
defaults: CODEGRAPH_SCRIPTS_DEFAULTS,
|
|
73749
|
+
timing: "next_call"
|
|
73750
|
+
},
|
|
73751
|
+
{
|
|
73752
|
+
group: "boundaries",
|
|
73753
|
+
id: "codegraph-boundaries/v1",
|
|
73754
|
+
title: "Code graph boundaries",
|
|
73755
|
+
description: "codegraph/boundaries.toml: the crossings allowed between domains.",
|
|
73756
|
+
schema: codegraphBoundariesSchema,
|
|
73757
|
+
defaults: CODEGRAPH_BOUNDARIES_DEFAULTS,
|
|
73758
|
+
timing: "next_call"
|
|
73759
|
+
},
|
|
73760
|
+
{
|
|
73761
|
+
group: "budgets",
|
|
73762
|
+
id: "codegraph-budgets/v1",
|
|
73763
|
+
title: "Code graph budgets",
|
|
73764
|
+
description: "codegraph/budgets.toml: the default answer budget.",
|
|
73765
|
+
schema: codegraphBudgetsSchema,
|
|
73766
|
+
defaults: CODEGRAPH_BUDGETS_DEFAULTS,
|
|
73767
|
+
timing: "next_call"
|
|
73768
|
+
},
|
|
73769
|
+
{
|
|
73770
|
+
group: "freshness",
|
|
73771
|
+
id: "codegraph-freshness/v1",
|
|
73772
|
+
title: "Code graph freshness and retention",
|
|
73773
|
+
description: "codegraph/freshness.toml: the CI check's lag window and how long revisions and PR copies are kept.",
|
|
73774
|
+
schema: codegraphFreshnessSchema,
|
|
73775
|
+
defaults: CODEGRAPH_FRESHNESS_DEFAULTS,
|
|
73776
|
+
timing: "next_build"
|
|
73777
|
+
}
|
|
73778
|
+
];
|
|
73225
73779
|
}
|
|
73226
73780
|
});
|
|
73227
73781
|
|
|
73228
|
-
// ../../packages/
|
|
73229
|
-
var
|
|
73230
|
-
var
|
|
73231
|
-
"../../packages/
|
|
73782
|
+
// ../../packages/oxagen/src/steering-repo/governance.ts
|
|
73783
|
+
var ledgerRotationSchema, governanceSchema;
|
|
73784
|
+
var init_governance = __esm({
|
|
73785
|
+
"../../packages/oxagen/src/steering-repo/governance.ts"() {
|
|
73232
73786
|
"use strict";
|
|
73233
|
-
|
|
73234
|
-
|
|
73235
|
-
|
|
73236
|
-
|
|
73237
|
-
|
|
73238
|
-
|
|
73239
|
-
|
|
73240
|
-
|
|
73241
|
-
|
|
73242
|
-
|
|
73243
|
-
|
|
73244
|
-
|
|
73245
|
-
|
|
73787
|
+
init_zod();
|
|
73788
|
+
init_context_steering_shared();
|
|
73789
|
+
init_common();
|
|
73790
|
+
init_json_schema();
|
|
73791
|
+
init_tokens();
|
|
73792
|
+
ledgerRotationSchema = external_exports.enum(["day", "week", "month", "year"]);
|
|
73793
|
+
governanceSchema = withRules(
|
|
73794
|
+
external_exports.object({
|
|
73795
|
+
schema: external_exports.literal("governance/v1"),
|
|
73796
|
+
mode: governanceModeSchema,
|
|
73797
|
+
steering: external_exports.object({
|
|
73798
|
+
always_on_tokens: external_exports.union([external_exports.number().int().positive(), external_exports.literal("off")]).optional().describe(
|
|
73799
|
+
"The always-on budget per code repository, or off. Unset inherits Oxagen's default, the largest harness hook limit. A budget above that limit fails the budget check."
|
|
73800
|
+
)
|
|
73801
|
+
}).strict().optional(),
|
|
73802
|
+
ledger: external_exports.object({
|
|
73803
|
+
rotate: ledgerRotationSchema.optional(),
|
|
73804
|
+
max_lines: external_exports.number().int().positive().optional().describe("A new file starts here even mid-period.")
|
|
73805
|
+
}).strict().optional(),
|
|
73806
|
+
// `recall_unreviewed` left the memory table on 2026-09-30, because
|
|
73807
|
+
// Oxagen no longer recalls a memory that waits for review (ADR-238).
|
|
73808
|
+
memory: external_exports.object({
|
|
73809
|
+
batch_size: external_exports.number().int().positive().optional().describe("Memories per memory PR."),
|
|
73810
|
+
retire_after_days: external_exports.number().int().positive().optional(),
|
|
73811
|
+
auto_merge: external_exports.boolean().optional().describe("Allowed in solo mode only.")
|
|
73812
|
+
}).strict().optional(),
|
|
73813
|
+
reviewers: external_exports.array(
|
|
73814
|
+
external_exports.object({
|
|
73815
|
+
paths: external_exports.array(external_exports.string().min(1)).min(1),
|
|
73816
|
+
group: organizationSlugSchema
|
|
73817
|
+
}).strict()
|
|
73818
|
+
).optional().describe(
|
|
73819
|
+
"Route the folders a pull request changes to a reviewer group."
|
|
73820
|
+
)
|
|
73821
|
+
}).strict(),
|
|
73822
|
+
[
|
|
73823
|
+
{
|
|
73824
|
+
kind: "equals",
|
|
73825
|
+
when: { field: "mode", isNot: "solo" },
|
|
73826
|
+
path: ["memory", "auto_merge"],
|
|
73827
|
+
value: false
|
|
73828
|
+
}
|
|
73829
|
+
]
|
|
73246
73830
|
);
|
|
73247
|
-
GITHUB_REF_SOURCE = String.raw`\bhttps?:\/\/(?:www\.)?github\.com\/[\w.-]+\/[\w.-]+\/(pull|issues)\/(\d+)\S*`;
|
|
73248
73831
|
}
|
|
73249
73832
|
});
|
|
73250
73833
|
|
|
73251
|
-
// ../../packages/
|
|
73252
|
-
var
|
|
73253
|
-
|
|
73834
|
+
// ../../packages/oxagen/src/steering-repo/health.ts
|
|
73835
|
+
var REPO_HEALTH_STATES, repoHealthSchema, settingsDifferenceSchema;
|
|
73836
|
+
var init_health = __esm({
|
|
73837
|
+
"../../packages/oxagen/src/steering-repo/health.ts"() {
|
|
73254
73838
|
"use strict";
|
|
73255
|
-
|
|
73839
|
+
init_zod();
|
|
73840
|
+
init_common();
|
|
73841
|
+
REPO_HEALTH_STATES = [
|
|
73842
|
+
"healthy",
|
|
73843
|
+
"drifted",
|
|
73844
|
+
"disconnected",
|
|
73845
|
+
"diverged"
|
|
73846
|
+
];
|
|
73847
|
+
repoHealthSchema = external_exports.enum(REPO_HEALTH_STATES);
|
|
73848
|
+
settingsDifferenceSchema = external_exports.object({
|
|
73849
|
+
setting: external_exports.string().min(1).describe(
|
|
73850
|
+
"The setting's path in the baseline, such as rulesets.oxagen_merges."
|
|
73851
|
+
),
|
|
73852
|
+
expected: external_exports.unknown(),
|
|
73853
|
+
actual: external_exports.unknown(),
|
|
73854
|
+
changed_by: external_exports.string().nullable(),
|
|
73855
|
+
changed_at: instantSchema2.nullable()
|
|
73856
|
+
}).strict();
|
|
73256
73857
|
}
|
|
73257
73858
|
});
|
|
73258
73859
|
|
|
73259
|
-
// ../../packages/
|
|
73260
|
-
var
|
|
73261
|
-
|
|
73860
|
+
// ../../packages/oxagen/src/steering-repo/promotion.ts
|
|
73861
|
+
var promotionChangeSchema, branchSchema, promotionSchema;
|
|
73862
|
+
var init_promotion = __esm({
|
|
73863
|
+
"../../packages/oxagen/src/steering-repo/promotion.ts"() {
|
|
73262
73864
|
"use strict";
|
|
73263
|
-
|
|
73264
|
-
|
|
73265
|
-
|
|
73266
|
-
|
|
73267
|
-
|
|
73268
|
-
|
|
73269
|
-
|
|
73270
|
-
|
|
73271
|
-
|
|
73272
|
-
|
|
73273
|
-
|
|
73274
|
-
|
|
73275
|
-
|
|
73276
|
-
|
|
73277
|
-
|
|
73865
|
+
init_zod();
|
|
73866
|
+
init_src3();
|
|
73867
|
+
init_context_steering_shared();
|
|
73868
|
+
init_common();
|
|
73869
|
+
init_names();
|
|
73870
|
+
promotionChangeSchema = external_exports.object({
|
|
73871
|
+
path: repoPathSchema,
|
|
73872
|
+
action: external_exports.enum(["added", "modified", "removed"]),
|
|
73873
|
+
lineage: lineageSchema.optional(),
|
|
73874
|
+
id: recordIdSchema.optional(),
|
|
73875
|
+
hash: sha256Schema2.optional(),
|
|
73876
|
+
replaces: recordIdSchema.optional().describe(
|
|
73877
|
+
"The id this record had before a format change, such as the v0.1 conversion."
|
|
73878
|
+
)
|
|
73879
|
+
}).strict();
|
|
73880
|
+
branchSchema = external_exports.string().regex(new RegExp(`^(?:${BRANCH_PREFIXES.join("|")})/.+$`)).describe("Starts with the top-level folder the change touches.");
|
|
73881
|
+
promotionSchema = external_exports.object({
|
|
73882
|
+
schema: external_exports.literal("promotion/v1"),
|
|
73883
|
+
seq: external_exports.number().int().min(1).describe("The line's place in the whole chain, across files."),
|
|
73884
|
+
at: instantSchema2,
|
|
73885
|
+
pull_request: external_exports.object({
|
|
73886
|
+
provider: repositoryProviderSchema,
|
|
73887
|
+
number: external_exports.number().int().positive()
|
|
73888
|
+
}).strict(),
|
|
73889
|
+
branch: branchSchema,
|
|
73890
|
+
mode: governanceModeSchema,
|
|
73891
|
+
approved_by: external_exports.array(actorSchema),
|
|
73892
|
+
merged_by: actorSchema,
|
|
73893
|
+
without_review: external_exports.boolean().describe(
|
|
73894
|
+
"True when the owner, or a role with merge_pr_without_review, merged without an approval."
|
|
73895
|
+
),
|
|
73896
|
+
changes: external_exports.array(promotionChangeSchema).min(1),
|
|
73897
|
+
prev: sha256Schema2.nullable().describe(
|
|
73898
|
+
"The hash of the line before, or null on the first line of the chain."
|
|
73899
|
+
),
|
|
73900
|
+
hash: sha256Schema2.describe(
|
|
73901
|
+
"sha256 over the RFC 8785 canonical JSON of this line without hash."
|
|
73902
|
+
)
|
|
73903
|
+
}).strict();
|
|
73278
73904
|
}
|
|
73279
73905
|
});
|
|
73280
73906
|
|
|
@@ -74730,6 +75356,41 @@ function definitionBudget(tree) {
|
|
|
74730
75356
|
function repositoryName(repository) {
|
|
74731
75357
|
return repository ?? "a repository no record names";
|
|
74732
75358
|
}
|
|
75359
|
+
function harnessNames(harnesses) {
|
|
75360
|
+
const names2 = harnesses.map((harness) => HARNESS_LABELS[harness] ?? harness);
|
|
75361
|
+
if (names2.length <= 1) return names2.join("");
|
|
75362
|
+
return `${names2.slice(0, -1).join(", ")} and ${names2[names2.length - 1]}`;
|
|
75363
|
+
}
|
|
75364
|
+
function budgetCeiling(budget, line) {
|
|
75365
|
+
if (budget === "off" || budget.tokens <= LARGEST_PREFIX_BUDGET_TOKENS)
|
|
75366
|
+
return null;
|
|
75367
|
+
const at = harnessesAtLargestBudget();
|
|
75368
|
+
const limit = formatCount(LARGEST_PREFIX_BUDGET_TOKENS);
|
|
75369
|
+
const chars = formatCount(
|
|
75370
|
+
Math.max(...at.map((harness) => HARNESS_HOOK_LIMITS[harness].chars))
|
|
75371
|
+
);
|
|
75372
|
+
return find2({
|
|
75373
|
+
rule: "always-on-ceiling",
|
|
75374
|
+
severity: "error",
|
|
75375
|
+
path: GOVERNANCE_TOML_PATH,
|
|
75376
|
+
line,
|
|
75377
|
+
field: "steering.always_on_tokens",
|
|
75378
|
+
message: `always_on_tokens is ${formatCount(budget.tokens)}, above the ${limit} tokens ${harnessNames(at)} take from one hook answer (${chars} characters). No harness would hand an agent the extra text.`,
|
|
75379
|
+
expected: `At most ${limit} tokens, the largest harness hook limit.`,
|
|
75380
|
+
fix: `Set always_on_tokens to ${limit} or less in this PR, or remove it to inherit Oxagen's default, which is that limit.`,
|
|
75381
|
+
detail: {
|
|
75382
|
+
budget: budget.tokens,
|
|
75383
|
+
budget_source: budget.source,
|
|
75384
|
+
ceiling: LARGEST_PREFIX_BUDGET_TOKENS,
|
|
75385
|
+
harnesses: at.map((harness) => ({
|
|
75386
|
+
harness,
|
|
75387
|
+
chars: HARNESS_HOOK_LIMITS[harness].chars,
|
|
75388
|
+
tokens: prefixBudgetTokens(harness),
|
|
75389
|
+
source: HARNESS_HOOK_LIMITS[harness].source
|
|
75390
|
+
}))
|
|
75391
|
+
}
|
|
75392
|
+
});
|
|
75393
|
+
}
|
|
74733
75394
|
function sameBudget(a, b5) {
|
|
74734
75395
|
if (a === "off" || b5 === "off") return a === b5;
|
|
74735
75396
|
return a.tokens === b5.tokens;
|
|
@@ -74784,6 +75445,8 @@ function alwaysOnPart(env) {
|
|
|
74784
75445
|
const line = governance === void 0 ? null : tomlLine(governance, "steering.always_on_tokens");
|
|
74785
75446
|
const findings = [];
|
|
74786
75447
|
const notes = [];
|
|
75448
|
+
const ceiling = budgetCeiling(budget, line);
|
|
75449
|
+
if (ceiling !== null) findings.push(ceiling);
|
|
74787
75450
|
for (const block of alwaysOnBlocks(env.head)) {
|
|
74788
75451
|
const prior = before.get(block.repository);
|
|
74789
75452
|
if (!budgetMoved && prior?.text === block.text) continue;
|
|
@@ -74896,16 +75559,23 @@ function toolsPart(env) {
|
|
|
74896
75559
|
]
|
|
74897
75560
|
};
|
|
74898
75561
|
}
|
|
74899
|
-
var find2, LARGEST, budgetCheck;
|
|
75562
|
+
var find2, LARGEST, HARNESS_LABELS, budgetCheck;
|
|
74900
75563
|
var init_budget3 = __esm({
|
|
74901
75564
|
"../../packages/steering-check/src/checks/budget.ts"() {
|
|
74902
75565
|
"use strict";
|
|
75566
|
+
init_src4();
|
|
74903
75567
|
init_steering_repo();
|
|
74904
75568
|
init_always_on();
|
|
74905
75569
|
init_finding();
|
|
74906
75570
|
init_repo2();
|
|
74907
75571
|
find2 = finder("budget");
|
|
74908
75572
|
LARGEST = 3;
|
|
75573
|
+
HARNESS_LABELS = {
|
|
75574
|
+
"claude-code": "Claude Code",
|
|
75575
|
+
codex: "Codex",
|
|
75576
|
+
cursor: "Cursor",
|
|
75577
|
+
stella: "Stella"
|
|
75578
|
+
};
|
|
74909
75579
|
budgetCheck = (env) => {
|
|
74910
75580
|
const always = alwaysOnPart(env);
|
|
74911
75581
|
const tools = toolsPart(env);
|
|
@@ -76922,7 +77592,9 @@ function importFilename(path2, folder) {
|
|
|
76922
77592
|
async function readImportDocuments(sources, target2, writer) {
|
|
76923
77593
|
const documents = [];
|
|
76924
77594
|
const unreadable = [];
|
|
77595
|
+
const binary = [];
|
|
76925
77596
|
const tooLong = [];
|
|
77597
|
+
const tooMany = [];
|
|
76926
77598
|
for (const source of sources) {
|
|
76927
77599
|
let content;
|
|
76928
77600
|
try {
|
|
@@ -76940,9 +77612,36 @@ async function readImportDocuments(sources, target2, writer) {
|
|
|
76940
77612
|
continue;
|
|
76941
77613
|
}
|
|
76942
77614
|
const filename = importFilename(source.path, source.folder);
|
|
76943
|
-
|
|
76944
|
-
|
|
76945
|
-
);
|
|
77615
|
+
const document = { filename, content };
|
|
77616
|
+
if (target2 !== void 0) document.target = target2;
|
|
77617
|
+
if (source.source !== void 0) document.source = source.source;
|
|
77618
|
+
if (source.files !== void 0 && source.files.length > 0) {
|
|
77619
|
+
const files3 = [];
|
|
77620
|
+
for (const file of source.files) {
|
|
77621
|
+
let text5;
|
|
77622
|
+
try {
|
|
77623
|
+
text5 = await readFile9(file.file, "utf8");
|
|
77624
|
+
} catch {
|
|
77625
|
+
unreadable.push(file.file);
|
|
77626
|
+
continue;
|
|
77627
|
+
}
|
|
77628
|
+
if (text5.includes("\0")) {
|
|
77629
|
+
binary.push(file.file);
|
|
77630
|
+
continue;
|
|
77631
|
+
}
|
|
77632
|
+
if (text5.length > MARKDOWN_IMPORT_FILE_CHARS_MAX) {
|
|
77633
|
+
tooLong.push(file.file);
|
|
77634
|
+
continue;
|
|
77635
|
+
}
|
|
77636
|
+
if (files3.length >= MARKDOWN_IMPORT_SKILL_FILES_MAX) {
|
|
77637
|
+
tooMany.push(file.file);
|
|
77638
|
+
continue;
|
|
77639
|
+
}
|
|
77640
|
+
files3.push({ path: file.path, content: text5 });
|
|
77641
|
+
}
|
|
77642
|
+
if (files3.length > 0) document.files = files3;
|
|
77643
|
+
}
|
|
77644
|
+
documents.push(document);
|
|
76946
77645
|
}
|
|
76947
77646
|
if (unreadable.length > 0) {
|
|
76948
77647
|
writer.writeErr(
|
|
@@ -76950,12 +77649,24 @@ async function readImportDocuments(sources, target2, writer) {
|
|
|
76950
77649
|
${unreadable.join("\n ")}`
|
|
76951
77650
|
);
|
|
76952
77651
|
}
|
|
77652
|
+
if (binary.length > 0) {
|
|
77653
|
+
writer.writeErr(
|
|
77654
|
+
`Skipped binary files, which the import does not carry:
|
|
77655
|
+
${binary.join("\n ")}`
|
|
77656
|
+
);
|
|
77657
|
+
}
|
|
76953
77658
|
if (tooLong.length > 0) {
|
|
76954
77659
|
writer.writeErr(
|
|
76955
77660
|
`Skipped files over ${MARKDOWN_IMPORT_FILE_CHARS_MAX.toLocaleString("en-US")} characters, the most one file may hold:
|
|
76956
77661
|
${tooLong.join("\n ")}`
|
|
76957
77662
|
);
|
|
76958
77663
|
}
|
|
77664
|
+
if (tooMany.length > 0) {
|
|
77665
|
+
writer.writeErr(
|
|
77666
|
+
`Skipped skill files past the ${MARKDOWN_IMPORT_SKILL_FILES_MAX} one skill may carry:
|
|
77667
|
+
${tooMany.join("\n ")}`
|
|
77668
|
+
);
|
|
77669
|
+
}
|
|
76959
77670
|
if (documents.length === 0) {
|
|
76960
77671
|
failCommand("No readable, non-empty files to import.", writer);
|
|
76961
77672
|
}
|
|
@@ -77144,24 +77855,25 @@ var init_markdown_import = __esm({
|
|
|
77144
77855
|
// src/commands/steering-import.ts
|
|
77145
77856
|
var steering_import_exports = {};
|
|
77146
77857
|
__export(steering_import_exports, {
|
|
77147
|
-
|
|
77148
|
-
CURSOR_RULES_FOLDER: () => CURSOR_RULES_FOLDER,
|
|
77149
|
-
CURSOR_RULE_EXTENSIONS: () => CURSOR_RULE_EXTENSIONS,
|
|
77858
|
+
CATALOGUE_FOLDERS: () => CATALOGUE_FOLDERS,
|
|
77150
77859
|
MARKDOWN_EXTENSIONS: () => MARKDOWN_EXTENSIONS,
|
|
77151
77860
|
STEERING_IMPORT_CAPABILITIES: () => STEERING_IMPORT_CAPABILITIES,
|
|
77152
77861
|
findMarkdownFiles: () => findMarkdownFiles,
|
|
77153
77862
|
handleSteeringImport: () => handleSteeringImport
|
|
77154
77863
|
});
|
|
77155
77864
|
import { readdir as readdir4, realpath as realpath2, stat as stat4 } from "node:fs/promises";
|
|
77156
|
-
import { basename as basename8, extname, join as join50 } from "node:path";
|
|
77865
|
+
import { basename as basename8, extname, join as join50, relative as relative7, sep as sep8 } from "node:path";
|
|
77157
77866
|
function byName(a, b5) {
|
|
77158
77867
|
return a.name < b5.name ? -1 : 1;
|
|
77159
77868
|
}
|
|
77869
|
+
function under(root, path2) {
|
|
77870
|
+
return relative7(root, path2).split(sep8).join("/");
|
|
77871
|
+
}
|
|
77160
77872
|
async function findMarkdownFiles(paths) {
|
|
77161
77873
|
const sources = [];
|
|
77162
77874
|
const unreadable = [];
|
|
77163
77875
|
const seen = /* @__PURE__ */ new Set();
|
|
77164
|
-
const take = async (path2,
|
|
77876
|
+
const take = async (path2, extra = {}) => {
|
|
77165
77877
|
let real = path2;
|
|
77166
77878
|
try {
|
|
77167
77879
|
real = await realpath2(path2);
|
|
@@ -77169,9 +77881,29 @@ async function findMarkdownFiles(paths) {
|
|
|
77169
77881
|
}
|
|
77170
77882
|
if (seen.has(real)) return;
|
|
77171
77883
|
seen.add(real);
|
|
77172
|
-
sources.push(
|
|
77884
|
+
sources.push({ path: path2, ...extra });
|
|
77885
|
+
};
|
|
77886
|
+
const filesUnder = async (dir, from) => {
|
|
77887
|
+
let entries2;
|
|
77888
|
+
try {
|
|
77889
|
+
entries2 = await readdir4(dir, { withFileTypes: true });
|
|
77890
|
+
} catch {
|
|
77891
|
+
unreadable.push(dir);
|
|
77892
|
+
return [];
|
|
77893
|
+
}
|
|
77894
|
+
const found = [];
|
|
77895
|
+
for (const entry2 of entries2.sort(byName)) {
|
|
77896
|
+
const path2 = join50(dir, entry2.name);
|
|
77897
|
+
if (entry2.isDirectory()) {
|
|
77898
|
+
if (!entry2.name.startsWith(".") && entry2.name !== "node_modules")
|
|
77899
|
+
found.push(...await filesUnder(path2, from));
|
|
77900
|
+
} else if (entry2.isFile() || entry2.isSymbolicLink()) {
|
|
77901
|
+
if (under(from, path2) !== "SKILL.md") found.push(path2);
|
|
77902
|
+
}
|
|
77903
|
+
}
|
|
77904
|
+
return found;
|
|
77173
77905
|
};
|
|
77174
|
-
const walk2 = async (dir, folder,
|
|
77906
|
+
const walk2 = async (dir, root, folder, inCatalogue) => {
|
|
77175
77907
|
let entries2;
|
|
77176
77908
|
try {
|
|
77177
77909
|
entries2 = await readdir4(dir, { withFileTypes: true });
|
|
@@ -77180,25 +77912,45 @@ async function findMarkdownFiles(paths) {
|
|
|
77180
77912
|
return;
|
|
77181
77913
|
}
|
|
77182
77914
|
entries2.sort(byName);
|
|
77183
|
-
const extensions2 = place2 === "rules" ? CURSOR_RULE_EXTENSIONS : MARKDOWN_EXTENSIONS;
|
|
77184
77915
|
for (const entry2 of entries2) {
|
|
77185
77916
|
const path2 = join50(dir, entry2.name);
|
|
77917
|
+
const rel = under(root, path2);
|
|
77186
77918
|
if (entry2.isDirectory()) {
|
|
77187
|
-
if (place2 === "cursor") {
|
|
77188
|
-
if (entry2.name === CURSOR_RULES_FOLDER) {
|
|
77189
|
-
await walk2(path2, folder, "rules");
|
|
77190
|
-
}
|
|
77191
|
-
continue;
|
|
77192
|
-
}
|
|
77193
77919
|
if (entry2.name === "node_modules") continue;
|
|
77194
|
-
if (entry2.name
|
|
77195
|
-
|
|
77920
|
+
if (entry2.name.startsWith(".")) {
|
|
77921
|
+
if (!inCatalogue && CATALOGUE_FOLDERS.has(entry2.name))
|
|
77922
|
+
await walk2(path2, root, folder, true);
|
|
77196
77923
|
continue;
|
|
77197
77924
|
}
|
|
77198
|
-
|
|
77199
|
-
|
|
77200
|
-
}
|
|
77201
|
-
|
|
77925
|
+
await walk2(path2, root, folder, inCatalogue);
|
|
77926
|
+
continue;
|
|
77927
|
+
}
|
|
77928
|
+
if (!entry2.isFile() && !entry2.isSymbolicLink()) continue;
|
|
77929
|
+
const source = markdownImportSourceOf(rel);
|
|
77930
|
+
if (inCatalogue) {
|
|
77931
|
+
if (source === null) continue;
|
|
77932
|
+
if (source.kind === "skill") {
|
|
77933
|
+
const skillDir = dir;
|
|
77934
|
+
await take(path2, {
|
|
77935
|
+
folder,
|
|
77936
|
+
source: { ...source, path: rel },
|
|
77937
|
+
files: (await filesUnder(skillDir, skillDir)).map((file) => ({
|
|
77938
|
+
path: under(skillDir, file),
|
|
77939
|
+
file
|
|
77940
|
+
}))
|
|
77941
|
+
});
|
|
77942
|
+
} else {
|
|
77943
|
+
await take(path2, { folder, source: { ...source, path: rel } });
|
|
77944
|
+
}
|
|
77945
|
+
continue;
|
|
77946
|
+
}
|
|
77947
|
+
if (MARKDOWN_EXTENSIONS.has(extname(entry2.name).toLowerCase())) {
|
|
77948
|
+
await take(
|
|
77949
|
+
path2,
|
|
77950
|
+
source === null ? { folder } : { folder, source: { ...source, path: rel } }
|
|
77951
|
+
);
|
|
77952
|
+
} else if (source !== null && source.kind === "instructions") {
|
|
77953
|
+
await take(path2, { folder, source: { ...source, path: rel } });
|
|
77202
77954
|
}
|
|
77203
77955
|
}
|
|
77204
77956
|
};
|
|
@@ -77211,9 +77963,16 @@ async function findMarkdownFiles(paths) {
|
|
|
77211
77963
|
continue;
|
|
77212
77964
|
}
|
|
77213
77965
|
if (isFolder) {
|
|
77214
|
-
const
|
|
77215
|
-
await walk2(path2, path2,
|
|
77216
|
-
} else
|
|
77966
|
+
const named = CATALOGUE_FOLDERS.has(basename8(path2));
|
|
77967
|
+
await walk2(path2, named ? join50(path2, "..") : path2, path2, false);
|
|
77968
|
+
} else {
|
|
77969
|
+
const rel = under(process.cwd(), path2);
|
|
77970
|
+
const source = rel.startsWith("..") ? null : markdownImportSourceOf(rel);
|
|
77971
|
+
await take(
|
|
77972
|
+
path2,
|
|
77973
|
+
source === null ? {} : { source: { ...source, path: rel } }
|
|
77974
|
+
);
|
|
77975
|
+
}
|
|
77217
77976
|
}
|
|
77218
77977
|
return { sources, unreadable };
|
|
77219
77978
|
}
|
|
@@ -77254,9 +78013,11 @@ async function handleSteeringImport(paths, opts, writer = stdoutWriter) {
|
|
|
77254
78013
|
writer
|
|
77255
78014
|
);
|
|
77256
78015
|
}
|
|
77257
|
-
var STEERING_IMPORT_CAPABILITIES, MARKDOWN_EXTENSIONS,
|
|
78016
|
+
var STEERING_IMPORT_CAPABILITIES, MARKDOWN_EXTENSIONS, CATALOGUE_FOLDERS, TARGETS;
|
|
77258
78017
|
var init_steering_import = __esm({
|
|
77259
78018
|
"src/commands/steering-import.ts"() {
|
|
78019
|
+
init_steering_markdown_import_shared();
|
|
78020
|
+
init_harness_files();
|
|
77260
78021
|
init_capture_writer();
|
|
77261
78022
|
init_markdown_import();
|
|
77262
78023
|
STEERING_IMPORT_CAPABILITIES = [
|
|
@@ -77269,12 +78030,11 @@ var init_steering_import = __esm({
|
|
|
77269
78030
|
".mdx",
|
|
77270
78031
|
".mdc"
|
|
77271
78032
|
]);
|
|
77272
|
-
|
|
77273
|
-
|
|
77274
|
-
|
|
77275
|
-
|
|
77276
|
-
|
|
77277
|
-
]);
|
|
78033
|
+
CATALOGUE_FOLDERS = new Set(
|
|
78034
|
+
WELL_KNOWN_FOLDERS.map((folder) => folder.split("/")[0] ?? "").filter(
|
|
78035
|
+
(name) => name.startsWith(".")
|
|
78036
|
+
)
|
|
78037
|
+
);
|
|
77278
78038
|
TARGETS = [
|
|
77279
78039
|
"records",
|
|
77280
78040
|
"policies",
|
|
@@ -79401,7 +80161,7 @@ async function handleMemoryList(opts, writer = stdoutWriter) {
|
|
|
79401
80161
|
const states2 = listOpt(opts.state);
|
|
79402
80162
|
for (const state of states2)
|
|
79403
80163
|
oneOf(state, WORKSPACE_MEMORY_STATES, "--state", writer);
|
|
79404
|
-
const harness = oneOf(opts.harness,
|
|
80164
|
+
const harness = oneOf(opts.harness, HARNESSES3, "--harness", writer);
|
|
79405
80165
|
try {
|
|
79406
80166
|
const result2 = await listWorkspaceMemories({
|
|
79407
80167
|
states: states2.length === 0 ? void 0 : states2,
|
|
@@ -79608,7 +80368,7 @@ async function handleMemoryImport(files3, opts, writer = stdoutWriter) {
|
|
|
79608
80368
|
writer
|
|
79609
80369
|
);
|
|
79610
80370
|
}
|
|
79611
|
-
var MEMORY_COMMAND_CAPABILITIES,
|
|
80371
|
+
var MEMORY_COMMAND_CAPABILITIES, HARNESSES3, KINDS2, FORCES2, EFFECTS2, DISMISS_REASONS, MEMORY_IMPORT_CAPABILITIES;
|
|
79612
80372
|
var init_memory2 = __esm({
|
|
79613
80373
|
"src/commands/memory.ts"() {
|
|
79614
80374
|
init_api();
|
|
@@ -79623,7 +80383,7 @@ var init_memory2 = __esm({
|
|
|
79623
80383
|
"dismiss_memories",
|
|
79624
80384
|
"drop_memory_record"
|
|
79625
80385
|
];
|
|
79626
|
-
|
|
80386
|
+
HARNESSES3 = [
|
|
79627
80387
|
"claude-code",
|
|
79628
80388
|
"codex",
|
|
79629
80389
|
"cursor",
|
|
@@ -79901,7 +80661,7 @@ import {
|
|
|
79901
80661
|
writeFileSync as writeFileSync10
|
|
79902
80662
|
} from "node:fs";
|
|
79903
80663
|
import { homedir as homedir12, hostname as osHostname3 } from "node:os";
|
|
79904
|
-
import { join as join52, relative as
|
|
80664
|
+
import { join as join52, relative as relative8, resolve as resolve20, sep as sep9 } from "node:path";
|
|
79905
80665
|
function git4(cwd, args) {
|
|
79906
80666
|
return new Promise((done) => {
|
|
79907
80667
|
try {
|
|
@@ -79972,7 +80732,7 @@ function symlinkState(root) {
|
|
|
79972
80732
|
try {
|
|
79973
80733
|
if (!lstatSync9(at).isSymbolicLink()) return "missing";
|
|
79974
80734
|
const target2 = realpathSync8(at);
|
|
79975
|
-
if (target2 !== oxagenReal && !target2.startsWith(oxagenReal +
|
|
80735
|
+
if (target2 !== oxagenReal && !target2.startsWith(oxagenReal + sep9)) {
|
|
79976
80736
|
return "missing";
|
|
79977
80737
|
}
|
|
79978
80738
|
} catch {
|
|
@@ -80062,10 +80822,10 @@ async function ensureWorkspaceLinkIgnored(root) {
|
|
|
80062
80822
|
const top = await git4(root, ["rev-parse", "--show-toplevel"]);
|
|
80063
80823
|
if (!top) return null;
|
|
80064
80824
|
const topDir = resolve20(top);
|
|
80065
|
-
const entry2 =
|
|
80825
|
+
const entry2 = relative8(
|
|
80066
80826
|
topDir,
|
|
80067
80827
|
join52(realpathOr2(root), ".oxagen", "workspace.json")
|
|
80068
|
-
).split(
|
|
80828
|
+
).split(sep9).join("/");
|
|
80069
80829
|
if (entry2.startsWith("../")) return null;
|
|
80070
80830
|
const rule = await git4(topDir, ["check-ignore", "--no-index", "-v", entry2]);
|
|
80071
80831
|
if (rule !== null) return null;
|
|
@@ -80556,7 +81316,7 @@ import {
|
|
|
80556
81316
|
join as join53,
|
|
80557
81317
|
parse as parsePath2,
|
|
80558
81318
|
posix as posix4,
|
|
80559
|
-
sep as
|
|
81319
|
+
sep as sep10
|
|
80560
81320
|
} from "node:path";
|
|
80561
81321
|
function checkSteeringPath(path2) {
|
|
80562
81322
|
if (typeof path2 !== "string" || path2.length === 0) {
|
|
@@ -80703,7 +81463,7 @@ function assertInsideOxagen(root, path2) {
|
|
|
80703
81463
|
real = null;
|
|
80704
81464
|
}
|
|
80705
81465
|
if (real !== null) {
|
|
80706
|
-
if (real !== oxagenReal && !real.startsWith(oxagenReal +
|
|
81466
|
+
if (real !== oxagenReal && !real.startsWith(oxagenReal + sep10)) {
|
|
80707
81467
|
throw new Error(`${path2} resolves outside .oxagen/`);
|
|
80708
81468
|
}
|
|
80709
81469
|
return;
|
|
@@ -80716,7 +81476,7 @@ function assertInsideOxagen(root, path2) {
|
|
|
80716
81476
|
function pruneEmptyDirs(root, path2) {
|
|
80717
81477
|
const stop = join53(root, OXAGEN_DIR);
|
|
80718
81478
|
let dir = dirname29(join53(root, ...path2.split("/")));
|
|
80719
|
-
while (dir.startsWith(stop +
|
|
81479
|
+
while (dir.startsWith(stop + sep10)) {
|
|
80720
81480
|
try {
|
|
80721
81481
|
if (readdirSync14(dir).length > 0) return;
|
|
80722
81482
|
rmdirSync7(dir);
|
|
@@ -124033,7 +124793,7 @@ import {
|
|
|
124033
124793
|
readlinkSync as readlinkSync4,
|
|
124034
124794
|
statSync as statSync13
|
|
124035
124795
|
} from "node:fs";
|
|
124036
|
-
import { dirname as dirname30, isAbsolute as isAbsolute15, join as join54, relative as
|
|
124796
|
+
import { dirname as dirname30, isAbsolute as isAbsolute15, join as join54, relative as relative9, resolve as resolve22, sep as sep11 } from "node:path";
|
|
124037
124797
|
function git5(cwd, args, input) {
|
|
124038
124798
|
try {
|
|
124039
124799
|
return execFileSync2("git", args, {
|
|
@@ -124173,11 +124933,11 @@ function within3(path2, scope) {
|
|
|
124173
124933
|
function scopesFor(root, cwd, paths, trees) {
|
|
124174
124934
|
const scopes = [];
|
|
124175
124935
|
for (const path2 of paths) {
|
|
124176
|
-
const rel =
|
|
124177
|
-
if (rel === ".." || rel.startsWith(`..${
|
|
124936
|
+
const rel = relative9(root, resolve22(cwd, path2));
|
|
124937
|
+
if (rel === ".." || rel.startsWith(`..${sep11}`) || isAbsolute15(rel)) {
|
|
124178
124938
|
return { error: `${path2} is outside the steering repo at ${root}.` };
|
|
124179
124939
|
}
|
|
124180
|
-
const scope = rel.split(
|
|
124940
|
+
const scope = rel.split(sep11).join("/");
|
|
124181
124941
|
const known = trees.some(
|
|
124182
124942
|
(tree) => tree !== null && [...tree.keys()].some((file) => within3(file, scope))
|
|
124183
124943
|
);
|
|
@@ -124485,7 +125245,7 @@ async function check(paths = [], opts = {}, writer = stdoutWriter, cwd = process
|
|
|
124485
125245
|
}
|
|
124486
125246
|
if (!report.passed) process.exitCode = 1;
|
|
124487
125247
|
}
|
|
124488
|
-
var
|
|
125248
|
+
var ROOT_FILES3, TREE_DIRS, PATHSPECS, DEFAULT_BASES, NOT_A_STEERING_REPO, NO_BASE, GIT_TIMEOUT_MS2, GIT_MAX_BUFFER, CACHE_MAX_AGE_MS, CONTEXT_KEYS, workspaceSlugs, KEY_SCOPE_MISMATCH, ScopeMismatchError;
|
|
124489
125249
|
var init_check3 = __esm({
|
|
124490
125250
|
"src/commands/check.ts"() {
|
|
124491
125251
|
init_paths2();
|
|
@@ -124498,7 +125258,7 @@ var init_check3 = __esm({
|
|
|
124498
125258
|
init_capture_writer();
|
|
124499
125259
|
init_config();
|
|
124500
125260
|
init_output();
|
|
124501
|
-
|
|
125261
|
+
ROOT_FILES3 = [
|
|
124502
125262
|
AGENTS_MD_PATH,
|
|
124503
125263
|
CLAUDE_MD_PATH,
|
|
124504
125264
|
README_PATH,
|
|
@@ -124511,7 +125271,7 @@ var init_check3 = __esm({
|
|
|
124511
125271
|
TOOLS_DIR,
|
|
124512
125272
|
POLICY_DIR
|
|
124513
125273
|
];
|
|
124514
|
-
PATHSPECS = [...
|
|
125274
|
+
PATHSPECS = [...ROOT_FILES3, ...TREE_DIRS];
|
|
124515
125275
|
DEFAULT_BASES = ["origin/HEAD", "origin/main"];
|
|
124516
125276
|
NOT_A_STEERING_REPO = "This directory is not in a steering repo. Run oxagen check inside a clone that holds workspace.toml, or AGENTS.md and steering/ for an organization repo.";
|
|
124517
125277
|
NO_BASE = `No production branch to compare with. ${DEFAULT_BASES.join(" and ")} do not resolve in this clone, so the checks read the working tree whole. Pass --base <ref> to compare with a branch.`;
|
|
@@ -128189,13 +128949,13 @@ var init_src9 = __esm({
|
|
|
128189
128949
|
|
|
128190
128950
|
// src/commands/codegraph-upload/files.ts
|
|
128191
128951
|
import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
|
|
128192
|
-
import { join as join55, relative as
|
|
128952
|
+
import { join as join55, relative as relative10, sep as sep12 } from "node:path";
|
|
128193
128953
|
function hasGlobChars(pattern) {
|
|
128194
128954
|
return /[*?[\]{}]/.test(pattern);
|
|
128195
128955
|
}
|
|
128196
128956
|
function normalize2(path2) {
|
|
128197
128957
|
const trimmed = path2.replace(/^\.\//, "");
|
|
128198
|
-
return
|
|
128958
|
+
return sep12 === "/" ? trimmed : trimmed.split(sep12).join("/");
|
|
128199
128959
|
}
|
|
128200
128960
|
async function walk(root, dir, out) {
|
|
128201
128961
|
const entries2 = await readdir5(dir, { withFileTypes: true });
|
|
@@ -128205,7 +128965,7 @@ async function walk(root, dir, out) {
|
|
|
128205
128965
|
if (entry2.isDirectory()) {
|
|
128206
128966
|
if (!SKIP_DIRS.has(entry2.name)) await walk(root, full, out);
|
|
128207
128967
|
} else if (entry2.isFile()) {
|
|
128208
|
-
out.push(normalize2(
|
|
128968
|
+
out.push(normalize2(relative10(root, full)));
|
|
128209
128969
|
}
|
|
128210
128970
|
}
|
|
128211
128971
|
}
|