loki-mode 11.17.52 → 11.17.53
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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/secure-scan.py +70 -2
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +6 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/BOARD.md +60 -0
- package/docs/v10/CLI-MODERN.md +1 -1
- package/docs/v10/FAILURE-CLASSES.md +7 -0
- package/docs/v10/PROGRESS.md +3 -0
- package/loki-ts/dist/loki.js +1114 -1114
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/ask-tools-server.js +6 -2
- package/packages/control-plane/dist/server.js +319 -67
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-DX_G4hP6.js → AdminPage-B5S4tImz.js} +1 -1
- package/web-app/dist/assets/{Avatar--ccDfOZe.js → Avatar-DVT9cXf-.js} +1 -1
- package/web-app/dist/assets/{Badge-Kxepzqt6.js → Badge-D-n8nS0d.js} +1 -1
- package/web-app/dist/assets/{Button-C6vHRfwo.js → Button-Dfgum0N6.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-D0NmW6Nv.js → CockpitPage-4xhSdrDM.js} +1 -1
- package/web-app/dist/assets/{ComparePage-eAmNL_uA.js → ComparePage-CPta-oKN.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DR3x2HWP.js → ErrorBoundary-CR8B9oGo.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-CbvDRoB_.js → EvidenceReceiptPanel-CUhElwm7.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-D18A2yuI.js → GitHubIssuesPanel-xKI3dI1W.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-35UiyfA1.js → GitHubPRsPanel-CJ16YJ9s.js} +1 -1
- package/web-app/dist/assets/{HomePage-CxdTthGm.js → HomePage-CzW6cDpa.js} +2 -2
- package/web-app/dist/assets/{LoginPage-CRMenLGu.js → LoginPage-CV6Tvhge.js} +1 -1
- package/web-app/dist/assets/{MagicPage-C4N3jB5F.js → MagicPage-Dqq2v6Uu.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-Ci92NkfO.js → MetricsPage-w5e0DFyq.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-TQ8wyqFz.js → NotFoundPage-CD15KPqA.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-CkLrPs83.js → ProjectPage-CLOEGdOa.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-CL_lJ-FU.js → ProjectsPage-wVGxTUqN.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-BBxpPd17.js → SettingsPage-tcZTOUCx.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-DJt78The.js → ShowcasePage-DhhFuJrY.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-Euu77KSq.js → SystemSettingsPage-DJTIpzRe.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-C3qbkeUm.js → TeamsPage-D_G-ch7e.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-DtDJQ2n1.js → TemplatesPage-Br8IjtsC.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-DBaMeu6Q.js → TerminalOutput-CDpeKr1C.js} +1 -1
- package/web-app/dist/assets/{activity-I-0LW_9B.js → activity-D3HHYtv7.js} +1 -1
- package/web-app/dist/assets/{bell-BsUHri1j.js → bell-Cw_RiUI1.js} +1 -1
- package/web-app/dist/assets/{bot-DJ2ZKDQJ.js → bot-CvSdbJCG.js} +1 -1
- package/web-app/dist/assets/{check-C49BGiaw.js → check-BrdmdEjE.js} +1 -1
- package/web-app/dist/assets/{chevron-left-9qCcpW8p.js → chevron-left-BNGgoAGR.js} +1 -1
- package/web-app/dist/assets/{circle-alert-C2IgWJIL.js → circle-alert-DbRWBNqr.js} +1 -1
- package/web-app/dist/assets/{clock-CPbQQVnU.js → clock-Be7jXWMi.js} +1 -1
- package/web-app/dist/assets/{cloud-ZgfYLOfd.js → cloud-CRvIp-jH.js} +1 -1
- package/web-app/dist/assets/{code-xml-DP_-TvJa.js → code-xml-BzHwWlm3.js} +1 -1
- package/web-app/dist/assets/{database-b8yZ9SPW.js → database-91AqM-FY.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-B9Fn3SCl.js → dollar-sign-BeNsKJBp.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-DLFYVjpQ.js → file-code-corner-BvNUefQ2.js} +1 -1
- package/web-app/dist/assets/{file-plus-CaXv2jSM.js → file-plus-DSdhJlCE.js} +1 -1
- package/web-app/dist/assets/{globe-DP7GFaoo.js → globe-alpFSVbm.js} +1 -1
- package/web-app/dist/assets/{hammer-RdlMd-CJ.js → hammer-DceL_3zd.js} +1 -1
- package/web-app/dist/assets/{index-LOkHALQt.js → index-BOfXC5KW.js} +3 -3
- package/web-app/dist/assets/{layers-DuP5BAIU.js → layers-C2dORLkY.js} +1 -1
- package/web-app/dist/assets/{loader-circle-D7vQvzyk.js → loader-circle-CcbHAofe.js} +1 -1
- package/web-app/dist/assets/{lock-CP9EmNs2.js → lock-yivPar99.js} +1 -1
- package/web-app/dist/assets/{package-CWjk8WQU.js → package-BGe4JXNK.js} +1 -1
- package/web-app/dist/assets/{plus-Ct7NSObM.js → plus-BpZ4ajEG.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-27AFS27n.js → refresh-cw-CqIBSjzI.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-B3kFoJu0.js → rotate-ccw-C7s45N_R.js} +1 -1
- package/web-app/dist/assets/{scroll-text-CD9FDcSN.js → scroll-text-Ce9Kmot6.js} +1 -1
- package/web-app/dist/assets/{server-CVevRsO-.js → server-DyUYnlLz.js} +1 -1
- package/web-app/dist/assets/{shield-alert-DmiHlWsA.js → shield-alert-DT2LYxTG.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-BxB1gdJg.js → thumbs-up-DJeSSzDq.js} +1 -1
- package/web-app/dist/assets/{trash-2-B2p2orXY.js → trash-2-BfICAUqu.js} +1 -1
- package/web-app/dist/assets/{trending-down-CzNEin9H.js → trending-down-DzjhrhCE.js} +1 -1
- package/web-app/dist/assets/{trending-up-BGQgb-1k.js → trending-up-qxrTgUwQ.js} +1 -1
- package/web-app/dist/assets/{upload-DZNyC4Hc.js → upload-BRZGP_py.js} +1 -1
- package/web-app/dist/assets/{usePolling-BLMiUm3S.js → usePolling-V4nOdEIl.js} +1 -1
- package/web-app/dist/assets/{user-5NQ3EYpr.js → user-CHfDU18s.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -156,7 +156,8 @@ var init_redact = __esm(() => {
|
|
|
156
156
|
[/github_pat_[A-Za-z0-9_]{20,}/g, "[REDACTED:GITHUB_TOKEN]"],
|
|
157
157
|
[/gh[pousr]_[A-Za-z0-9]{20,}/g, "[REDACTED:GITHUB_TOKEN]"],
|
|
158
158
|
[/xox[baprs]-[A-Za-z0-9-]{10,}/g, "[REDACTED:SLACK_TOKEN]"],
|
|
159
|
-
[/AKIA[0-9A-Z]{16}/g, "[REDACTED:AWS_KEY]"],
|
|
159
|
+
[/(?:AKIA|ASIA)[0-9A-Z]{16}/g, "[REDACTED:AWS_KEY]"],
|
|
160
|
+
[/(AccountKey=)[A-Za-z0-9+/]{40,}={0,2}/g, "$1[REDACTED:AZURE_KEY]"],
|
|
160
161
|
[/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, "[REDACTED:JWT]"],
|
|
161
162
|
[/\bSG\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/g, "[REDACTED:SENDGRID_KEY]"],
|
|
162
163
|
[/\bSK[0-9a-f]{32}\b/g, "[REDACTED:TWILIO_KEY]"],
|
|
@@ -270,7 +271,7 @@ function tokenFreeEnv(env = process.env) {
|
|
|
270
271
|
return out;
|
|
271
272
|
}
|
|
272
273
|
function driverKeys(repoDir) {
|
|
273
|
-
const r = spawnSync("git", [...SAFE_GIT_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", DRIVER_KEY_RE], { cwd: repoDir, env: safeGitEnv(), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
274
|
+
const r = spawnSync("git", [...SAFE_GIT_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", DRIVER_KEY_RE], { cwd: repoDir, env: safeGitEnv(), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: configEnumTimeoutMs(), killSignal: "SIGKILL" });
|
|
274
275
|
if (r.error)
|
|
275
276
|
throw r.error;
|
|
276
277
|
if (r.status === 1)
|
|
@@ -287,7 +288,7 @@ function driverKeys(repoDir) {
|
|
|
287
288
|
return [...new Set(keys)];
|
|
288
289
|
}
|
|
289
290
|
function netCommandOverrides(repoDir, env) {
|
|
290
|
-
const r = spawnSync("git", [...CREDENTIAL_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", NET_CMD_KEY_RE], { cwd: repoDir, env: safeGitEnv(env, true), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
291
|
+
const r = spawnSync("git", [...CREDENTIAL_CONFIG, "config", "--includes", "--show-scope", "-z", "--get-regexp", NET_CMD_KEY_RE], { cwd: repoDir, env: safeGitEnv(env, true), encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: configEnumTimeoutMs(), killSignal: "SIGKILL" });
|
|
291
292
|
if (r.error)
|
|
292
293
|
throw r.error;
|
|
293
294
|
if (r.status === 1)
|
|
@@ -422,6 +423,9 @@ var SAFE_GIT_CONFIG, CREDENTIAL_CONFIG, DRIVER_CONFIG, ATTRS_OFF = "core.attribu
|
|
|
422
423
|
delete env.GIT_ATTR_SOURCE;
|
|
423
424
|
delete env.GIT_EXTERNAL_DIFF;
|
|
424
425
|
return env;
|
|
426
|
+
}, configEnumTimeoutMs = () => {
|
|
427
|
+
const n2 = Number(process.env.LOKI_SAFE_GIT_CONFIG_TIMEOUT_MS);
|
|
428
|
+
return Number.isFinite(n2) && n2 > 0 ? n2 : 30000;
|
|
425
429
|
}, NET_CMD_KEY_RE = "^(core\\.(sshcommand|gitproxy|askpass)|remote\\..*\\.(uploadpack|receivepack|proxy)|credential(\\..*)?\\.helper|https?\\.(.*\\.)?(proxy|sslverify|sslcainfo|sslcapath|curloptresolve))$", BOOL_SAFE_DEFAULT, LOCAL_SCOPES, PUSH_CMD, PACK_OPTS, TRANSPORT_OR_LOCAL;
|
|
426
430
|
var init_safe_git = __esm(() => {
|
|
427
431
|
init_credential_env();
|
|
@@ -11001,6 +11005,249 @@ var init_run_control = __esm(() => {
|
|
|
11001
11005
|
PARENT_PID = process.ppid;
|
|
11002
11006
|
});
|
|
11003
11007
|
|
|
11008
|
+
// ../../loki-ts/src/cli/registry.ts
|
|
11009
|
+
function cmd(name, cls, where, desc2, reason, extra = {}) {
|
|
11010
|
+
return { name, cls, where, desc: desc2, reason, ...extra };
|
|
11011
|
+
}
|
|
11012
|
+
var bool = (name, desc2, excludes) => ({ name, type: "bool", desc: desc2, ...excludes ? { excludes } : {} }), json, str3 = (name, placeholder, desc2) => ({ name, type: "string", placeholder, desc: desc2 }), dyn = (name, dynamic, desc2) => ({ name, type: "dynamic", dynamic, desc: desc2 }), sub = (name, desc2, extra = {}) => ({ name, desc: desc2, ...extra }), port, dbFlag, runId, legacy = (name, desc2, reason, aliases) => cmd(name, "DROP-LEGACY", "bash", desc2, reason, aliases ? { aliases } : {}), startFlags, REGISTRY;
|
|
11013
|
+
var init_registry2 = __esm(() => {
|
|
11014
|
+
json = bool("--json", "Machine-readable JSON output");
|
|
11015
|
+
port = { name: "--port", type: "int", placeholder: "<port>", desc: "Port" };
|
|
11016
|
+
dbFlag = { name: "--db", type: "path", desc: "Database path" };
|
|
11017
|
+
runId = { name: "id", type: "dynamic", dynamic: "runs" };
|
|
11018
|
+
startFlags = [
|
|
11019
|
+
dyn("--provider", "providers", "AI provider"),
|
|
11020
|
+
bool("--parallel", "Parallel mode with git worktrees"),
|
|
11021
|
+
str3("--workspace", "<name>", "Run a loki.yaml workspace (multi-repo) for the brief"),
|
|
11022
|
+
bool("--deploy", "After a VERIFIED run, deploy through the gated loki deploy --execute"),
|
|
11023
|
+
str3("--health-url", "<url>", "With --deploy: probe this URL after the deploy"),
|
|
11024
|
+
bool("--auto-rollback", "With --deploy: roll back automatically when the health probe fails"),
|
|
11025
|
+
bool("--bg", "Run in background mode"),
|
|
11026
|
+
bool("--simple", "Force simple complexity tier", ["--complex"]),
|
|
11027
|
+
bool("--complex", "Force complex complexity tier", ["--simple"]),
|
|
11028
|
+
bool("--github", "Enable GitHub issue import"),
|
|
11029
|
+
bool("--no-dashboard", "Disable the web dashboard"),
|
|
11030
|
+
bool("--sandbox", "Run in a Docker sandbox"),
|
|
11031
|
+
{ name: "--isolation", type: "enum", values: ["none", "worktree", "docker"], desc: "Per-run isolation level" },
|
|
11032
|
+
bool("--skip-memory", "Skip loading memory context at startup"),
|
|
11033
|
+
bool("--fresh-prd", "Regenerate the PRD from the codebase"),
|
|
11034
|
+
{ name: "--compliance", type: "enum", values: ["default", "healthcare", "fintech", "government"], desc: "Compliance preset" },
|
|
11035
|
+
str3("--budget", "<usd>", "Cost budget limit in USD"),
|
|
11036
|
+
{ name: "--cost", type: "enum", values: ["lean", "off"], desc: "Cost profile (also LOKI_COST_PROFILE)" },
|
|
11037
|
+
{ name: "--bmad-project", type: "path", desc: "BMAD Method project artifacts as input" },
|
|
11038
|
+
{ name: "--openspec", type: "path", desc: "OpenSpec change directory as input" },
|
|
11039
|
+
{ name: "--config", type: "path", desc: "Load settings from a config file" }
|
|
11040
|
+
];
|
|
11041
|
+
REGISTRY = [
|
|
11042
|
+
cmd("version", "KEEP-MODERN", "bun", "Show version", "Bun-native, no legacy dependency", { aliases: ["--version", "-v"] }),
|
|
11043
|
+
cmd("status", "UPDATE", "both", "Show current run status", "Reads both engines; fold legacy fields into the v10 view", { flags: [json, bool("--badge", "Print the verified deploy badge"), bool("--probe", "Re-probe the last deploy health URL; exit 1 on regression")], example: "loki status --json" }),
|
|
11044
|
+
cmd("stats", "DELETE", "bun", "Session statistics (alias of report session)", "Deprecated alias; use report session", { flags: [json, bool("--efficiency", "Token and cost efficiency")] }),
|
|
11045
|
+
cmd("doctor", "KEEP-MODERN", "both", "System prerequisites health check; --json, --fix, --requirements, --repo (repo profile with a 0-100 readiness score and fixes)", "Core onboarding gate", { flags: [json, bool("--fix", "Apply safe fixes; with --repo, build or refresh the repo profile"), bool("--yes", "With --fix: run the claude install and login without asking"), bool("--airgap", "Air-gapped check"), bool("--repo", "Print the repo profile and readiness score"), bool("--requirements", "Requirements per execution path")], example: "loki doctor --json" }),
|
|
11046
|
+
cmd("provider", "KEEP-MODERN", "both", "Show, list or set the AI provider", "Provider-agnostic core", {
|
|
11047
|
+
subcommands: [
|
|
11048
|
+
sub("show", "Show current provider", { positionals: [{ name: "name", type: "dynamic", dynamic: "providers" }] }),
|
|
11049
|
+
sub("list", "List providers and install status"),
|
|
11050
|
+
sub("set", "Switch the active provider", { positionals: [{ name: "name", type: "dynamic", dynamic: "providers" }] }),
|
|
11051
|
+
sub("info", "Provider details; --json prints the capability contract", { positionals: [{ name: "name", type: "dynamic", dynamic: "providers" }] }),
|
|
11052
|
+
sub("matrix", "Capability matrix per provider and engine")
|
|
11053
|
+
]
|
|
11054
|
+
}),
|
|
11055
|
+
cmd("memory", "UPDATE", "both", "Cross-project learnings", "Memory still carries legacy store paths", {
|
|
11056
|
+
subcommands: [
|
|
11057
|
+
sub("list", "All learnings", { flags: [bool("--json", "Print the learnings summary as JSON")] }),
|
|
11058
|
+
sub("index", "Show or rebuild the memory index", { positionals: [{ name: "action", type: "enum", values: ["rebuild"] }] }),
|
|
11059
|
+
sub("learn", "Learn lessons from a merged PR's review comments", { positionals: [{ name: "pr", type: "string" }] }),
|
|
11060
|
+
sub("lessons", "List PR review lessons with uses and outcomes", { flags: [bool("--json", "Print the lessons as JSON")] }),
|
|
11061
|
+
sub("brief", "Print the lessons and learnings block an engine10 run injects", { flags: [str3("--task", "text", "Task text used to pick relevant lessons")] }),
|
|
11062
|
+
sub("show", "Show one learning"),
|
|
11063
|
+
sub("search", "Search learnings"),
|
|
11064
|
+
sub("stats", "Memory statistics"),
|
|
11065
|
+
sub("consolidate", "Episodic-to-semantic pipeline"),
|
|
11066
|
+
sub("compound", "Compound learnings")
|
|
11067
|
+
]
|
|
11068
|
+
}),
|
|
11069
|
+
cmd("rollback", "KEEP-MODERN", "both", "Restore .loki/ state from a checkpoint", "Checkpoint restore is engine-neutral", {
|
|
11070
|
+
subcommands: [
|
|
11071
|
+
sub("list", "List checkpoints", { flags: [bool("--json", "Print the checkpoints as a JSON array")] }),
|
|
11072
|
+
sub("show", "Show a checkpoint", { positionals: [runId] }),
|
|
11073
|
+
sub("to", "Restore a checkpoint", { positionals: [runId] }),
|
|
11074
|
+
sub("latest", "Restore the latest checkpoint"),
|
|
11075
|
+
sub("deploy", "Print the provider rollback command for the last deploy (read-only)")
|
|
11076
|
+
]
|
|
11077
|
+
}),
|
|
11078
|
+
cmd("backup", "KEEP-MODERN", "bash", "Back up dashboard state (audit log, checkpoint) with a sha256 manifest", "Enterprise retention and backup (D99 item 7)", { flags: [str3("--dir", "<path>", "State directory (default ~/.loki/dashboard)"), str3("--out", "<archive>", "Archive path (default ./loki-backup-<timestamp>.tar.gz)")] }),
|
|
11079
|
+
cmd("restore", "KEEP-MODERN", "bash", "Restore dashboard state from a verified backup archive", "Enterprise retention and backup (D99 item 7)", { flags: [str3("--dir", "<path>", "State directory (default ~/.loki/dashboard)"), bool("--force", "Replace a non-empty state directory (old one is kept aside)"), str3("--sha256", "<hex>", "Expected archive digest when no .sha256 sidecar exists")], positionals: [{ name: "archive", type: "path" }] }),
|
|
11080
|
+
cmd("proof", "KEEP-MODERN", "both", "Inspect and share proof-of-run receipts", "The Evidence Receipt moat", {
|
|
11081
|
+
aliases: ["receipt"],
|
|
11082
|
+
subcommands: [
|
|
11083
|
+
sub("list", "List receipts"),
|
|
11084
|
+
sub("show", "Show a receipt", { positionals: [runId] }),
|
|
11085
|
+
sub("open", "Open a receipt", { positionals: [runId] }),
|
|
11086
|
+
sub("share", "Share a receipt", { positionals: [runId] }),
|
|
11087
|
+
sub("badge", "Print the Verified by Loki badge", { positionals: [runId] }),
|
|
11088
|
+
sub("md", "Print badge markdown for a README", { positionals: [runId] }),
|
|
11089
|
+
sub("bundle", "Write a self-verifying receipt bundle", { positionals: [runId] })
|
|
11090
|
+
]
|
|
11091
|
+
}),
|
|
11092
|
+
cmd("wiki", "KEEP-MODERN", "both", "Cited codebase wiki and Q&A", "Bun-native knowledge feature", {
|
|
11093
|
+
subcommands: [
|
|
11094
|
+
sub("generate", "Generate the wiki"),
|
|
11095
|
+
sub("show", "Show a section", { positionals: [{ name: "section", type: "string" }] }),
|
|
11096
|
+
sub("ask", "Ask a question", { positionals: [{ name: "question", type: "string" }] })
|
|
11097
|
+
]
|
|
11098
|
+
}),
|
|
11099
|
+
cmd("control", "KEEP-MODERN", "both", "Control Plane (serve, backfill, prune, stop, status)", "D56 control plane, on by default", {
|
|
11100
|
+
subcommands: [
|
|
11101
|
+
sub("serve", "Run the control plane and UI", { flags: [port, dbFlag] }),
|
|
11102
|
+
sub("backfill", "Ship DIR/.loki/runs to the control plane", { positionals: [{ name: "dir", type: "path" }] }),
|
|
11103
|
+
sub("prune", "Delete matching runs", { flags: [str3("--repo", "<owner/name>", "Repository to prune"), str3("--before", "<iso-date>", "Prune runs before this date"), bool("--dry-run", "Report only"), dbFlag] }),
|
|
11104
|
+
sub("stop", "Stop the running control plane"),
|
|
11105
|
+
sub("status", "Show control plane reachability", { flags: [bool("--json", "Print one JSON object")] })
|
|
11106
|
+
]
|
|
11107
|
+
}),
|
|
11108
|
+
cmd("intent", "KEEP-MODERN", "bun", "Show a past run's intent card", "Read-only intent view", { subcommands: [sub("show", "Print the intent card and answer", { positionals: [runId] })] }),
|
|
11109
|
+
cmd("kpis", "KEEP-MODERN", "bun", "KPI snapshot (alias of report kpis)", "Bun-native KPI report", { flags: [json, str3("--since", "<Nd|YYYY-MM-DD>", "Limit iteration totals to a window")] }),
|
|
11110
|
+
cmd("report", "UPDATE", "both", "Reporting: kpis, session, metrics, cost, export, share, dogfood", "Mixed route; only kpis is Bun", {
|
|
11111
|
+
subcommands: [
|
|
11112
|
+
sub("kpis", "Canonical KPI snapshot", { flags: [json, str3("--since", "<Nd|YYYY-MM-DD>", "Limit iteration totals to a window")] }),
|
|
11113
|
+
sub("session", "Session report", { flags: [bool("--efficiency", "Token and cost stats")] }),
|
|
11114
|
+
sub("metrics", "Metrics report"),
|
|
11115
|
+
sub("cost", "Cost report"),
|
|
11116
|
+
sub("export", "Export session", { positionals: [{ name: "format", type: "enum", values: ["json", "markdown", "csv", "timeline", "vibe-kanban"] }] }),
|
|
11117
|
+
sub("share", "Share a report"),
|
|
11118
|
+
sub("dogfood", "Dogfood report")
|
|
11119
|
+
]
|
|
11120
|
+
}),
|
|
11121
|
+
cmd("trust", "KEEP-MODERN", "both", "Trust trajectory from proof history", "Trust moat surface", { flags: [bool("--json", "Print the trust trajectory as JSON")], subcommands: [sub("detail", "Trust metrics detail")] }),
|
|
11122
|
+
cmd("crash", "KEEP-MODERN", "both", "Inspect or submit scrubbed crash reports", "Local-only crash plumbing", {
|
|
11123
|
+
subcommands: [sub("list", "List stored crash reports"), sub("show", "Show one scrubbed crash report"), sub("submit", "Submit a scrubbed crash report"), sub("help", "Show crash usage")]
|
|
11124
|
+
}),
|
|
11125
|
+
cmd("contract", "KEEP-MODERN", "bun", "Print the spec delivery contract", "v10 delivery contract", { positionals: [{ name: "spec", type: "path" }] }),
|
|
11126
|
+
cmd("start", "UPDATE", "both", "Run the autonomous build (a `jira:KEY` or `linear:KEY` ref also writes the outcome back to that ticket, see docs/trackers.md)", "Forks between v10 and the SDK loop; flags still legacy-shaped", { flags: startFlags, positionals: [{ name: "spec", type: "path" }], example: "loki start ./prd.md --provider claude" }),
|
|
11127
|
+
cmd("slack", "KEEP-MODERN", "bun", "Slack inbound handler", "Bun-native integration", { subcommands: [sub("serve", "Serve the Slack handler", { flags: [port, str3("--host", "<host>", "Bind host")] })] }),
|
|
11128
|
+
cmd("queue", "KEEP-MODERN", "bun", "Overnight issue queue with a morning digest", "Governor-aware batch of issue-mode runs", { subcommands: [sub("add", "Queue issue refs", { positionals: [{ name: "issue", type: "string" }] }), sub("list", "Show the queue", { flags: [bool("--json", "Print the queued refs as a JSON array")] }), sub("remove", "Take issue refs out of the queue", { positionals: [{ name: "issue", type: "string" }] }), sub("clear", "Empty the queue"), sub("run", "Process the queue", { flags: [bool("--no-pr", "Do not open pull requests"), str3("--max-total-cost", "<usd>", "Stop before the next item once cumulative spend reaches this cap")] })] }),
|
|
11129
|
+
cmd("issues", "KEEP-MODERN", "bun", "Run every open issue in a repo and open PRs", "Mass issue pickup on the T7 queue", {
|
|
11130
|
+
subcommands: [sub("run", "Triage and run open issues; split too-large ones into stacked PRs", {
|
|
11131
|
+
example: "loki issues run owner/repo --label bug --limit 10",
|
|
11132
|
+
positionals: [{ name: "repo", type: "string" }],
|
|
11133
|
+
flags: [str3("--label", "<label>", "Only issues with this label"), { name: "--limit", type: "int", placeholder: "<n>", desc: "At most this many issues" }, { name: "--parallel", type: "int", placeholder: "<k>", desc: "Runs at once, at most 4 (separate worktrees)" }, bool("--draft", "Open every PR as a draft"), bool("--dry-run", "List, dedupe and show the plan; no model calls"), bool("--json", "With --dry-run: print the plan as JSON (number, decision, reason, covered_by_pr)"), bool("--yes", "Skip the cost confirmation (CI)"), bool("--comment", "Comment the triage reason on skipped issues and the slice plan on split ones"), bool("--no-split", "Skip too-large issues instead of splitting them into stacked PRs")]
|
|
11134
|
+
})]
|
|
11135
|
+
}),
|
|
11136
|
+
cmd("undo", "KEEP-MODERN", "bun", "Plan or apply an undo of a run", "UNDO-1/2: --plan is read-only, apply behind LOKI_UNDO=1", { flags: [bool("--plan", "Read-only plan"), bool("--list", "List runs that can be undone"), bool("--dry-run", "Report what would be undone; change nothing"), bool("--json", "JSON plan (with --plan)"), bool("--allow-unsigned", "Accept an unsigned receipt (with --plan)"), bool("--yes", "Skip the confirm prompt"), bool("--close-pr", "Also close the PR")], positionals: [{ name: "run", type: "dynamic", dynamic: "runs" }] }),
|
|
11137
|
+
cmd("verify-pr", "KEEP-MODERN", "bun", "Verify a PR against its linked issue in a sandbox", "VPR-2: fail-to-pass check, LOKI_VERIFY_PR=1", { flags: [{ name: "--out", type: "path", desc: "Result directory" }, bool("--json", "Print the verdict object on stdout")], positionals: [{ name: "pr", type: "string" }], subcommands: [sub("respond", "Fix open review comments on the PR branch, one commit each, reply with the sha", { positionals: [{ name: "pr", type: "string" }] })] }),
|
|
11138
|
+
cmd("answer", "KEEP-MODERN", "bun", "Start a follow-up run from a BLOCKED run with your answer", "v10 blocked-run flow", { flags: [bool("--text", "Answer text inline")], positionals: [{ name: "run", type: "dynamic", dynamic: "runs" }] }),
|
|
11139
|
+
cmd("engine10", "KEEP-MODERN", "bun", "v10 engine router", "The v10 engine", {
|
|
11140
|
+
subcommands: [sub("run", "Run the v10 engine"), sub("status", "v10 status"), sub("verify", "v10 verify"), sub("keys", "v10 keys"), sub("dashboard", "v10 dashboard"), sub("modernize", "v10 modernize")]
|
|
11141
|
+
}),
|
|
11142
|
+
cmd("internal", "KEEP-MODERN", "bun", "Internal plumbing for the bash CLI", "Hidden plumbing", { hidden: true }),
|
|
11143
|
+
cmd("completion", "KEEP-MODERN", "bun", "Generate shell completions", "Hidden plumbing; completions install themselves", { hidden: true, positionals: [{ name: "shell", type: "enum", values: ["bash", "zsh", "fish"] }] }),
|
|
11144
|
+
cmd("__complete", "KEEP-MODERN", "bun", "Dynamic completion values", "Hidden plumbing for generated completions", { hidden: true, positionals: [{ name: "kind", type: "enum", values: ["providers", "models", "branches", "runs", "issues", "workspaces"] }] }),
|
|
11145
|
+
cmd("help", "KEEP-MODERN", "bash", "Show help", "Core", { aliases: ["--help", "-h"], positionals: [{ name: "command", type: "string" }] }),
|
|
11146
|
+
cmd("chat", "KEEP-MODERN", "bash", "Interactive chat with the active provider", "Provider-neutral conversational verb", { positionals: [{ name: "message", type: "string" }] }),
|
|
11147
|
+
cmd("edit", "KEEP-MODERN", "bash", "Make one small scoped edit", "Provider-neutral single-edit verb", { positionals: [{ name: "task", type: "string" }] }),
|
|
11148
|
+
cmd("diff", "KEEP-MODERN", "bash", "Show what the last run changed", "Passes extra args to git diff"),
|
|
11149
|
+
cmd("models", "KEEP-MODERN", "bash", "Show per-provider model routes", "Provider-neutral model tiers"),
|
|
11150
|
+
cmd("setup", "KEEP-MODERN", "bash", "Guided first-run setup wizard", "Onboarding gate"),
|
|
11151
|
+
cmd("quick", "UPDATE", "bash", "One small task", "Routes to the v10 lean path by default", { positionals: [{ name: "task", type: "string" }] }),
|
|
11152
|
+
cmd("quickstart", "KEEP-MODERN", "bash", "Guided first build", "Onboarding path", { positionals: [{ name: "idea", type: "string" }] }),
|
|
11153
|
+
cmd("init", "UPDATE", "bash", "Scaffold from a template", "Templates predate v10", { flags: [str3("-t", "<template>", "Template name")] }),
|
|
11154
|
+
cmd("template", "KEEP-MODERN", "bash", "Manage PRD templates", "Engine-neutral"),
|
|
11155
|
+
cmd("verify", "UPDATE", "bash", "Deterministic PR verification", "Legacy proof vs v10 verify split", { flags: [bool("--fast", "PR-scoped fast verify"), bool("--pr", "PR mode"), json, dyn("--base", "branches", "Base branch")], positionals: [{ name: "base", type: "dynamic", dynamic: "branches" }] }),
|
|
11156
|
+
cmd("keys", "KEEP-MODERN", "bash", "Receipt-signing keys", "Trust moat", { subcommands: [sub("export", "Print the public signing key (JWK)")] }),
|
|
11157
|
+
cmd("review", "UPDATE", "bash", "Standalone code review with quality gates", "Gates are legacy-shaped"),
|
|
11158
|
+
cmd("dashboard", "UPDATE", "bash", "Operations UI server", "Overlaps Control Plane", { subcommands: [sub("start", "Start"), sub("stop", "Stop"), sub("status", "Status"), sub("url", "Print URL"), sub("open", "Open in browser")] }),
|
|
11159
|
+
cmd("config", "UPDATE", "bash", "Manage configuration", "Mixed legacy keys", { subcommands: [sub("show", "Show config"), sub("list", "List config (alias of show)"), sub("init", "Create config"), sub("edit", "Edit config"), sub("path", "Print config path"), sub("set", "Set a value"), sub("get", "Get a value")] }),
|
|
11160
|
+
cmd("mcp", "KEEP-MODERN", "bash", "Launch the MCP server (stdio)", "Engine-neutral", { subcommands: [sub("install", "Register loki-mode in an MCP client config", { flags: [str3("--client", "<name>", "claude, cursor, vscode or windsurf"), bool("--project", "Project-level config"), bool("--global", "User-level config"), bool("--print", "Print, write nothing")] })] }),
|
|
11161
|
+
cmd("acp", "KEEP-MODERN", "bash", "Run Loki as an ACP agent", "Engine-neutral"),
|
|
11162
|
+
cmd("stop", "KEEP-MODERN", "bash", "Stop execution immediately", "Session control"),
|
|
11163
|
+
cmd("pause", "KEEP-MODERN", "both", "Pause after the current session", "Session control; Bun writes the Loki 10 run request, bash keeps the legacy PAUSE file"),
|
|
11164
|
+
cmd("resume", "KEEP-MODERN", "both", "Resume a paused or interrupted run", "Session control; Bun clears a Loki 10 pause, bash keeps the legacy resume"),
|
|
11165
|
+
cmd("cancel", "KEEP-MODERN", "both", "Cancel the active Loki 10 run at the next stage boundary", "Session control; Loki 10 only"),
|
|
11166
|
+
cmd("why", "KEEP-MODERN", "bash", "Explain how the last run ended", "Outcome explainer"),
|
|
11167
|
+
cmd("next", "KEEP-MODERN", "bash", "Run the right next step", "Guided flow"),
|
|
11168
|
+
cmd("logs", "KEEP-MODERN", "bash", "Tail recent log output", "Engine-neutral"),
|
|
11169
|
+
cmd("ship", "KEEP-MODERN", "bash", "Ship the verified result", "Delivery"),
|
|
11170
|
+
cmd("deploy", "KEEP-MODERN", "bash", "Deploy the built product", "Delivery"),
|
|
11171
|
+
cmd("import", "KEEP-MODERN", "bash", "Import issues or specs", "Spec intake"),
|
|
11172
|
+
cmd("github", "KEEP-MODERN", "bash", "GitHub integration", "Integration"),
|
|
11173
|
+
cmd("issue", "KEEP-MODERN", "bash", "Work an issue", "Issue-mode", { positionals: [{ name: "ref", type: "dynamic", dynamic: "issues" }] }),
|
|
11174
|
+
cmd("ci", "KEEP-MODERN", "bash", "CI helpers", "Engine-neutral"),
|
|
11175
|
+
cmd("modernize", "KEEP-MODERN", "both", "Code modernization", "Routed to engine10 modernize"),
|
|
11176
|
+
cmd("share", "KEEP-MODERN", "bash", "Share a run", "Engine-neutral"),
|
|
11177
|
+
cmd("assets", "KEEP-MODERN", "bash", "Export team assets", "Engine-neutral", { subcommands: [sub("export", "Export shareable assets", { positionals: [{ name: "file", type: "path" }] })] }),
|
|
11178
|
+
cmd("export", "UPDATE", "bash", "Export session data", "Duplicates report export", { flags: [bool("--sarif", "Write findings.sarif for a run (SARIF 2.1.0)")] }),
|
|
11179
|
+
cmd("notify", "KEEP-MODERN", "bash", "Notifications", "Engine-neutral"),
|
|
11180
|
+
cmd("tour", "KEEP-MODERN", "bash", "See a sample result", "Onboarding"),
|
|
11181
|
+
cmd("welcome", "KEEP-MODERN", "bash", "First-run opener", "Onboarding"),
|
|
11182
|
+
cmd("onboard", "UPDATE", "bash", "Onboard to a codebase", "Overlaps wiki"),
|
|
11183
|
+
cmd("setup-skill", "KEEP-MODERN", "bash", "Install the skill symlinks", "Setup"),
|
|
11184
|
+
cmd("self-update", "KEEP-MODERN", "bash", "Update Loki", "Maintenance", { aliases: ["self_update", "update"] }),
|
|
11185
|
+
cmd("remote", "KEEP-MODERN", "bash", "Remote session", "Engine-neutral", { aliases: ["rc"] }),
|
|
11186
|
+
cmd("cockpit", "KEEP-MODERN", "bash", "Live multi-repo cockpit", "Engine-neutral"),
|
|
11187
|
+
cmd("code", "UPDATE", "bash", "Code intelligence", "Overlaps wiki"),
|
|
11188
|
+
cmd("context", "KEEP-MODERN", "bash", "Cross-project context", "Engine-neutral", { aliases: ["ctx"] }),
|
|
11189
|
+
cmd("secrets", "KEEP-MODERN", "bash", "Secrets handling", "Security"),
|
|
11190
|
+
cmd("api", "KEEP-MODERN", "bash", "Dashboard HTTP API", "Engine-neutral"),
|
|
11191
|
+
cmd("sandbox", "KEEP-MODERN", "bash", "Docker sandbox", "Isolation"),
|
|
11192
|
+
cmd("docker", "KEEP-MODERN", "bash", "Docker helpers", "Isolation"),
|
|
11193
|
+
cmd("web", "UPDATE", "bash", "Web UI", "Overlaps Control Plane UI"),
|
|
11194
|
+
cmd("preview", "KEEP-MODERN", "bash", "Preview the built app", "Delivery"),
|
|
11195
|
+
cmd("telemetry", "KEEP-MODERN", "bash", "Telemetry controls", "Privacy surface", { aliases: ["otel"] }),
|
|
11196
|
+
cmd("syslog", "UPDATE", "bash", "System log forwarding", "Legacy log paths"),
|
|
11197
|
+
cmd("explain", "KEEP-MODERN", "bash", "Explain code", "Knowledge"),
|
|
11198
|
+
cmd("docs", "KEEP-MODERN", "bash", "Open docs", "Core"),
|
|
11199
|
+
cmd("test", "UPDATE", "bash", "Run project tests", "Legacy runner"),
|
|
11200
|
+
cmd("bench", "KEEP-MODERN", "bash", "Benchmarks", "Engine-neutral"),
|
|
11201
|
+
cmd("voice", "UPDATE", "bash", "Voice input", "Experimental"),
|
|
11202
|
+
cmd("own", "UPDATE", "bash", "Hand off ownership", "Legacy handoff", { aliases: ["handoff"] }),
|
|
11203
|
+
cmd("secure", "KEEP-MODERN", "bash", "Security scan", "Security"),
|
|
11204
|
+
cmd("compliance", "KEEP-MODERN", "bash", "Compliance reports", "Enterprise"),
|
|
11205
|
+
cmd("enterprise", "KEEP-MODERN", "bash", "Enterprise features", "Enterprise"),
|
|
11206
|
+
cmd("projects", "KEEP-MODERN", "bash", "Project registry", "Engine-neutral"),
|
|
11207
|
+
cmd("audit", "KEEP-MODERN", "bash", "Audit log", "Enterprise"),
|
|
11208
|
+
cmd("cost", "UPDATE", "bash", "Cost report", "Duplicates report cost"),
|
|
11209
|
+
cmd("metrics", "UPDATE", "bash", "Metrics", "Duplicates report metrics"),
|
|
11210
|
+
cmd("sentrux", "UPDATE", "bash", "Architecture sensor", "Legacy gate input"),
|
|
11211
|
+
cmd("magic", "UPDATE", "bash", "Magic modules", "Legacy UI generator"),
|
|
11212
|
+
legacy("estimate", "Cost estimate for a PRD", "Estimates the legacy PRD flow"),
|
|
11213
|
+
legacy("plan", "Dry-run PRD analysis", "Legacy PRD flow"),
|
|
11214
|
+
legacy("grill", "Spec interrogation", "Legacy PRD flow"),
|
|
11215
|
+
legacy("spec", "Living-spec drift", "Legacy PRD flow"),
|
|
11216
|
+
legacy("intent", "Intent capture", "Legacy PRD flow"),
|
|
11217
|
+
legacy("backlog", "Run matching issues in parallel", "Drives legacy RARV per issue"),
|
|
11218
|
+
legacy("workspace", "Multi-repo workspace runs", "Drives legacy RARV"),
|
|
11219
|
+
legacy("council", "Completion council", "Legacy RARV gate"),
|
|
11220
|
+
legacy("compound", "Compound-learning pipeline", "Legacy memory pipeline"),
|
|
11221
|
+
legacy("cluster", "Cluster mode", "Legacy RARV"),
|
|
11222
|
+
legacy("optimize", "Optimize loop", "Legacy RARV"),
|
|
11223
|
+
legacy("ultracode", "Claude Dynamic Workflow run", "Legacy Claude-only"),
|
|
11224
|
+
legacy("monitor", "Monitor a legacy run", "Legacy engine state"),
|
|
11225
|
+
legacy("watch", "Rerun on PRD change", "PRD flow"),
|
|
11226
|
+
legacy("watchdog", "Legacy run watchdog", "Legacy engine"),
|
|
11227
|
+
legacy("cleanup", "Kill orphaned processes", "Legacy run.sh orphans"),
|
|
11228
|
+
legacy("state", "Legacy state store", "Legacy engine"),
|
|
11229
|
+
legacy("agent", "Legacy agent types", "Legacy engine"),
|
|
11230
|
+
legacy("agents", "User-configurable child agents (.loki/agents)", "Legacy engine"),
|
|
11231
|
+
legacy("trigger", "Event triggers", "Legacy engine"),
|
|
11232
|
+
legacy("failover", "Provider failover", "Legacy engine"),
|
|
11233
|
+
legacy("reset", "Reset legacy state", "Legacy engine"),
|
|
11234
|
+
legacy("merge", "Gated PR merge queue (pr, watch, run); also merges parallel worktrees", "Bash PR merge gate"),
|
|
11235
|
+
legacy("heal", "Legacy healing", "Legacy engine"),
|
|
11236
|
+
legacy("migrate", "Legacy migration", "Superseded by modernize"),
|
|
11237
|
+
legacy("dogfood", "Dogfood run", "Legacy engine"),
|
|
11238
|
+
cmd("steer", "KEEP-MODERN", "bash", "Nudge a running build", "Session control"),
|
|
11239
|
+
legacy("outcomes", "Outcome analytics", "Legacy outcome store"),
|
|
11240
|
+
legacy("worktree", "Worktree management", "Legacy parallel mode", ["wt"]),
|
|
11241
|
+
legacy("checkpoint", "Legacy checkpoints", "Legacy engine", ["cp"]),
|
|
11242
|
+
legacy("analyze", "Codebase analysis", "Legacy analyze flow"),
|
|
11243
|
+
legacy("demo", "Build the sample todo app", "Legacy engine demo"),
|
|
11244
|
+
cmd("run", "DELETE", "bash", "Deprecated alias of start", "Alias; use start"),
|
|
11245
|
+
cmd("trust-metrics", "DELETE", "bash", "Deprecated alias of trust detail", "Alias; use trust detail"),
|
|
11246
|
+
cmd("serve", "DELETE", "bash", "Deprecated alias of api start", "Alias; use api start"),
|
|
11247
|
+
cmd("open", "DELETE", "bash", "Deprecated alias of dashboard open", "Alias; use dashboard open")
|
|
11248
|
+
];
|
|
11249
|
+
});
|
|
11250
|
+
|
|
11004
11251
|
// ../../loki-ts/src/features/receipt_dsse.ts
|
|
11005
11252
|
import { createPublicKey as createPublicKey3, sign as sign2, verify as verify3 } from "crypto";
|
|
11006
11253
|
import { readFileSync as readFileSync33 } from "fs";
|
|
@@ -11054,7 +11301,7 @@ function outcomeOf(j) {
|
|
|
11054
11301
|
return "UNREADABLE";
|
|
11055
11302
|
}
|
|
11056
11303
|
}
|
|
11057
|
-
function envelopeRunIdProblem(j,
|
|
11304
|
+
function envelopeRunIdProblem(j, runId2) {
|
|
11058
11305
|
if (!isEnvelope(j))
|
|
11059
11306
|
return null;
|
|
11060
11307
|
let id;
|
|
@@ -11063,7 +11310,7 @@ function envelopeRunIdProblem(j, runId) {
|
|
|
11063
11310
|
} catch {
|
|
11064
11311
|
return "envelope payload is not readable";
|
|
11065
11312
|
}
|
|
11066
|
-
return id ===
|
|
11313
|
+
return id === runId2 ? null : `envelope predicate.run_id ${JSON.stringify(id)} does not match run id ${JSON.stringify(runId2)}`;
|
|
11067
11314
|
}
|
|
11068
11315
|
function verifyDsseReceipt(env, d) {
|
|
11069
11316
|
const c = verifyEnvelope(env, d.pubFor);
|
|
@@ -11078,9 +11325,9 @@ function verifyDsseReceipt(env, d) {
|
|
|
11078
11325
|
return { verdict: o.status === "tampered" ? "TAMPERED" : "UNCHECKED", reasons: [o.reason ?? "attestation invalid"] };
|
|
11079
11326
|
return { verdict: "VERIFIED", reasons: [], receiptSha256: computed };
|
|
11080
11327
|
}
|
|
11081
|
-
function runIdGuard(receiptPath,
|
|
11328
|
+
function runIdGuard(receiptPath, runId2) {
|
|
11082
11329
|
try {
|
|
11083
|
-
return envelopeRunIdProblem(JSON.parse(readFileSync33(receiptPath, "utf8")),
|
|
11330
|
+
return envelopeRunIdProblem(JSON.parse(readFileSync33(receiptPath, "utf8")), runId2);
|
|
11084
11331
|
} catch {
|
|
11085
11332
|
return null;
|
|
11086
11333
|
}
|
|
@@ -11094,12 +11341,14 @@ var init_forecast = () => {};
|
|
|
11094
11341
|
var init_queue = __esm(() => {
|
|
11095
11342
|
init_atomic();
|
|
11096
11343
|
init_paths();
|
|
11344
|
+
init_registry2();
|
|
11097
11345
|
init_forecast();
|
|
11098
11346
|
});
|
|
11099
11347
|
|
|
11100
11348
|
// ../../loki-ts/src/commands/undo.ts
|
|
11101
11349
|
var READ_ONLY_GIT;
|
|
11102
11350
|
var init_undo = __esm(() => {
|
|
11351
|
+
init_registry2();
|
|
11103
11352
|
init_paths();
|
|
11104
11353
|
init_safe_git();
|
|
11105
11354
|
init_verify_cmd();
|
|
@@ -11199,7 +11448,7 @@ function mutationProof(i) {
|
|
|
11199
11448
|
return np("no recorded Wall test command");
|
|
11200
11449
|
if (tests.length !== rels.length)
|
|
11201
11450
|
return np("a Wall file has no recorded test command");
|
|
11202
|
-
const budgetS = Math.min(i.timeoutS ?? (
|
|
11451
|
+
const budgetS = Math.min(i.timeoutS ?? envTimeoutS((i.env ?? process.env)["LOKI_MUTATION_PROOF_TIMEOUT_S"]), MAX_TOTAL_S);
|
|
11203
11452
|
const deadline = Date.now() + budgetS * 1000, remaining = () => deadline - Date.now();
|
|
11204
11453
|
let parent = null, wt = null, added = false;
|
|
11205
11454
|
try {
|
|
@@ -11255,7 +11504,10 @@ function mutationProof(i) {
|
|
|
11255
11504
|
rmSync10(parent, { recursive: true, force: true });
|
|
11256
11505
|
}
|
|
11257
11506
|
}
|
|
11258
|
-
var mutationStrict = (env = process.env) => (env["LOKI_MUTATION_STRICT"] ?? "").trim() === "1", mutationEnabled = (env = process.env) => (env["LOKI_MUTATION_PROOF"] ?? "").trim() !== "0", LABEL = "test fails without the fix: ", np = (reason) => ({ outcome: "inconclusive", line: `${LABEL}inconclusive (${reason})` }), MAX_TOTAL_S = 40,
|
|
11507
|
+
var mutationStrict = (env = process.env) => (env["LOKI_MUTATION_STRICT"] ?? "").trim() === "1", mutationEnabled = (env = process.env) => (env["LOKI_MUTATION_PROOF"] ?? "").trim() !== "0", LABEL = "test fails without the fix: ", np = (reason) => ({ outcome: "inconclusive", line: `${LABEL}inconclusive (${reason})` }), MAX_TOTAL_S = 40, envTimeoutS = (raw2) => {
|
|
11508
|
+
const n2 = Number(raw2 ?? 30);
|
|
11509
|
+
return Number.isFinite(n2) && n2 > 0 ? n2 : 30;
|
|
11510
|
+
}, DEP_DIRS, git = (cwd, args, timeout = 30000) => {
|
|
11259
11511
|
try {
|
|
11260
11512
|
safeGit(cwd, args, { timeout });
|
|
11261
11513
|
return { status: 0 };
|
|
@@ -11836,8 +12088,8 @@ function holdoutSplit(seed, ids, opts) {
|
|
|
11836
12088
|
const held = new Set(ranked.slice(0, Math.max(1, Math.round(opts.ratio * ids.length))).map((r) => r.id));
|
|
11837
12089
|
return ids.filter((id) => held.has(id));
|
|
11838
12090
|
}
|
|
11839
|
-
function removeHoldout(
|
|
11840
|
-
rmSync12(holdoutDirFor(
|
|
12091
|
+
function removeHoldout(runId2, repoDir) {
|
|
12092
|
+
rmSync12(holdoutDirFor(runId2, repoDir), { recursive: true, force: true });
|
|
11841
12093
|
}
|
|
11842
12094
|
function stashHoldout(o) {
|
|
11843
12095
|
const eligible = o.names.filter((n2) => o.runnerOf(n2) !== null);
|
|
@@ -11887,7 +12139,7 @@ function recordHoldoutTriage(runDir, entry) {
|
|
|
11887
12139
|
`, { mode: 384 });
|
|
11888
12140
|
} catch {}
|
|
11889
12141
|
}
|
|
11890
|
-
var sha2 = (s) => createHash13("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (
|
|
12142
|
+
var sha2 = (s) => createHash13("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId2, repoDir) => join44(tmpdir6(), `loki-e10-holdout-${sha2(`${runId2}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
|
|
11891
12143
|
var init_holdout = () => {};
|
|
11892
12144
|
|
|
11893
12145
|
// ../../loki-ts/src/features/runner_config.ts
|
|
@@ -12614,11 +12866,11 @@ function killTree(pid) {
|
|
|
12614
12866
|
}
|
|
12615
12867
|
}
|
|
12616
12868
|
async function runOnBase(i, dir) {
|
|
12617
|
-
const
|
|
12869
|
+
const sub2 = (s) => s.split(i.repoDir).join(dir);
|
|
12618
12870
|
const stop = AbortSignal.any([i.signal, AbortSignal.timeout(i.timeoutMs ?? 60000)]);
|
|
12619
12871
|
try {
|
|
12620
|
-
const proc = Bun.spawn([
|
|
12621
|
-
cwd:
|
|
12872
|
+
const proc = Bun.spawn([sub2(i.cmd), ...i.args.map(sub2)], {
|
|
12873
|
+
cwd: sub2(i.cwd ?? i.repoDir),
|
|
12622
12874
|
stdin: "ignore",
|
|
12623
12875
|
stdout: "pipe",
|
|
12624
12876
|
stderr: "pipe",
|
|
@@ -13418,9 +13670,9 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
13418
13670
|
return skip("playwright not resolvable in the repo");
|
|
13419
13671
|
const budget = opts.budgetMs ?? DEFAULT_BUDGET_MS, end = Date.now() + budget, left = () => end - Date.now();
|
|
13420
13672
|
const aborted = () => signal?.aborted === true;
|
|
13421
|
-
const
|
|
13673
|
+
const port2 = await freePort(), base = `http://127.0.0.1:${port2}`;
|
|
13422
13674
|
const [bc, ba] = boot ? ["bash", ["-c", boot.boot.cmd]] : ["npm", ["run", script, "--silent"]];
|
|
13423
|
-
child = spawn7(bc, [...ba], { cwd: appDir, detached: true, env: { ...opts.env ?? process.env, PORT: String(
|
|
13675
|
+
child = spawn7(bc, [...ba], { cwd: appDir, detached: true, env: { ...opts.env ?? process.env, PORT: String(port2), HOST: "127.0.0.1", BROWSER: "none" }, stdio: "ignore" });
|
|
13424
13676
|
child.on("error", () => {
|
|
13425
13677
|
return;
|
|
13426
13678
|
});
|
|
@@ -13609,12 +13861,12 @@ function appendReceiptFact(repoDir, f, now2 = () => new Date) {
|
|
|
13609
13861
|
save(repoDir, lessons);
|
|
13610
13862
|
return true;
|
|
13611
13863
|
}
|
|
13612
|
-
function recordRunVerdict(repoDir,
|
|
13864
|
+
function recordRunVerdict(repoDir, runId2, verdict) {
|
|
13613
13865
|
const lessons = loadLessons(repoDir);
|
|
13614
13866
|
let dirty = false;
|
|
13615
13867
|
for (const l of lessons)
|
|
13616
13868
|
for (const u of l.uses)
|
|
13617
|
-
if (u.run_id ===
|
|
13869
|
+
if (u.run_id === runId2 && u.verdict === null) {
|
|
13618
13870
|
u.verdict = verdict;
|
|
13619
13871
|
dirty = true;
|
|
13620
13872
|
}
|
|
@@ -13931,12 +14183,12 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
|
13931
14183
|
if (withTests.length === 0)
|
|
13932
14184
|
return false;
|
|
13933
14185
|
for (const pkg of withTests) {
|
|
13934
|
-
const tc = pkg.commands.test, name = `full suite: ${pkg.name}`,
|
|
14186
|
+
const tc = pkg.commands.test, name = `full suite: ${pkg.name}`, cmd2 = `(cd ${tc.cwd} && ${tc.cmd})`;
|
|
13935
14187
|
const started = Date.now();
|
|
13936
14188
|
const r = await run(["bash", "-c", tc.cmd], { cwd: join55(repoDir, tc.cwd), timeoutMs: opts.timeoutMs, ...opts.path ? { env: { PATH: opts.path } } : {} });
|
|
13937
14189
|
const duration_s = (Date.now() - started) / 1000;
|
|
13938
14190
|
if (signal.aborted) {
|
|
13939
|
-
checks.push({ name, cmd, result: "not_run", duration_s });
|
|
14191
|
+
checks.push({ name, cmd: cmd2, result: "not_run", duration_s });
|
|
13940
14192
|
notProven.add(`not run: ${name} (aborted)`);
|
|
13941
14193
|
continue;
|
|
13942
14194
|
}
|
|
@@ -13944,12 +14196,12 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
|
13944
14196
|
${r.stderr}`;
|
|
13945
14197
|
const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd: join55(repoDir, tc.cwd), ...opts.path ? { env: { PATH: opts.path } } : {} });
|
|
13946
14198
|
if (lr) {
|
|
13947
|
-
checks.push({ name, cmd, result: "not_run", duration_s });
|
|
14199
|
+
checks.push({ name, cmd: cmd2, result: "not_run", duration_s });
|
|
13948
14200
|
notProven.add(`${lr} (${name}; harness-owned)`);
|
|
13949
14201
|
continue;
|
|
13950
14202
|
}
|
|
13951
14203
|
const cls = classifyCheck({ kind: "test", ok: r.exitCode === 0, out: out2, ...goRunner(tc.cmd) });
|
|
13952
|
-
checks.push({ name, cmd, result: cls.result, duration_s, ...cls.result === "fail" ? { ids: failIds(out2) } : {} });
|
|
14204
|
+
checks.push({ name, cmd: cmd2, result: cls.result, duration_s, ...cls.result === "fail" ? { ids: failIds(out2) } : {} });
|
|
13953
14205
|
if (cls.result === "not_run")
|
|
13954
14206
|
notProven.add(`not run: ${name} (${cls.reason ?? NO_TESTS_REASON})`);
|
|
13955
14207
|
}
|
|
@@ -14108,14 +14360,14 @@ async function secureScanChanged(repoDir, changed, opts) {
|
|
|
14108
14360
|
}
|
|
14109
14361
|
}
|
|
14110
14362
|
async function runSecretScan(ctx, changed, opts, checks, notProven) {
|
|
14111
|
-
const scriptPath = opts.secretScanShPath ?? DEFAULT_SECRET_SCAN_SH, name = "security scan",
|
|
14363
|
+
const scriptPath = opts.secretScanShPath ?? DEFAULT_SECRET_SCAN_SH, name = "security scan", cmd2 = "secret-scan.sh + secure-scan.py";
|
|
14112
14364
|
if (!existsSync36(scriptPath)) {
|
|
14113
|
-
checks.push({ name, cmd, result: "not_run", duration_s: 0 });
|
|
14365
|
+
checks.push({ name, cmd: cmd2, result: "not_run", duration_s: 0 });
|
|
14114
14366
|
notProven.add(`not run: ${name} (secret-scan.sh not found)`);
|
|
14115
14367
|
return;
|
|
14116
14368
|
}
|
|
14117
14369
|
if (changed.length === 0) {
|
|
14118
|
-
checks.push({ name, cmd, result: "pass", duration_s: 0 });
|
|
14370
|
+
checks.push({ name, cmd: cmd2, result: "pass", duration_s: 0 });
|
|
14119
14371
|
return;
|
|
14120
14372
|
}
|
|
14121
14373
|
const inline = 'script="$1"; shift; . "$script" || exit 3; hit=0; for f in "$@"; do if _commit_scan_secret_file "$f" || _commit_path_looks_secret "$f"; then printf "%s\\n" "$f"; hit=1; fi; done; exit "$hit"';
|
|
@@ -14133,7 +14385,7 @@ async function runSecretScan(ctx, changed, opts, checks, notProven) {
|
|
|
14133
14385
|
if (high.length > 0)
|
|
14134
14386
|
reasons.push(`secure-scan: ${high.map((f) => `${f.rule}: ${f.file}:${f.line}`).join(", ")}`);
|
|
14135
14387
|
const result = reasons.length > 0 ? "fail" : gaps.length > 0 ? "not_run" : "pass";
|
|
14136
|
-
checks.push({ name, cmd, result, duration_s: (Date.now() - started) / 1000, ...result === "pass" ? {} : { reason: (result === "fail" ? reasons : gaps).join("; ") } });
|
|
14388
|
+
checks.push({ name, cmd: cmd2, result, duration_s: (Date.now() - started) / 1000, ...result === "pass" ? {} : { reason: (result === "fail" ? reasons : gaps).join("; ") } });
|
|
14137
14389
|
if (result === "not_run")
|
|
14138
14390
|
notProven.add(`not run: ${name} (${gaps.join("; ")})`);
|
|
14139
14391
|
}
|
|
@@ -14279,8 +14531,8 @@ function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
|
|
|
14279
14531
|
function runnerCmd(t, repoDir) {
|
|
14280
14532
|
switch (t.runner) {
|
|
14281
14533
|
case "pytest": {
|
|
14282
|
-
const [
|
|
14283
|
-
return [
|
|
14534
|
+
const [cmd2, interpreter, pre] = resolveTool(repoDir, "python", "python3", "python");
|
|
14535
|
+
return [cmd2, [...pre, "-m", "pytest", "-q", t.path], interpreter];
|
|
14284
14536
|
}
|
|
14285
14537
|
case "vitest":
|
|
14286
14538
|
return ["npx", ["--no-install", "vitest", "run", t.path]];
|
|
@@ -14300,14 +14552,14 @@ function runnerCmd(t, repoDir) {
|
|
|
14300
14552
|
}
|
|
14301
14553
|
function commandFor(t, repoDir, api) {
|
|
14302
14554
|
const site = siteFor(api, repoDir, t.path);
|
|
14303
|
-
const [
|
|
14304
|
-
return { cwd: site?.cwd ?? repoDir, cmd, args, argv: [
|
|
14555
|
+
const [cmd2, args, interpreter] = runnerCmd(site ? { runner: t.runner, path: site.file } : t, repoDir);
|
|
14556
|
+
return { cwd: site?.cwd ?? repoDir, cmd: cmd2, args, argv: [cmd2, ...args], ...interpreter ? { interpreter } : {}, pkgRoot: site?.root ?? "." };
|
|
14305
14557
|
}
|
|
14306
|
-
async function runOnce2(
|
|
14307
|
-
if (!Bun.which(
|
|
14558
|
+
async function runOnce2(cmd2, args, cwd, signal, opts) {
|
|
14559
|
+
if (!Bun.which(cmd2, { PATH: opts.path ?? process.env["PATH"] ?? "" }))
|
|
14308
14560
|
return { ok: false, missing: true, cut: false, out: "" };
|
|
14309
14561
|
const timeout = AbortSignal.timeout(opts.timeoutMs ?? CHECK_TIMEOUT_MS);
|
|
14310
|
-
const proc = Bun.spawn([
|
|
14562
|
+
const proc = Bun.spawn([cmd2, ...args], {
|
|
14311
14563
|
cwd,
|
|
14312
14564
|
stdin: opts.stdin !== undefined ? Buffer.from(opts.stdin) : "ignore",
|
|
14313
14565
|
stdout: "pipe",
|
|
@@ -14345,26 +14597,26 @@ function firstError(out2) {
|
|
|
14345
14597
|
`).map((l2) => (l2.startsWith("{") ? goOut(l2) : l2).trim()).filter(Boolean), l = lines2.find((x) => /^(FAILED\s|\u25cf\s.*\u203a|not ok\s|_{3,}\s.+\s_{3,}$)/.test(x)) ?? lines2.find((x) => /^[\w./-]+\.go:\d+:\d+: \S/.test(x)) ?? lines2.find((x) => /fail|error/i.test(x) && !/^(=|\u2713|ok\b|PASS)/.test(x)) ?? "";
|
|
14346
14598
|
return l.replace(/\d{4}-\d\d-\d\dT[\d:.]+Z?/g, "").replace(/(^|\s)\/(?:[\w.@-]+\/)*[\w.@-]+/g, "$1<path>").replace(/:\d+(?::\d+)?/g, "").replace(/\[?\d+(?:\.\d+)?m?s\]?/g, "").replace(/\s+/g, " ").slice(0, 160);
|
|
14347
14599
|
}
|
|
14348
|
-
async function runCheck(ctx, name,
|
|
14600
|
+
async function runCheck(ctx, name, cmd2, args, signal, checks, opts = {}) {
|
|
14349
14601
|
const started = Date.now();
|
|
14350
|
-
const cmdStr = [
|
|
14602
|
+
const cmdStr = [cmd2, ...args].join(" ");
|
|
14351
14603
|
const kind = opts.kind ?? "test";
|
|
14352
14604
|
const cwd = opts.cwd ?? ctx.repoDir;
|
|
14353
14605
|
const one = async (a) => {
|
|
14354
|
-
let c2 = classifyCheck({ kind, ok: a.ok, cut: a.cut, missing: a.missing, out: a.out, ...goRunner(
|
|
14355
|
-
const lr = kind === "test" && !a.ok && !a.cut && !a.missing ? await harnessLoadReason({ repoDir: ctx.repoDir, baseSha: ctx.baseSha, out: a.out, cmd, args, signal, cwd, protect: opts.protect, ...opts.path ? { env: { PATH: opts.path } } : {} }) : undefined;
|
|
14606
|
+
let c2 = classifyCheck({ kind, ok: a.ok, cut: a.cut, missing: a.missing, out: a.out, ...goRunner(cmd2, args), path: /\.[cm]?[jt]s$/.test(args[args.length - 1] ?? "") ? args[args.length - 1] : undefined });
|
|
14607
|
+
const lr = kind === "test" && !a.ok && !a.cut && !a.missing ? await harnessLoadReason({ repoDir: ctx.repoDir, baseSha: ctx.baseSha, out: a.out, cmd: cmd2, args, signal, cwd, protect: opts.protect, ...opts.path ? { env: { PATH: opts.path } } : {} }) : undefined;
|
|
14356
14608
|
if (lr)
|
|
14357
14609
|
c2 = { result: "not_run", reason: lr, owner: "harness" };
|
|
14358
14610
|
if (!lr && kind === "static" && !a.ok && !a.cut && !a.missing && opts.wall?.size && wallOwnedFailure(a.out, cwd, ctx.repoDir, opts.wall))
|
|
14359
14611
|
c2 = { result: "not_run", reason: WALL_COMPILE_REASON, owner: "harness" };
|
|
14360
|
-
const reason2 = a.missing ? `${
|
|
14612
|
+
const reason2 = a.missing ? `${cmd2} not found on PATH` : a.cut ? signal.aborted ? "aborted" : `timed out after ${(opts.timeoutMs ?? CHECK_TIMEOUT_MS) / 1000}s` : c2.reason;
|
|
14361
14613
|
return { ...c2, ...reason2 ? { reason: reason2 } : {} };
|
|
14362
14614
|
};
|
|
14363
|
-
let attempt = await runOnce2(
|
|
14615
|
+
let attempt = await runOnce2(cmd2, args, cwd, signal, opts);
|
|
14364
14616
|
let c = await one(attempt);
|
|
14365
14617
|
let result = c.result;
|
|
14366
14618
|
if (c.result === "fail") {
|
|
14367
|
-
attempt = await runOnce2(
|
|
14619
|
+
attempt = await runOnce2(cmd2, args, cwd, signal, opts);
|
|
14368
14620
|
c = await one(attempt);
|
|
14369
14621
|
result = c.result === "not_run" ? "not_run" : c.result === "pass" ? "flaky" : "fail";
|
|
14370
14622
|
}
|
|
@@ -14458,10 +14710,10 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
|
14458
14710
|
}
|
|
14459
14711
|
return pre;
|
|
14460
14712
|
}
|
|
14461
|
-
var CHECK_TIMEOUT_MS = 60000, excerpts, isHold = (c) => isHoldoutCheck(c.name), pubHold = (c) => ({ name: "holdout", cmd: "holdout", result: c.result, duration_s: c.duration_s, ...c.n !== undefined ? { n: c.n } : {}, ...c.sk !== undefined ? { sk: c.sk } : {}, ...c.owner ? { owner: c.owner, reason: "holdout infrastructure failure" } : {} }), testCheckName = (t) => `${t.runner}:${t.path}`, dedupeTests = (tests) => [...new Map(tests.map((t) => [`${t.runner}:${t.path}`, t])).values()], CODE_EXT, ESLINT_CONFIGS, excuseLint = (ctx, signal, c, tool,
|
|
14713
|
+
var CHECK_TIMEOUT_MS = 60000, excerpts, isHold = (c) => isHoldoutCheck(c.name), pubHold = (c) => ({ name: "holdout", cmd: "holdout", result: c.result, duration_s: c.duration_s, ...c.n !== undefined ? { n: c.n } : {}, ...c.sk !== undefined ? { sk: c.sk } : {}, ...c.owner ? { owner: c.owner, reason: "holdout infrastructure failure" } : {} }), testCheckName = (t) => `${t.runner}:${t.path}`, dedupeTests = (tests) => [...new Map(tests.map((t) => [`${t.runner}:${t.path}`, t])).values()], CODE_EXT, ESLINT_CONFIGS, excuseLint = (ctx, signal, c, tool, cmd2, prefix, cwd, rel, opts) => c.result !== "fail" || signal.aborted ? Promise.resolve(false) : staticPreExisting(tool, prefix, rel, { run: async (a, stdin) => {
|
|
14462
14714
|
if (signal.aborted)
|
|
14463
14715
|
return null;
|
|
14464
|
-
const r = await runOnce2(
|
|
14716
|
+
const r = await runOnce2(cmd2, a, cwd, AbortSignal.any([signal, AbortSignal.timeout(opts.timeoutMs ?? CHECK_TIMEOUT_MS)]), { ...opts, ...stdin !== undefined ? { stdin } : {} });
|
|
14465
14717
|
return r.missing || r.cut ? null : r;
|
|
14466
14718
|
}, base: (f) => {
|
|
14467
14719
|
try {
|
|
@@ -14735,8 +14987,8 @@ class RealBaseTestRunner {
|
|
|
14735
14987
|
const not_run_files = [];
|
|
14736
14988
|
const api = this.api === undefined ? loadProjectApi(repoDir) : this.api;
|
|
14737
14989
|
for (const f of files) {
|
|
14738
|
-
const { cmd, args, interpreter, cwd } = commandFor(f, repoDir, api);
|
|
14739
|
-
const r = spawnSync7(
|
|
14990
|
+
const { cmd: cmd2, args, interpreter, cwd } = commandFor(f, repoDir, api);
|
|
14991
|
+
const r = spawnSync7(cmd2, f.runner === "pytest" ? [...args, "-rfE"] : args, { cwd, encoding: "utf8", timeout: Math.max(1000, this.timeoutMs), env: plainTestEnv() });
|
|
14740
14992
|
const status = r.error ? null : r.status;
|
|
14741
14993
|
const result = classify(f, status, stripAnsi(`${r.stdout ?? ""}
|
|
14742
14994
|
${r.stderr ?? ""}`), repoDir, interpreter);
|
|
@@ -15620,10 +15872,10 @@ function sealGroup(runDir, rh) {
|
|
|
15620
15872
|
} catch {
|
|
15621
15873
|
return fail2(`unit ${id} sub-receipt missing`);
|
|
15622
15874
|
}
|
|
15623
|
-
const
|
|
15624
|
-
if (!isObj10(
|
|
15875
|
+
const sub2 = readJson6(rp);
|
|
15876
|
+
if (!isObj10(sub2) || typeof sub2["receipt_sha256"] !== "string" || rh(sub2) !== sub2["receipt_sha256"])
|
|
15625
15877
|
return fail2(`unit ${id} sub-receipt unreadable or its hash does not recompute`);
|
|
15626
|
-
const verdict = String(
|
|
15878
|
+
const verdict = String(sub2["verdict"] ?? "");
|
|
15627
15879
|
if (!PASSING.has(verdict)) {
|
|
15628
15880
|
allUnitsPass = false;
|
|
15629
15881
|
notProven.push(`group: unit ${id} verdict ${verdict || "unknown"}`);
|
|
@@ -15632,7 +15884,7 @@ function sealGroup(runDir, rh) {
|
|
|
15632
15884
|
index: index2,
|
|
15633
15885
|
unit_id: id,
|
|
15634
15886
|
sub_receipt_sha256: sha3(bytes),
|
|
15635
|
-
receipt_sha256:
|
|
15887
|
+
receipt_sha256: sub2["receipt_sha256"],
|
|
15636
15888
|
events_file_sha256: existsSync44(ep) ? sha3(readFileSync52(ep)) : null,
|
|
15637
15889
|
verdict,
|
|
15638
15890
|
goal: text2(u["goal"], 200),
|
|
@@ -15686,10 +15938,10 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
15686
15938
|
const evSha = existsSync44(ep) ? sha3(readFileSync52(ep)) : null;
|
|
15687
15939
|
if (evSha !== (e["events_file_sha256"] ?? null))
|
|
15688
15940
|
return bad(`unit ${id} events.jsonl does not match its recorded hash`);
|
|
15689
|
-
const
|
|
15690
|
-
if (!isObj10(
|
|
15941
|
+
const sub2 = readJson6(rp);
|
|
15942
|
+
if (!isObj10(sub2) || sub2["receipt_sha256"] !== e["receipt_sha256"] || rh(sub2) !== e["receipt_sha256"])
|
|
15691
15943
|
return bad(`unit ${id} sub-receipt hash does not recompute`);
|
|
15692
|
-
if (String(
|
|
15944
|
+
if (String(sub2["verdict"] ?? "") !== e["verdict"])
|
|
15693
15945
|
return bad(`unit ${id} verdict differs from the combined receipt`);
|
|
15694
15946
|
const r = await verifyOne(rp, deps);
|
|
15695
15947
|
if (r.verdict === "UNSIGNED" && signed)
|
|
@@ -15944,11 +16196,11 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
|
|
|
15944
16196
|
cargo: ["cargo", "search", dep.name, "--limit", "5"],
|
|
15945
16197
|
go: ["go", "list", "-m", "-json", `${dep.name}@latest`]
|
|
15946
16198
|
};
|
|
15947
|
-
const
|
|
15948
|
-
if (!
|
|
16199
|
+
const cmd2 = argv[dep.ecosystem];
|
|
16200
|
+
if (!cmd2 || dep.name.startsWith("-"))
|
|
15949
16201
|
return { status: "unproven" };
|
|
15950
16202
|
try {
|
|
15951
|
-
const r = await run(
|
|
16203
|
+
const r = await run(cmd2, { cwd, timeoutMs: 1e4 });
|
|
15952
16204
|
return classify2(dep.ecosystem, dep.name, r.exitCode, r.stdout, r.stderr);
|
|
15953
16205
|
} catch {
|
|
15954
16206
|
return { status: "unproven" };
|
|
@@ -16047,7 +16299,7 @@ function renderReceiptMd(r) {
|
|
|
16047
16299
|
].join(`
|
|
16048
16300
|
`);
|
|
16049
16301
|
}
|
|
16050
|
-
var DEEP_NOT_PROVEN, SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", AGENT_ONLY_REASON = "only agent-authored tests executed (no agent-independent proof)", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash18("sha256").update(s).digest("hex"),
|
|
16302
|
+
var DEEP_NOT_PROVEN, SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", AGENT_ONLY_REASON = "only agent-authored tests executed (no agent-independent proof)", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash18("sha256").update(s).digest("hex"), str4 = (v) => typeof v === "string" && v !== "" ? v : null, strs2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : [], receiptRel = (ctx) => {
|
|
16051
16303
|
const r = relative10(ctx.repoDir, join68(ctx.runDir, "receipt.json"));
|
|
16052
16304
|
return r.startsWith("..") || isAbsolute11(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
|
|
16053
16305
|
}, commitStage, wallGreenOnBaseOf = (o) => {
|
|
@@ -16108,7 +16360,7 @@ var init_seal = __esm(() => {
|
|
|
16108
16360
|
const notes = flagOutsideScope(ctx.outputs(), staged.filter(({ f }) => !dropped2.has(f)));
|
|
16109
16361
|
if ((await git4(ctx, ["diff", "--cached", "--quiet"])).code === 0)
|
|
16110
16362
|
return { status: "completed", data: { committed: false, scope_notes: notes } };
|
|
16111
|
-
const title = (
|
|
16363
|
+
const title = (str4(ctx.outputs().intake?.title) ?? `run ${ctx.runId}`).split(`
|
|
16112
16364
|
`)[0].slice(0, 72);
|
|
16113
16365
|
const c = await git4(ctx, ["commit", "-q", "-m", `loki: ${title}`, "-m", [`Loki-Run: ${ctx.runId}`, ...aiTrailers({ runId: ctx.runId, provider: ctx.provider, model: ctx.model, receiptRel: receiptRel(ctx) })].join(`
|
|
16114
16366
|
`)], { repoDrivers: true, userHooks: true });
|
|
@@ -16185,7 +16437,7 @@ var init_seal = __esm(() => {
|
|
|
16185
16437
|
if (!vl.length)
|
|
16186
16438
|
continue;
|
|
16187
16439
|
const tc = tcs?.[t];
|
|
16188
|
-
const mine = assertDeltaNotes(ctx.repoDir, ctx.baseSha, head, t,
|
|
16440
|
+
const mine = assertDeltaNotes(ctx.repoDir, ctx.baseSha, head, t, str4(o.intake?.task) ?? "", cnt(tc?.b), cnt(tc?.h));
|
|
16189
16441
|
if (!mine || mine.length !== vl.length || mine.some((n3) => !vl.includes(n3)))
|
|
16190
16442
|
for (const v of vl)
|
|
16191
16443
|
dropped2.add(v);
|
|
@@ -16218,7 +16470,7 @@ var init_seal = __esm(() => {
|
|
|
16218
16470
|
const source = o.intake?.source;
|
|
16219
16471
|
if (source !== "text" && source !== "issue")
|
|
16220
16472
|
notProven.add("task source not recorded by intake");
|
|
16221
|
-
const repo =
|
|
16473
|
+
const repo = str4(o.intake?.repo);
|
|
16222
16474
|
if (mp?.outcome === "no")
|
|
16223
16475
|
notProven.add(`Wall tests passed without the fix (mutation proof)${verdict !== verdict2 ? "; verdict downgraded to PARTIAL (LOKI_MUTATION_STRICT=1, declared behavior change)" : ""}`);
|
|
16224
16476
|
if (repo === null)
|
|
@@ -16248,7 +16500,7 @@ var init_seal = __esm(() => {
|
|
|
16248
16500
|
const body = {
|
|
16249
16501
|
schema: "loki.v10.receipt/1",
|
|
16250
16502
|
run_id: ctx.runId,
|
|
16251
|
-
task: { source: source === "issue" ? "issue" : "text", sha256:
|
|
16503
|
+
task: { source: source === "issue" ? "issue" : "text", sha256: str4(o.intake?.task_sha256) ?? "" },
|
|
16252
16504
|
repo: repo ?? "",
|
|
16253
16505
|
base_sha: ctx.baseSha,
|
|
16254
16506
|
head_sha: head,
|
|
@@ -16261,7 +16513,7 @@ var init_seal = __esm(() => {
|
|
|
16261
16513
|
...typeof o.implement?.limit_s === "number" ? { implement_limit: { limit_s: o.implement.limit_s, elapsed_s: typeof o.implement.elapsed_s === "number" ? o.implement.elapsed_s : 0 } } : {},
|
|
16262
16514
|
...grp.section ? { group: grp.section } : {},
|
|
16263
16515
|
...ctx.failovers && ctx.failovers().length > 0 ? { failover: ctx.failovers() } : {},
|
|
16264
|
-
...
|
|
16516
|
+
...str4(o.implement?.spec_conflict_reason) !== null ? { spec_conflict_reason: sanitizeReason(str4(o.implement?.spec_conflict_reason)) } : {},
|
|
16265
16517
|
evidence: strs2(o.intake?.evidence),
|
|
16266
16518
|
...o.intake?.preexisting_dirty ? { pre_existing_dirty: Object.keys(o.intake.preexisting_dirty) } : {},
|
|
16267
16519
|
cost: {
|
|
@@ -16325,7 +16577,7 @@ var init_seal = __esm(() => {
|
|
|
16325
16577
|
} catch {}
|
|
16326
16578
|
if (process.env["LOKI_AUTO_LEARN_PR"] !== "0") {
|
|
16327
16579
|
try {
|
|
16328
|
-
appendReceiptFact(ctx.repoDir, { runId: ctx.runId, verdict, receiptSha256: signed ? hash : null, title:
|
|
16580
|
+
appendReceiptFact(ctx.repoDir, { runId: ctx.runId, verdict, receiptSha256: signed ? hash : null, title: str4(ctx.outputs().intake?.title) ?? `run ${ctx.runId}`, headSha: receipt.head_sha });
|
|
16329
16581
|
} catch {}
|
|
16330
16582
|
}
|
|
16331
16583
|
ctx.emit("receipt.sealed", "seal", { path, receipt_sha256: hash, signed, kid: sig.kid, verdict, not_proven: receipt.not_proven, ...routeBlock ? { route_line: routePrLine(routeBlock) } : {} });
|
|
@@ -16415,12 +16667,12 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
16415
16667
|
}
|
|
16416
16668
|
if (sha3(bytes) !== c["receipt_file_sha256"])
|
|
16417
16669
|
return bad(`child ${repo} receipt does not match its recorded hash (swapped or edited)`);
|
|
16418
|
-
const
|
|
16419
|
-
if (!isObj10(
|
|
16670
|
+
const sub2 = readJson6(rp);
|
|
16671
|
+
if (!isObj10(sub2) || sub2["receipt_sha256"] !== c["receipt_sha256"] || rh(sub2) !== c["receipt_sha256"])
|
|
16420
16672
|
return bad(`child ${repo} receipt hash does not recompute`);
|
|
16421
|
-
if (String(
|
|
16673
|
+
if (String(sub2["verdict"] ?? "") !== c["verdict"])
|
|
16422
16674
|
return bad(`child ${repo} verdict differs from the composite`);
|
|
16423
|
-
if (String(
|
|
16675
|
+
if (String(sub2["head_sha"] ?? "") !== c["head_sha"] || !c["head_sha"])
|
|
16424
16676
|
return bad(`child ${repo} head_sha differs from the composite`);
|
|
16425
16677
|
verdicts.push(String(c["verdict"]));
|
|
16426
16678
|
if (typeof heads[repo] !== "string" || heads[repo] === "") {
|
|
@@ -27757,7 +28009,7 @@ if (warning)
|
|
|
27757
28009
|
console.error(warning);
|
|
27758
28010
|
var bindHost = process.env.LOKI_CONTROL_HOST || "127.0.0.1";
|
|
27759
28011
|
var { app } = createApp({ dbPath: process.env.LOKI_CONTROL_DB ?? "control.db", token: process.env.LOKI_CONTROL_TOKEN || undefined, loopbackOnly: isLoopbackHost(bindHost.includes(":") && !bindHost.startsWith("[") ? `[${bindHost}]` : bindHost) });
|
|
27760
|
-
var serve = (
|
|
28012
|
+
var serve = (port2) => Bun.serve({ port: port2, hostname: process.env.LOKI_CONTROL_HOST || "127.0.0.1", fetch: app.fetch });
|
|
27761
28013
|
var s;
|
|
27762
28014
|
try {
|
|
27763
28015
|
s = serve(Number(process.env.PORT ?? 0));
|