altimate-receipts 0.18.1 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LYLHXQAU.js → chunk-44V3DNK5.js} +3 -2
- package/dist/chunk-44V3DNK5.js.map +1 -0
- package/dist/{chunk-JWDZLJDG.js → chunk-C7NAN2LL.js} +17 -17
- package/dist/chunk-C7NAN2LL.js.map +1 -0
- package/dist/{chunk-UADWOMMH.js → chunk-COMWJSBT.js} +2 -2
- package/dist/{chunk-3R25IDH5.js → chunk-MJ3ZJNPX.js} +223 -7
- package/dist/chunk-MJ3ZJNPX.js.map +1 -0
- package/dist/cli.js +67 -91
- package/dist/cli.js.map +1 -1
- package/dist/gen-catalog.js +1 -1
- package/dist/index.js +9 -3
- package/dist/mcp/server.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-3R25IDH5.js.map +0 -1
- package/dist/chunk-JWDZLJDG.js.map +0 -1
- package/dist/chunk-LYLHXQAU.js.map +0 -1
- /package/dist/{chunk-UADWOMMH.js.map → chunk-COMWJSBT.js.map} +0 -0
|
@@ -44,7 +44,8 @@ function privileged(id, filePath) {
|
|
|
44
44
|
return id.startsWith("file-shrink") && !!filePath && TEST_PATH.test(filePath);
|
|
45
45
|
}
|
|
46
46
|
function findingSurface(id) {
|
|
47
|
-
|
|
47
|
+
const base = id.replace(/-sa-[0-9a-f]+$/i, "");
|
|
48
|
+
if (OPERATOR_KINDS.has(base) || base.startsWith("errcluster-")) {
|
|
48
49
|
return "operator";
|
|
49
50
|
}
|
|
50
51
|
return "merge";
|
|
@@ -103,4 +104,4 @@ export {
|
|
|
103
104
|
regenerableReceiptRm,
|
|
104
105
|
regenerableBuildArtifact
|
|
105
106
|
};
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
107
|
+
//# sourceMappingURL=chunk-44V3DNK5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/findings/surface.ts"],"sourcesContent":["/**\n * Which surface a finding belongs to. The **merge gate** (the PR comment) is about\n * the *merged artifact* — what a reviewer must check before merging. The **operator**\n * view (the `receipts` card and `receipts trends`) is about *how the agent worked* —\n * efficiency, cost, loops, retries. One source of truth, shared by the PR-comment\n * renderer and its standalone Action mirror.\n */\n\n/** Kinds that describe agent behaviour/efficiency, not the merged change. */\nconst OPERATOR_KINDS = new Set([\n \"loop\",\n \"bottleneck\",\n \"cost-concentration\",\n \"cache-opportunity\",\n \"model-downgrade\",\n]);\n\nexport type Surface = \"merge\" | \"operator\";\n\n/** Finding-id prefixes that touch a PRIVILEGED surface — CI/CD, lockfiles, hooks,\n * checker config, graders/evals, test integrity, git history (SPEC-0073 R5). These\n * render first in the Agent Work Record, ▲-marked, never collapsed: an edit here runs\n * with repository secrets or moves the ground truth reviewers stand on. */\nexport const PRIVILEGED_PREFIXES = [\n \"ci-cd-touch\",\n \"lockfile-edit\",\n \"hook-bypass\",\n \"config-weaken\",\n \"spec-tamper\",\n \"grader-edit\",\n \"eval-override\",\n \"test-focus\",\n \"test-skipped\",\n \"test-trivialised\",\n \"green-by-suppression\",\n \"untested-test\",\n \"history-rewrite\",\n \"force-push\",\n \"self-permission\",\n \"sensitive-access\",\n \"guard-blocked\",\n \"mcp-write\",\n \"mcp-config-change\",\n \"metadata-egress\",\n \"tls-verify-disabled\",\n \"setuid-create\",\n \"obfuscated-exec\",\n \"untrusted-dep-source\",\n \"persistence-write\",\n \"masked-failure\",\n];\n\n/** `file-shrink` is privileged only when the shrunk file is a test (assertion loss). */\nconst TEST_PATH = /(?:^|\\/)(?:tests?|specs?|__tests__)(?:\\/|$)|\\.(?:test|spec)\\.|_test\\./;\n\nexport function privileged(id: string, filePath?: string): boolean {\n if (PRIVILEGED_PREFIXES.some((p) => id.startsWith(p))) {\n return true;\n }\n return id.startsWith(\"file-shrink\") && !!filePath && TEST_PATH.test(filePath);\n}\n\nexport function findingSurface(id: string): Surface {\n // Classify on the BASE kind: strip a subagent suffix (`-sa-<agentId>`, M104) so a wrapped operator\n // id like `bottleneck-sa-1a2b3c4d` is still recognized as operator and can't leak onto the merge\n // surface. (`errcluster-<tool>` — \"X failed N× before succeeding\" — is also an efficiency signal.)\n const base = id.replace(/-sa-[0-9a-f]+$/i, \"\");\n if (OPERATOR_KINDS.has(base) || base.startsWith(\"errcluster-\")) {\n return \"operator\";\n }\n return \"merge\";\n}\n\n/**\n * Shared shape for the destructive-op carve-outs below. Parses the `rm`/`rmdir` clause from a\n * `Destructive op:` finding title and returns true only when EVERY removal operand satisfies\n * `safe`. A non-rm destructive (git/SQL/infra acts on the repo or an external system) or an empty\n * operand list returns false — i.e. the finding keeps flagging. Each carve-out below just supplies\n * the per-operand `safe` predicate.\n */\nfunction everyRemovalOperand(title: string, safe: (operand: string) => boolean): boolean {\n const clause = title.replace(/^Destructive op:\\s*/i, \"\").replace(/\\s*×\\d+\\s*$/, \"\");\n const m = clause.match(/^\\s*(rm|rmdir)\\b(.*)$/i);\n if (!m) {\n return false;\n }\n const operands = m[2].split(/\\s+/).filter((t) => t && !t.startsWith(\"-\"));\n return operands.length > 0 && operands.every(safe);\n}\n\n/** Strip surrounding quotes from a parsed operand before matching. */\nconst unquote = (operand: string): string => operand.replace(/^[\"']|[\"']$/g, \"\");\n\n/**\n * True when a destructive finding's target is a **scratch path** (a `$VAR`, `/tmp`,\n * `/var/folders`, or `~`), so it can't be a merge risk and shouldn't gate the PR. Conservative:\n * `rm -rf ./src`, `rm -rf build`, `git reset --hard`, `DROP TABLE` are all kept (return false).\n */\nexport function destructiveOutsideRepo(title: string): boolean {\n return everyRemovalOperand(title, (operand) => {\n const p = unquote(operand);\n return (\n /\\$/.test(p) ||\n p.startsWith(\"/tmp\") ||\n p.startsWith(\"/var/folders\") ||\n p.startsWith(\"/private/var/folders\") ||\n p.startsWith(\"~\")\n );\n });\n}\n\n/**\n * True when a destructive finding deletes only the tool's **own regenerable Receipt artifact**\n * (`rm .receipts/<branch>.json`) — a scope-layer carve-out: a `.receipts/*.json` is inside the repo\n * but is rewritten by `receipts pr`, so it isn't a merge risk. Only a flat `.receipts/<name>.json`\n * file matches; a mixed command or the whole dir (`rm -rf .receipts`) keeps flagging.\n */\nexport function regenerableReceiptRm(title: string): boolean {\n return everyRemovalOperand(title, (operand) =>\n /(?:^|\\/)\\.receipts\\/[^/]+\\.json$/.test(unquote(operand)),\n );\n}\n\n/** Well-known regenerable build/dependency output dirs — deleting them is housekeeping, not\n * data loss. Frozen + conservative: excludes `vendor` (committed in Go/PHP), `.cache`/`bin`\n * (ambiguous), `.terraform` (stateful). */\nconst BUILD_DIRS = new Set([\n \"target\",\n \"dist\",\n \"build\",\n \"out\",\n \"node_modules\",\n \".next\",\n \".nuxt\",\n \".turbo\",\n \".parcel-cache\",\n \"__pycache__\",\n \".pytest_cache\",\n \".mypy_cache\",\n \".ruff_cache\",\n \"coverage\",\n \".gradle\",\n]);\n\n/**\n * True when a destructive op deletes only **regenerable build artifacts** (`rm -rf dist`, `rm -rf\n * node_modules`). Scope-layer carve-out like {@link destructiveOutsideRepo}: build output is inside\n * the repo but regenerable in one command. Conservative: every operand must have a path segment in\n * the frozen build-dir set — a mixed command (`rm -rf dist src`) or a real target keeps flagging.\n */\nexport function regenerableBuildArtifact(title: string): boolean {\n return everyRemovalOperand(title, (operand) =>\n unquote(operand)\n .split(\"/\")\n .some((seg) => BUILD_DIRS.has(seg)),\n );\n}\n"],"mappings":";;;AASA,IAAM,iBAAiB,oBAAI,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,IAAM,sBAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,YAAY;AAEX,SAAS,WAAW,IAAY,UAA4B;AACjE,MAAI,oBAAoB,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,GAAG;AACrD,WAAO;AAAA,EACT;AACA,SAAO,GAAG,WAAW,aAAa,KAAK,CAAC,CAAC,YAAY,UAAU,KAAK,QAAQ;AAC9E;AAEO,SAAS,eAAe,IAAqB;AAIlD,QAAM,OAAO,GAAG,QAAQ,mBAAmB,EAAE;AAC7C,MAAI,eAAe,IAAI,IAAI,KAAK,KAAK,WAAW,aAAa,GAAG;AAC9D,WAAO;AAAA,EACT;AACA,SAAO;AACT;AASA,SAAS,oBAAoB,OAAe,MAA6C;AACvF,QAAM,SAAS,MAAM,QAAQ,wBAAwB,EAAE,EAAE,QAAQ,eAAe,EAAE;AAClF,QAAM,IAAI,OAAO,MAAM,wBAAwB;AAC/C,MAAI,CAAC,GAAG;AACN,WAAO;AAAA,EACT;AACA,QAAM,WAAW,EAAE,CAAC,EAAE,MAAM,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,WAAW,GAAG,CAAC;AACxE,SAAO,SAAS,SAAS,KAAK,SAAS,MAAM,IAAI;AACnD;AAGA,IAAM,UAAU,CAAC,YAA4B,QAAQ,QAAQ,gBAAgB,EAAE;AAOxE,SAAS,uBAAuB,OAAwB;AAC7D,SAAO,oBAAoB,OAAO,CAAC,YAAY;AAC7C,UAAM,IAAI,QAAQ,OAAO;AACzB,WACE,KAAK,KAAK,CAAC,KACX,EAAE,WAAW,MAAM,KACnB,EAAE,WAAW,cAAc,KAC3B,EAAE,WAAW,sBAAsB,KACnC,EAAE,WAAW,GAAG;AAAA,EAEpB,CAAC;AACH;AAQO,SAAS,qBAAqB,OAAwB;AAC3D,SAAO;AAAA,IAAoB;AAAA,IAAO,CAAC,YACjC,mCAAmC,KAAK,QAAQ,OAAO,CAAC;AAAA,EAC1D;AACF;AAKA,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,SAAS,yBAAyB,OAAwB;AAC/D,SAAO;AAAA,IAAoB;AAAA,IAAO,CAAC,YACjC,QAAQ,OAAO,EACZ,MAAM,GAAG,EACT,KAAK,CAAC,QAAQ,WAAW,IAAI,GAAG,CAAC;AAAA,EACtC;AACF;","names":[]}
|
|
@@ -3,7 +3,21 @@ import {
|
|
|
3
3
|
destructiveOutsideRepo,
|
|
4
4
|
regenerableBuildArtifact,
|
|
5
5
|
regenerableReceiptRm
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-44V3DNK5.js";
|
|
7
|
+
|
|
8
|
+
// src/version.ts
|
|
9
|
+
import { readFileSync } from "fs";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
function getVersion() {
|
|
12
|
+
try {
|
|
13
|
+
const pkgUrl = new URL("../package.json", import.meta.url);
|
|
14
|
+
const raw = readFileSync(fileURLToPath(pkgUrl), "utf8");
|
|
15
|
+
const pkg = JSON.parse(raw);
|
|
16
|
+
return pkg.version ?? "0.0.0";
|
|
17
|
+
} catch {
|
|
18
|
+
return "0.0.0";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
7
21
|
|
|
8
22
|
// src/findings/gitParse.ts
|
|
9
23
|
var WRAPPER = /* @__PURE__ */ new Set(["sudo", "env", "nohup", "command", "stdbuf", "time", "timeout", "xargs"]);
|
|
@@ -3635,20 +3649,6 @@ function applyDiffScope(derived, findings, files, projectPath) {
|
|
|
3635
3649
|
};
|
|
3636
3650
|
}
|
|
3637
3651
|
|
|
3638
|
-
// src/version.ts
|
|
3639
|
-
import { readFileSync } from "fs";
|
|
3640
|
-
import { fileURLToPath } from "url";
|
|
3641
|
-
function getVersion() {
|
|
3642
|
-
try {
|
|
3643
|
-
const pkgUrl = new URL("../package.json", import.meta.url);
|
|
3644
|
-
const raw = readFileSync(fileURLToPath(pkgUrl), "utf8");
|
|
3645
|
-
const pkg = JSON.parse(raw);
|
|
3646
|
-
return pkg.version ?? "0.0.0";
|
|
3647
|
-
} catch {
|
|
3648
|
-
return "0.0.0";
|
|
3649
|
-
}
|
|
3650
|
-
}
|
|
3651
|
-
|
|
3652
3652
|
// src/receipt/hash.ts
|
|
3653
3653
|
import { createHash } from "crypto";
|
|
3654
3654
|
import { promises as fs } from "fs";
|
|
@@ -5678,6 +5678,7 @@ function redactReceipt(receipt) {
|
|
|
5678
5678
|
}
|
|
5679
5679
|
|
|
5680
5680
|
export {
|
|
5681
|
+
getVersion,
|
|
5681
5682
|
deriveSpans,
|
|
5682
5683
|
cwdAtFirstGit,
|
|
5683
5684
|
formatTokens,
|
|
@@ -5690,7 +5691,6 @@ export {
|
|
|
5690
5691
|
narrowEffort,
|
|
5691
5692
|
windowedEffort,
|
|
5692
5693
|
applyDiffScope,
|
|
5693
|
-
getVersion,
|
|
5694
5694
|
hashTranscriptFile,
|
|
5695
5695
|
sha256Hex,
|
|
5696
5696
|
PREDICATE_TYPE,
|
|
@@ -5719,4 +5719,4 @@ export {
|
|
|
5719
5719
|
redact,
|
|
5720
5720
|
redactReceipt
|
|
5721
5721
|
};
|
|
5722
|
-
//# sourceMappingURL=chunk-
|
|
5722
|
+
//# sourceMappingURL=chunk-C7NAN2LL.js.map
|