@oxagen/cli 2.1.4-679 → 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 +2227 -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",
|
|
@@ -72108,1173 +73506,401 @@ var init_codegraph_settings = __esm({
|
|
|
72108
73506
|
),
|
|
72109
73507
|
30
|
|
72110
73508
|
),
|
|
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
|
|
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
|
|
|
@@ -73355,7 +73981,7 @@ var init_run_shared = __esm({
|
|
|
73355
73981
|
});
|
|
73356
73982
|
|
|
73357
73983
|
// ../../packages/oxagen/src/contracts/run.list.ts
|
|
73358
|
-
var runPublicIdSchema, runSourceSchema, runStatusSchema, runOutcomeSchema, runCostSchema, replayGradeSchema, generatedRunSummarySchema, editedRunSummarySchema, runSummarySchema, operatorKindSchema, RUN_OPERATOR_ROLES, runOperatorRoleSchema, runModelSchema, runMachineSnapshotSchema, runMachineSchema, COMMAND_BLOCKS, STEER_BLOCKS, HOST_POLL_WINDOW_MS, RUN_PULL_REQUEST_MAX, runPullRequestSchema, runDiffSchema, RUN_PULL_REQUEST_FILTERS, RUN_PAUSE_STATES, runPauseSchema, RUN_REPLAY_FILTERS, RUN_SORT_KEYS, RUN_LIST_TOTAL_BOUND, RUN_LABEL_MAX, runItemSchema, runList;
|
|
73984
|
+
var runPublicIdSchema, runSourceSchema, runStatusSchema, runOutcomeSchema, runCostSchema, replayGradeSchema, generatedRunSummarySchema, editedRunSummarySchema, runSummarySchema, operatorKindSchema, RUN_OPERATOR_ROLES, runOperatorRoleSchema, runModelSchema, runMachineSnapshotSchema, runMachineSchema, COMMAND_BLOCKS, STEER_BLOCKS, HOST_POLL_WINDOW_MS, RUN_PULL_REQUEST_MAX, runPullRequestSchema, runDiffSchema, runAttributionSchema, RUN_PULL_REQUEST_FILTERS, RUN_PAUSE_STATES, runPauseSchema, RUN_REPLAY_FILTERS, RUN_SORT_KEYS, RUN_LIST_TOTAL_BOUND, RUN_LABEL_MAX, runItemSchema, runList;
|
|
73359
73985
|
var init_run_list = __esm({
|
|
73360
73986
|
"../../packages/oxagen/src/contracts/run.list.ts"() {
|
|
73361
73987
|
"use strict";
|
|
@@ -73465,6 +74091,13 @@ var init_run_list = __esm({
|
|
|
73465
74091
|
removed: external_exports.number().int().nonnegative(),
|
|
73466
74092
|
basis: external_exports.enum(["harness_reported", "git_observed"])
|
|
73467
74093
|
}).strict();
|
|
74094
|
+
runAttributionSchema = external_exports.object({
|
|
74095
|
+
commits: external_exports.number().int().nonnegative(),
|
|
74096
|
+
merges: external_exports.number().int().nonnegative(),
|
|
74097
|
+
written: external_exports.object({ added: external_exports.number().int().nonnegative(), removed: external_exports.number().int().nonnegative() }),
|
|
74098
|
+
shipped: external_exports.object({ added: external_exports.number().int().nonnegative(), removed: external_exports.number().int().nonnegative() }).nullable(),
|
|
74099
|
+
uncommitted: external_exports.object({ added: external_exports.number().int().nonnegative(), removed: external_exports.number().int().nonnegative() }).nullable()
|
|
74100
|
+
});
|
|
73468
74101
|
RUN_PULL_REQUEST_FILTERS = ["any", "with", "without"];
|
|
73469
74102
|
RUN_PAUSE_STATES = ["pausing", "paused", "resuming"];
|
|
73470
74103
|
runPauseSchema = external_exports.object({
|
|
@@ -73810,6 +74443,7 @@ var init_run_list = __esm({
|
|
|
73810
74443
|
pullRequestsOpened: external_exports.number().int().nonnegative().optional(),
|
|
73811
74444
|
/** Lines added and removed; null when neither the harness nor git reported any. */
|
|
73812
74445
|
diff: runDiffSchema.nullable().optional(),
|
|
74446
|
+
attribution: runAttributionSchema.nullable().optional(),
|
|
73813
74447
|
/**
|
|
73814
74448
|
* The run's token counts by class, from its `cost.run_totals` row. Null
|
|
73815
74449
|
* when the run has no rollup row. The column is NOT NULL, so an unpriced
|
|
@@ -74722,6 +75356,41 @@ function definitionBudget(tree) {
|
|
|
74722
75356
|
function repositoryName(repository) {
|
|
74723
75357
|
return repository ?? "a repository no record names";
|
|
74724
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
|
+
}
|
|
74725
75394
|
function sameBudget(a, b5) {
|
|
74726
75395
|
if (a === "off" || b5 === "off") return a === b5;
|
|
74727
75396
|
return a.tokens === b5.tokens;
|
|
@@ -74776,6 +75445,8 @@ function alwaysOnPart(env) {
|
|
|
74776
75445
|
const line = governance === void 0 ? null : tomlLine(governance, "steering.always_on_tokens");
|
|
74777
75446
|
const findings = [];
|
|
74778
75447
|
const notes = [];
|
|
75448
|
+
const ceiling = budgetCeiling(budget, line);
|
|
75449
|
+
if (ceiling !== null) findings.push(ceiling);
|
|
74779
75450
|
for (const block of alwaysOnBlocks(env.head)) {
|
|
74780
75451
|
const prior = before.get(block.repository);
|
|
74781
75452
|
if (!budgetMoved && prior?.text === block.text) continue;
|
|
@@ -74888,16 +75559,23 @@ function toolsPart(env) {
|
|
|
74888
75559
|
]
|
|
74889
75560
|
};
|
|
74890
75561
|
}
|
|
74891
|
-
var find2, LARGEST, budgetCheck;
|
|
75562
|
+
var find2, LARGEST, HARNESS_LABELS, budgetCheck;
|
|
74892
75563
|
var init_budget3 = __esm({
|
|
74893
75564
|
"../../packages/steering-check/src/checks/budget.ts"() {
|
|
74894
75565
|
"use strict";
|
|
75566
|
+
init_src4();
|
|
74895
75567
|
init_steering_repo();
|
|
74896
75568
|
init_always_on();
|
|
74897
75569
|
init_finding();
|
|
74898
75570
|
init_repo2();
|
|
74899
75571
|
find2 = finder("budget");
|
|
74900
75572
|
LARGEST = 3;
|
|
75573
|
+
HARNESS_LABELS = {
|
|
75574
|
+
"claude-code": "Claude Code",
|
|
75575
|
+
codex: "Codex",
|
|
75576
|
+
cursor: "Cursor",
|
|
75577
|
+
stella: "Stella"
|
|
75578
|
+
};
|
|
74901
75579
|
budgetCheck = (env) => {
|
|
74902
75580
|
const always = alwaysOnPart(env);
|
|
74903
75581
|
const tools = toolsPart(env);
|
|
@@ -76914,7 +77592,9 @@ function importFilename(path2, folder) {
|
|
|
76914
77592
|
async function readImportDocuments(sources, target2, writer) {
|
|
76915
77593
|
const documents = [];
|
|
76916
77594
|
const unreadable = [];
|
|
77595
|
+
const binary = [];
|
|
76917
77596
|
const tooLong = [];
|
|
77597
|
+
const tooMany = [];
|
|
76918
77598
|
for (const source of sources) {
|
|
76919
77599
|
let content;
|
|
76920
77600
|
try {
|
|
@@ -76932,9 +77612,36 @@ async function readImportDocuments(sources, target2, writer) {
|
|
|
76932
77612
|
continue;
|
|
76933
77613
|
}
|
|
76934
77614
|
const filename = importFilename(source.path, source.folder);
|
|
76935
|
-
|
|
76936
|
-
|
|
76937
|
-
);
|
|
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);
|
|
76938
77645
|
}
|
|
76939
77646
|
if (unreadable.length > 0) {
|
|
76940
77647
|
writer.writeErr(
|
|
@@ -76942,12 +77649,24 @@ async function readImportDocuments(sources, target2, writer) {
|
|
|
76942
77649
|
${unreadable.join("\n ")}`
|
|
76943
77650
|
);
|
|
76944
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
|
+
}
|
|
76945
77658
|
if (tooLong.length > 0) {
|
|
76946
77659
|
writer.writeErr(
|
|
76947
77660
|
`Skipped files over ${MARKDOWN_IMPORT_FILE_CHARS_MAX.toLocaleString("en-US")} characters, the most one file may hold:
|
|
76948
77661
|
${tooLong.join("\n ")}`
|
|
76949
77662
|
);
|
|
76950
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
|
+
}
|
|
76951
77670
|
if (documents.length === 0) {
|
|
76952
77671
|
failCommand("No readable, non-empty files to import.", writer);
|
|
76953
77672
|
}
|
|
@@ -77136,24 +77855,25 @@ var init_markdown_import = __esm({
|
|
|
77136
77855
|
// src/commands/steering-import.ts
|
|
77137
77856
|
var steering_import_exports = {};
|
|
77138
77857
|
__export(steering_import_exports, {
|
|
77139
|
-
|
|
77140
|
-
CURSOR_RULES_FOLDER: () => CURSOR_RULES_FOLDER,
|
|
77141
|
-
CURSOR_RULE_EXTENSIONS: () => CURSOR_RULE_EXTENSIONS,
|
|
77858
|
+
CATALOGUE_FOLDERS: () => CATALOGUE_FOLDERS,
|
|
77142
77859
|
MARKDOWN_EXTENSIONS: () => MARKDOWN_EXTENSIONS,
|
|
77143
77860
|
STEERING_IMPORT_CAPABILITIES: () => STEERING_IMPORT_CAPABILITIES,
|
|
77144
77861
|
findMarkdownFiles: () => findMarkdownFiles,
|
|
77145
77862
|
handleSteeringImport: () => handleSteeringImport
|
|
77146
77863
|
});
|
|
77147
77864
|
import { readdir as readdir4, realpath as realpath2, stat as stat4 } from "node:fs/promises";
|
|
77148
|
-
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";
|
|
77149
77866
|
function byName(a, b5) {
|
|
77150
77867
|
return a.name < b5.name ? -1 : 1;
|
|
77151
77868
|
}
|
|
77869
|
+
function under(root, path2) {
|
|
77870
|
+
return relative7(root, path2).split(sep8).join("/");
|
|
77871
|
+
}
|
|
77152
77872
|
async function findMarkdownFiles(paths) {
|
|
77153
77873
|
const sources = [];
|
|
77154
77874
|
const unreadable = [];
|
|
77155
77875
|
const seen = /* @__PURE__ */ new Set();
|
|
77156
|
-
const take = async (path2,
|
|
77876
|
+
const take = async (path2, extra = {}) => {
|
|
77157
77877
|
let real = path2;
|
|
77158
77878
|
try {
|
|
77159
77879
|
real = await realpath2(path2);
|
|
@@ -77161,9 +77881,29 @@ async function findMarkdownFiles(paths) {
|
|
|
77161
77881
|
}
|
|
77162
77882
|
if (seen.has(real)) return;
|
|
77163
77883
|
seen.add(real);
|
|
77164
|
-
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;
|
|
77165
77905
|
};
|
|
77166
|
-
const walk2 = async (dir, folder,
|
|
77906
|
+
const walk2 = async (dir, root, folder, inCatalogue) => {
|
|
77167
77907
|
let entries2;
|
|
77168
77908
|
try {
|
|
77169
77909
|
entries2 = await readdir4(dir, { withFileTypes: true });
|
|
@@ -77172,25 +77912,45 @@ async function findMarkdownFiles(paths) {
|
|
|
77172
77912
|
return;
|
|
77173
77913
|
}
|
|
77174
77914
|
entries2.sort(byName);
|
|
77175
|
-
const extensions2 = place2 === "rules" ? CURSOR_RULE_EXTENSIONS : MARKDOWN_EXTENSIONS;
|
|
77176
77915
|
for (const entry2 of entries2) {
|
|
77177
77916
|
const path2 = join50(dir, entry2.name);
|
|
77917
|
+
const rel = under(root, path2);
|
|
77178
77918
|
if (entry2.isDirectory()) {
|
|
77179
|
-
if (place2 === "cursor") {
|
|
77180
|
-
if (entry2.name === CURSOR_RULES_FOLDER) {
|
|
77181
|
-
await walk2(path2, folder, "rules");
|
|
77182
|
-
}
|
|
77183
|
-
continue;
|
|
77184
|
-
}
|
|
77185
77919
|
if (entry2.name === "node_modules") continue;
|
|
77186
|
-
if (entry2.name
|
|
77187
|
-
|
|
77920
|
+
if (entry2.name.startsWith(".")) {
|
|
77921
|
+
if (!inCatalogue && CATALOGUE_FOLDERS.has(entry2.name))
|
|
77922
|
+
await walk2(path2, root, folder, true);
|
|
77188
77923
|
continue;
|
|
77189
77924
|
}
|
|
77190
|
-
|
|
77191
|
-
|
|
77192
|
-
}
|
|
77193
|
-
|
|
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 } });
|
|
77194
77954
|
}
|
|
77195
77955
|
}
|
|
77196
77956
|
};
|
|
@@ -77203,9 +77963,16 @@ async function findMarkdownFiles(paths) {
|
|
|
77203
77963
|
continue;
|
|
77204
77964
|
}
|
|
77205
77965
|
if (isFolder) {
|
|
77206
|
-
const
|
|
77207
|
-
await walk2(path2, path2,
|
|
77208
|
-
} 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
|
+
}
|
|
77209
77976
|
}
|
|
77210
77977
|
return { sources, unreadable };
|
|
77211
77978
|
}
|
|
@@ -77246,9 +78013,11 @@ async function handleSteeringImport(paths, opts, writer = stdoutWriter) {
|
|
|
77246
78013
|
writer
|
|
77247
78014
|
);
|
|
77248
78015
|
}
|
|
77249
|
-
var STEERING_IMPORT_CAPABILITIES, MARKDOWN_EXTENSIONS,
|
|
78016
|
+
var STEERING_IMPORT_CAPABILITIES, MARKDOWN_EXTENSIONS, CATALOGUE_FOLDERS, TARGETS;
|
|
77250
78017
|
var init_steering_import = __esm({
|
|
77251
78018
|
"src/commands/steering-import.ts"() {
|
|
78019
|
+
init_steering_markdown_import_shared();
|
|
78020
|
+
init_harness_files();
|
|
77252
78021
|
init_capture_writer();
|
|
77253
78022
|
init_markdown_import();
|
|
77254
78023
|
STEERING_IMPORT_CAPABILITIES = [
|
|
@@ -77261,12 +78030,11 @@ var init_steering_import = __esm({
|
|
|
77261
78030
|
".mdx",
|
|
77262
78031
|
".mdc"
|
|
77263
78032
|
]);
|
|
77264
|
-
|
|
77265
|
-
|
|
77266
|
-
|
|
77267
|
-
|
|
77268
|
-
|
|
77269
|
-
]);
|
|
78033
|
+
CATALOGUE_FOLDERS = new Set(
|
|
78034
|
+
WELL_KNOWN_FOLDERS.map((folder) => folder.split("/")[0] ?? "").filter(
|
|
78035
|
+
(name) => name.startsWith(".")
|
|
78036
|
+
)
|
|
78037
|
+
);
|
|
77270
78038
|
TARGETS = [
|
|
77271
78039
|
"records",
|
|
77272
78040
|
"policies",
|
|
@@ -79393,7 +80161,7 @@ async function handleMemoryList(opts, writer = stdoutWriter) {
|
|
|
79393
80161
|
const states2 = listOpt(opts.state);
|
|
79394
80162
|
for (const state of states2)
|
|
79395
80163
|
oneOf(state, WORKSPACE_MEMORY_STATES, "--state", writer);
|
|
79396
|
-
const harness = oneOf(opts.harness,
|
|
80164
|
+
const harness = oneOf(opts.harness, HARNESSES3, "--harness", writer);
|
|
79397
80165
|
try {
|
|
79398
80166
|
const result2 = await listWorkspaceMemories({
|
|
79399
80167
|
states: states2.length === 0 ? void 0 : states2,
|
|
@@ -79600,7 +80368,7 @@ async function handleMemoryImport(files3, opts, writer = stdoutWriter) {
|
|
|
79600
80368
|
writer
|
|
79601
80369
|
);
|
|
79602
80370
|
}
|
|
79603
|
-
var MEMORY_COMMAND_CAPABILITIES,
|
|
80371
|
+
var MEMORY_COMMAND_CAPABILITIES, HARNESSES3, KINDS2, FORCES2, EFFECTS2, DISMISS_REASONS, MEMORY_IMPORT_CAPABILITIES;
|
|
79604
80372
|
var init_memory2 = __esm({
|
|
79605
80373
|
"src/commands/memory.ts"() {
|
|
79606
80374
|
init_api();
|
|
@@ -79615,7 +80383,7 @@ var init_memory2 = __esm({
|
|
|
79615
80383
|
"dismiss_memories",
|
|
79616
80384
|
"drop_memory_record"
|
|
79617
80385
|
];
|
|
79618
|
-
|
|
80386
|
+
HARNESSES3 = [
|
|
79619
80387
|
"claude-code",
|
|
79620
80388
|
"codex",
|
|
79621
80389
|
"cursor",
|
|
@@ -79893,7 +80661,7 @@ import {
|
|
|
79893
80661
|
writeFileSync as writeFileSync10
|
|
79894
80662
|
} from "node:fs";
|
|
79895
80663
|
import { homedir as homedir12, hostname as osHostname3 } from "node:os";
|
|
79896
|
-
import { join as join52, relative as
|
|
80664
|
+
import { join as join52, relative as relative8, resolve as resolve20, sep as sep9 } from "node:path";
|
|
79897
80665
|
function git4(cwd, args) {
|
|
79898
80666
|
return new Promise((done) => {
|
|
79899
80667
|
try {
|
|
@@ -79964,7 +80732,7 @@ function symlinkState(root) {
|
|
|
79964
80732
|
try {
|
|
79965
80733
|
if (!lstatSync9(at).isSymbolicLink()) return "missing";
|
|
79966
80734
|
const target2 = realpathSync8(at);
|
|
79967
|
-
if (target2 !== oxagenReal && !target2.startsWith(oxagenReal +
|
|
80735
|
+
if (target2 !== oxagenReal && !target2.startsWith(oxagenReal + sep9)) {
|
|
79968
80736
|
return "missing";
|
|
79969
80737
|
}
|
|
79970
80738
|
} catch {
|
|
@@ -80054,10 +80822,10 @@ async function ensureWorkspaceLinkIgnored(root) {
|
|
|
80054
80822
|
const top = await git4(root, ["rev-parse", "--show-toplevel"]);
|
|
80055
80823
|
if (!top) return null;
|
|
80056
80824
|
const topDir = resolve20(top);
|
|
80057
|
-
const entry2 =
|
|
80825
|
+
const entry2 = relative8(
|
|
80058
80826
|
topDir,
|
|
80059
80827
|
join52(realpathOr2(root), ".oxagen", "workspace.json")
|
|
80060
|
-
).split(
|
|
80828
|
+
).split(sep9).join("/");
|
|
80061
80829
|
if (entry2.startsWith("../")) return null;
|
|
80062
80830
|
const rule = await git4(topDir, ["check-ignore", "--no-index", "-v", entry2]);
|
|
80063
80831
|
if (rule !== null) return null;
|
|
@@ -80548,7 +81316,7 @@ import {
|
|
|
80548
81316
|
join as join53,
|
|
80549
81317
|
parse as parsePath2,
|
|
80550
81318
|
posix as posix4,
|
|
80551
|
-
sep as
|
|
81319
|
+
sep as sep10
|
|
80552
81320
|
} from "node:path";
|
|
80553
81321
|
function checkSteeringPath(path2) {
|
|
80554
81322
|
if (typeof path2 !== "string" || path2.length === 0) {
|
|
@@ -80695,7 +81463,7 @@ function assertInsideOxagen(root, path2) {
|
|
|
80695
81463
|
real = null;
|
|
80696
81464
|
}
|
|
80697
81465
|
if (real !== null) {
|
|
80698
|
-
if (real !== oxagenReal && !real.startsWith(oxagenReal +
|
|
81466
|
+
if (real !== oxagenReal && !real.startsWith(oxagenReal + sep10)) {
|
|
80699
81467
|
throw new Error(`${path2} resolves outside .oxagen/`);
|
|
80700
81468
|
}
|
|
80701
81469
|
return;
|
|
@@ -80708,7 +81476,7 @@ function assertInsideOxagen(root, path2) {
|
|
|
80708
81476
|
function pruneEmptyDirs(root, path2) {
|
|
80709
81477
|
const stop = join53(root, OXAGEN_DIR);
|
|
80710
81478
|
let dir = dirname29(join53(root, ...path2.split("/")));
|
|
80711
|
-
while (dir.startsWith(stop +
|
|
81479
|
+
while (dir.startsWith(stop + sep10)) {
|
|
80712
81480
|
try {
|
|
80713
81481
|
if (readdirSync14(dir).length > 0) return;
|
|
80714
81482
|
rmdirSync7(dir);
|
|
@@ -124025,7 +124793,7 @@ import {
|
|
|
124025
124793
|
readlinkSync as readlinkSync4,
|
|
124026
124794
|
statSync as statSync13
|
|
124027
124795
|
} from "node:fs";
|
|
124028
|
-
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";
|
|
124029
124797
|
function git5(cwd, args, input) {
|
|
124030
124798
|
try {
|
|
124031
124799
|
return execFileSync2("git", args, {
|
|
@@ -124165,11 +124933,11 @@ function within3(path2, scope) {
|
|
|
124165
124933
|
function scopesFor(root, cwd, paths, trees) {
|
|
124166
124934
|
const scopes = [];
|
|
124167
124935
|
for (const path2 of paths) {
|
|
124168
|
-
const rel =
|
|
124169
|
-
if (rel === ".." || rel.startsWith(`..${
|
|
124936
|
+
const rel = relative9(root, resolve22(cwd, path2));
|
|
124937
|
+
if (rel === ".." || rel.startsWith(`..${sep11}`) || isAbsolute15(rel)) {
|
|
124170
124938
|
return { error: `${path2} is outside the steering repo at ${root}.` };
|
|
124171
124939
|
}
|
|
124172
|
-
const scope = rel.split(
|
|
124940
|
+
const scope = rel.split(sep11).join("/");
|
|
124173
124941
|
const known = trees.some(
|
|
124174
124942
|
(tree) => tree !== null && [...tree.keys()].some((file) => within3(file, scope))
|
|
124175
124943
|
);
|
|
@@ -124477,7 +125245,7 @@ async function check(paths = [], opts = {}, writer = stdoutWriter, cwd = process
|
|
|
124477
125245
|
}
|
|
124478
125246
|
if (!report.passed) process.exitCode = 1;
|
|
124479
125247
|
}
|
|
124480
|
-
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;
|
|
124481
125249
|
var init_check3 = __esm({
|
|
124482
125250
|
"src/commands/check.ts"() {
|
|
124483
125251
|
init_paths2();
|
|
@@ -124490,7 +125258,7 @@ var init_check3 = __esm({
|
|
|
124490
125258
|
init_capture_writer();
|
|
124491
125259
|
init_config();
|
|
124492
125260
|
init_output();
|
|
124493
|
-
|
|
125261
|
+
ROOT_FILES3 = [
|
|
124494
125262
|
AGENTS_MD_PATH,
|
|
124495
125263
|
CLAUDE_MD_PATH,
|
|
124496
125264
|
README_PATH,
|
|
@@ -124503,7 +125271,7 @@ var init_check3 = __esm({
|
|
|
124503
125271
|
TOOLS_DIR,
|
|
124504
125272
|
POLICY_DIR
|
|
124505
125273
|
];
|
|
124506
|
-
PATHSPECS = [...
|
|
125274
|
+
PATHSPECS = [...ROOT_FILES3, ...TREE_DIRS];
|
|
124507
125275
|
DEFAULT_BASES = ["origin/HEAD", "origin/main"];
|
|
124508
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.";
|
|
124509
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.`;
|
|
@@ -128181,13 +128949,13 @@ var init_src9 = __esm({
|
|
|
128181
128949
|
|
|
128182
128950
|
// src/commands/codegraph-upload/files.ts
|
|
128183
128951
|
import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
|
|
128184
|
-
import { join as join55, relative as
|
|
128952
|
+
import { join as join55, relative as relative10, sep as sep12 } from "node:path";
|
|
128185
128953
|
function hasGlobChars(pattern) {
|
|
128186
128954
|
return /[*?[\]{}]/.test(pattern);
|
|
128187
128955
|
}
|
|
128188
128956
|
function normalize2(path2) {
|
|
128189
128957
|
const trimmed = path2.replace(/^\.\//, "");
|
|
128190
|
-
return
|
|
128958
|
+
return sep12 === "/" ? trimmed : trimmed.split(sep12).join("/");
|
|
128191
128959
|
}
|
|
128192
128960
|
async function walk(root, dir, out) {
|
|
128193
128961
|
const entries2 = await readdir5(dir, { withFileTypes: true });
|
|
@@ -128197,7 +128965,7 @@ async function walk(root, dir, out) {
|
|
|
128197
128965
|
if (entry2.isDirectory()) {
|
|
128198
128966
|
if (!SKIP_DIRS.has(entry2.name)) await walk(root, full, out);
|
|
128199
128967
|
} else if (entry2.isFile()) {
|
|
128200
|
-
out.push(normalize2(
|
|
128968
|
+
out.push(normalize2(relative10(root, full)));
|
|
128201
128969
|
}
|
|
128202
128970
|
}
|
|
128203
128971
|
}
|