@phamvuhoang/otto-core 0.31.0 → 0.33.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.
Files changed (50) hide show
  1. package/dist/compression-survival.d.ts +46 -0
  2. package/dist/compression-survival.d.ts.map +1 -0
  3. package/dist/compression-survival.js +81 -0
  4. package/dist/compression-survival.js.map +1 -0
  5. package/dist/context-compressor.d.ts +13 -2
  6. package/dist/context-compressor.d.ts.map +1 -1
  7. package/dist/context-compressor.js +43 -1
  8. package/dist/context-compressor.js.map +1 -1
  9. package/dist/extension-profiles.js +2 -2
  10. package/dist/extension-profiles.js.map +1 -1
  11. package/dist/headroom-adapter.d.ts +138 -27
  12. package/dist/headroom-adapter.d.ts.map +1 -1
  13. package/dist/headroom-adapter.js +335 -49
  14. package/dist/headroom-adapter.js.map +1 -1
  15. package/dist/index.d.ts +4 -3
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +4 -3
  18. package/dist/index.js.map +1 -1
  19. package/dist/inspect.d.ts.map +1 -1
  20. package/dist/inspect.js +1 -1
  21. package/dist/inspect.js.map +1 -1
  22. package/dist/loop.d.ts.map +1 -1
  23. package/dist/loop.js +45 -7
  24. package/dist/loop.js.map +1 -1
  25. package/dist/plan-rubric.d.ts +1 -1
  26. package/dist/plan-rubric.d.ts.map +1 -1
  27. package/dist/plan-rubric.js +19 -0
  28. package/dist/plan-rubric.js.map +1 -1
  29. package/dist/report-finalize.d.ts.map +1 -1
  30. package/dist/report-finalize.js +4 -3
  31. package/dist/report-finalize.js.map +1 -1
  32. package/dist/run-bin.d.ts.map +1 -1
  33. package/dist/run-bin.js +5 -0
  34. package/dist/run-bin.js.map +1 -1
  35. package/dist/run-report.d.ts +4 -1
  36. package/dist/run-report.d.ts.map +1 -1
  37. package/dist/run-report.js.map +1 -1
  38. package/dist/stage-exec.d.ts.map +1 -1
  39. package/dist/stage-exec.js +5 -1
  40. package/dist/stage-exec.js.map +1 -1
  41. package/dist/verification-evidence.d.ts +4 -0
  42. package/dist/verification-evidence.d.ts.map +1 -1
  43. package/dist/verification-evidence.js +33 -4
  44. package/dist/verification-evidence.js.map +1 -1
  45. package/dist/verification-matrix.d.ts +31 -4
  46. package/dist/verification-matrix.d.ts.map +1 -1
  47. package/dist/verification-matrix.js +44 -5
  48. package/dist/verification-matrix.js.map +1 -1
  49. package/package.json +1 -1
  50. package/templates/plan.md +5 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Fact-survival measurement for context compression (issue #179 P22).
3
+ *
4
+ * The roadmap gates trusting (and later expanding) Headroom compression on one
5
+ * condition: *"use Headroom selectively for `retrievable` categories where **eval
6
+ * proves buried facts survive compression**."* Compression (`context-compressor.ts`,
7
+ * `headroom-adapter.ts`) already shrinks retrievable content and measures the
8
+ * token savings — but token savings alone cannot tell you whether a specific
9
+ * load-bearing fact (an error code, a version, a file path) *survived* the
10
+ * summarization. This module answers that orthogonal question.
11
+ *
12
+ * Pure: it takes a known set of "buried facts" and the compressed text and
13
+ * reports which facts still appear. Evals score survival against facts they
14
+ * supply; the runtime keep-decision (`context-compressor.ts`, issue #200)
15
+ * scores it against anchors mechanically extracted from the original via
16
+ * {@link extractAnchors}, so a compression that drops a load-bearing
17
+ * identifier is rejected instead of used.
18
+ */
19
+ /** The outcome of scoring a fact set against one piece of compressed text. */
20
+ export type FactSurvival = {
21
+ /** How many facts were checked. */
22
+ total: number;
23
+ /** How many facts still appear in the compressed text. */
24
+ survived: number;
25
+ /** `survived / total`, or `1` for an empty fact set (vacuously all survive). */
26
+ survivalRate: number;
27
+ /** The facts that did not appear, in input order. */
28
+ missing: string[];
29
+ };
30
+ /**
31
+ * Score how many `facts` survive in `compressedText`. A fact "survives" when it
32
+ * appears as a normalized (case-insensitive, whitespace-collapsed) substring —
33
+ * robust to a summarizer rephrasing *around* a distinctive identifier while still
34
+ * catching a token that is dropped entirely. Pure.
35
+ */
36
+ export declare function assessFactSurvival(facts: string[], compressedText: string): FactSurvival;
37
+ /**
38
+ * Extract up to `limit` distinctive anchors from original text, deduplicated,
39
+ * in order of first appearance. The runtime survival floor checks these against
40
+ * the compressed text; an empty result means the text has no mechanically
41
+ * recognizable load-bearing tokens (survival is then vacuous). Pure.
42
+ */
43
+ export declare function extractAnchors(text: string, limit?: number): string[];
44
+ /** One-line human summary of a survival assessment for eval output. Pure. */
45
+ export declare function formatFactSurvival(s: FactSurvival): string;
46
+ //# sourceMappingURL=compression-survival.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compression-survival.d.ts","sourceRoot":"","sources":["../src/compression-survival.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG;IACzB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAQF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,cAAc,EAAE,MAAM,GACrB,YAAY,CAUd;AAeD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE,CAcjE;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAG1D"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Fact-survival measurement for context compression (issue #179 P22).
3
+ *
4
+ * The roadmap gates trusting (and later expanding) Headroom compression on one
5
+ * condition: *"use Headroom selectively for `retrievable` categories where **eval
6
+ * proves buried facts survive compression**."* Compression (`context-compressor.ts`,
7
+ * `headroom-adapter.ts`) already shrinks retrievable content and measures the
8
+ * token savings — but token savings alone cannot tell you whether a specific
9
+ * load-bearing fact (an error code, a version, a file path) *survived* the
10
+ * summarization. This module answers that orthogonal question.
11
+ *
12
+ * Pure: it takes a known set of "buried facts" and the compressed text and
13
+ * reports which facts still appear. Evals score survival against facts they
14
+ * supply; the runtime keep-decision (`context-compressor.ts`, issue #200)
15
+ * scores it against anchors mechanically extracted from the original via
16
+ * {@link extractAnchors}, so a compression that drops a load-bearing
17
+ * identifier is rejected instead of used.
18
+ */
19
+ /** Lowercase + collapse internal whitespace + trim, so a summarizer that changes
20
+ * spacing/case around a salient token does not read as a dropped fact. */
21
+ function normalize(s) {
22
+ return s.toLowerCase().replace(/\s+/g, " ").trim();
23
+ }
24
+ /**
25
+ * Score how many `facts` survive in `compressedText`. A fact "survives" when it
26
+ * appears as a normalized (case-insensitive, whitespace-collapsed) substring —
27
+ * robust to a summarizer rephrasing *around* a distinctive identifier while still
28
+ * catching a token that is dropped entirely. Pure.
29
+ */
30
+ export function assessFactSurvival(facts, compressedText) {
31
+ const haystack = normalize(compressedText);
32
+ const missing = facts.filter((f) => !haystack.includes(normalize(f)));
33
+ const survived = facts.length - missing.length;
34
+ return {
35
+ total: facts.length,
36
+ survived,
37
+ survivalRate: facts.length === 0 ? 1 : survived / facts.length,
38
+ missing,
39
+ };
40
+ }
41
+ /**
42
+ * The load-bearing token shapes a summarizer must not drop: slash file paths
43
+ * with an extension, uppercase identifier codes containing a digit or
44
+ * underscore (error codes, env keys — bare acronyms like `API` don't count),
45
+ * and version strings. Ordered by appearance so a capped list keeps the
46
+ * earliest (usually headline) anchors.
47
+ */
48
+ const ANCHOR_PATTERNS = [
49
+ /\bv?\d+\.\d+(?:\.\d+)+\b/g,
50
+ /\b[\w-]+(?:\/[\w.-]+)*\/[\w-]+\.\w{1,8}\b/g,
51
+ /\b[A-Z][A-Z0-9]*[_0-9][A-Z0-9_]*\b/g,
52
+ ];
53
+ /**
54
+ * Extract up to `limit` distinctive anchors from original text, deduplicated,
55
+ * in order of first appearance. The runtime survival floor checks these against
56
+ * the compressed text; an empty result means the text has no mechanically
57
+ * recognizable load-bearing tokens (survival is then vacuous). Pure.
58
+ */
59
+ export function extractAnchors(text, limit = 12) {
60
+ const found = [];
61
+ for (const pattern of ANCHOR_PATTERNS) {
62
+ for (const m of text.matchAll(pattern)) {
63
+ found.push({ index: m.index ?? 0, value: m[0] });
64
+ }
65
+ }
66
+ found.sort((a, b) => a.index - b.index);
67
+ const anchors = [];
68
+ for (const f of found) {
69
+ if (anchors.length >= limit)
70
+ break;
71
+ if (!anchors.includes(f.value))
72
+ anchors.push(f.value);
73
+ }
74
+ return anchors;
75
+ }
76
+ /** One-line human summary of a survival assessment for eval output. Pure. */
77
+ export function formatFactSurvival(s) {
78
+ const pct = Math.round(s.survivalRate * 100);
79
+ return `fact survival: ${s.survived}/${s.total} buried facts survived (${pct}%)`;
80
+ }
81
+ //# sourceMappingURL=compression-survival.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compression-survival.js","sourceRoot":"","sources":["../src/compression-survival.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAcH;2EAC2E;AAC3E,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAe,EACf,cAAsB;IAEtB,MAAM,QAAQ,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/C,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,QAAQ;QACR,YAAY,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,MAAM;QAC9D,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,eAAe,GAAG;IACtB,2BAA2B;IAC3B,4CAA4C;IAC5C,qCAAqC;CACtC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAK,GAAG,EAAE;IACrD,MAAM,KAAK,GAAuC,EAAE,CAAC;IACrD,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK;YAAE,MAAM;QACnC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,CAAe;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC;IAC7C,OAAO,kBAAkB,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,2BAA2B,GAAG,IAAI,CAAC;AACnF,CAAC"}
@@ -32,7 +32,17 @@ export type CompressorMode = "off" | "headroom";
32
32
  * The token-heavy content categories P7 already flags — the targets the roadmap
33
33
  * names. Carried on each compression so a report can attribute savings by source.
34
34
  */
35
- export type CompressionCategory = "issue-body" | "command-log" | "prior-iteration" | "read-artifact" | "memory-projection";
35
+ export declare const COMPRESSION_CATEGORIES: readonly ["issue-body", "command-log", "prior-iteration", "read-artifact", "memory-projection"];
36
+ export type CompressionCategory = (typeof COMPRESSION_CATEGORIES)[number];
37
+ /**
38
+ * Whether a category is authorized for live compression (issue #200). The
39
+ * roadmap scopes Headroom to the `retrievable` lifecycle class — today only
40
+ * `issue-body` (re-fetchable from the tracker). `command-log` diffs/patches
41
+ * feed the *current* decision (the reviewer reads `head.diff` line by line),
42
+ * and `read-artifact` is the unknown default bucket, so both stay verbatim.
43
+ * Pure.
44
+ */
45
+ export declare function isCompressibleCategory(category: CompressionCategory): boolean;
36
46
  /** Content handed to the compressor, tagged by source category + a stable key. */
37
47
  export type CompressInput = {
38
48
  /** A run-unique key (used to name the retrieval artifact). */
@@ -133,7 +143,8 @@ export declare function compressContent(compressor: ContextCompressor | null, in
133
143
  * Synchronous compression for the sync render/`@spill` path, where `renderTemplate`
134
144
  * cannot await. Same reversible measurement and degrade rules as
135
145
  * {@link compressContent}; backed by a {@link SyncContextCompressor} (the Headroom
136
- * command runner is itself synchronous). `compressor === null` original verbatim.
146
+ * runner is synchronous it drives `compress()` via a blocking subprocess).
147
+ * `compressor === null` → original verbatim.
137
148
  */
138
149
  export declare function compressContentSync(compressor: SyncContextCompressor | null, input: CompressInput, store: RetrievalStore | null, now?: () => number): CompressOutput;
139
150
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"context-compressor.d.ts","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-compressor.d.ts","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,31 @@
1
1
  import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { assessFactSurvival, extractAnchors } from "./compression-survival.js";
3
4
  import { estimateTokens } from "./context-report.js";
4
5
  import { runReportDir } from "./run-report.js";
5
6
  const MODES = new Set(["off", "headroom"]);
7
+ /**
8
+ * The token-heavy content categories P7 already flags — the targets the roadmap
9
+ * names. Carried on each compression so a report can attribute savings by source.
10
+ */
11
+ export const COMPRESSION_CATEGORIES = [
12
+ "issue-body",
13
+ "command-log",
14
+ "prior-iteration",
15
+ "read-artifact",
16
+ "memory-projection",
17
+ ];
18
+ /**
19
+ * Whether a category is authorized for live compression (issue #200). The
20
+ * roadmap scopes Headroom to the `retrievable` lifecycle class — today only
21
+ * `issue-body` (re-fetchable from the tracker). `command-log` diffs/patches
22
+ * feed the *current* decision (the reviewer reads `head.diff` line by line),
23
+ * and `read-artifact` is the unknown default bucket, so both stay verbatim.
24
+ * Pure.
25
+ */
26
+ export function isCompressibleCategory(category) {
27
+ return category === "issue-body";
28
+ }
6
29
  /**
7
30
  * Resolve the compressor mode from the flag/env/config precedence chain (flag >
8
31
  * env > config > off). An unrecognized value resolves to `off`, so a typo never
@@ -52,6 +75,13 @@ export function runRetrievalStore(workspaceDir, runId) {
52
75
  return join(".otto", "runs", runId, "compressed", `${safe}.orig`);
53
76
  };
54
77
  }
78
+ /**
79
+ * Minimum share of extracted anchors that must survive for a compression to be
80
+ * kept. At the default 12-anchor cap this tolerates one dropped anchor —
81
+ * summarizers legitimately trim repetition, but losing more than that means
82
+ * load-bearing identifiers are being destroyed.
83
+ */
84
+ const SURVIVAL_FLOOR = 0.9;
55
85
  /**
56
86
  * Turn a raw compression attempt into a measured {@link CompressOutput}, shared
57
87
  * by the async ({@link compressContent}) and sync ({@link compressContentSync})
@@ -80,6 +110,17 @@ function assembleOutput(input, version, result, store, latencyMs) {
80
110
  return passthrough(!result.ok, result.note ??
81
111
  (result.ok ? "no token reduction — kept original" : undefined));
82
112
  }
113
+ // Runtime fact-survival floor (issue #200): a compression that blanks the
114
+ // content or drops mechanically extracted load-bearing anchors (paths,
115
+ // identifier codes, versions) is rejected in favor of the original.
116
+ if (result.text.trim().length === 0) {
117
+ return passthrough(true, "blank compression result — kept original");
118
+ }
119
+ const survival = assessFactSurvival(extractAnchors(input.text), result.text);
120
+ if (survival.survivalRate < SURVIVAL_FLOOR) {
121
+ return passthrough(true, `survival floor: only ${survival.survived}/${survival.total} anchors ` +
122
+ `survived (missing: ${survival.missing.slice(0, 3).join(", ")}) — kept original`);
123
+ }
83
124
  const retrievalHandle = store ? store(input.key, input.text) : undefined;
84
125
  return {
85
126
  text: result.text,
@@ -136,7 +177,8 @@ export async function compressContent(compressor, input, store, deps = {}) {
136
177
  * Synchronous compression for the sync render/`@spill` path, where `renderTemplate`
137
178
  * cannot await. Same reversible measurement and degrade rules as
138
179
  * {@link compressContent}; backed by a {@link SyncContextCompressor} (the Headroom
139
- * command runner is itself synchronous). `compressor === null` original verbatim.
180
+ * runner is synchronous it drives `compress()` via a blocking subprocess).
181
+ * `compressor === null` → original verbatim.
140
182
  */
141
183
  export function compressContentSync(compressor, input, store, now = Date.now) {
142
184
  if (!compressor)
@@ -1 +1 @@
1
- {"version":3,"file":"context-compressor.js","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAkC/C,MAAM,KAAK,GAAwB,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AA0EhE;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACC,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAoB,CAAC,CAAC,CAAC,KAAK,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,MAAyB,OAAO,CAAC,GAAG,EACpC,IAAa;IAEb,IAAI,MAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CACtC,CAAC;QAC7B,IAAI,OAAO,GAAG,CAAC,iBAAiB,KAAK,QAAQ;YAC3C,MAAM,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IACD,OAAO,qBAAqB,CAAC;QAC3B,IAAI;QACJ,GAAG,EAAE,GAAG,CAAC,uBAAuB;QAChC,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,YAAoB,EACpB,KAAa;IAEb,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;QACvB,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChE,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC;AAKD;;;;;;;GAOG;AACH,SAAS,cAAc,CACrB,KAAoB,EACpB,OAAe,EACf,MAAwB,EACxB,KAA4B,EAC5B,SAAiB;IAEjB,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,CAAC,QAAiB,EAAE,IAAa,EAAkB,EAAE,CAAC,CAAC;QACzE,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,YAAY;QACZ,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,CAAC;QACd,SAAS;QACT,iBAAiB,EAAE,OAAO;QAC1B,QAAQ;QACR,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1B,CAAC,CAAC;IAEH,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,WAAW,CAChB,IAAI,EACJ,eAAe,OAAO,+BAA+B,CACtD,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,WAAW,IAAI,YAAY,EAAE,CAAC;QAC9C,OAAO,WAAW,CAChB,CAAC,MAAM,CAAC,EAAE,EACV,MAAM,CAAC,IAAI;YACT,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,SAAS,CAAC,CACjE,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzE,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,YAAY;QACZ,WAAW;QACX,WAAW,EAAE,YAAY,GAAG,WAAW;QACvC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,SAAS;QACT,iBAAiB,EAAE,OAAO;QAC1B,QAAQ,EAAE,KAAK;QACf,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAoC,EACpC,KAAoB,EACpB,KAA4B,EAC5B,OAA+B,EAAE;IAEjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,IAAI,CAAC,UAAU;QACb,OAAO,cAAc,CACnB,KAAK,EACL,KAAK,EACL,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAC9B,IAAI,EACJ,CAAC,CACF,CAAC;IAEJ,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,IAAI,SAAkB,CAAC;IACvB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,UAAU,CAAC,WAAW,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC;IACD,IAAI,CAAC,SAAS;QAAE,OAAO,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAE9E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB;YACE,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,qBAAsB,CAAW,CAAC,OAAO,IAAI,CAAC,EAAE;SACvD,EACD,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAwC,EACxC,KAAoB,EACpB,KAA4B,EAC5B,MAAoB,IAAI,CAAC,GAAG;IAE5B,IAAI,CAAC,UAAU;QACb,OAAO,cAAc,CACnB,KAAK,EACL,KAAK,EACL,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAC9B,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,IAAI,CAAC,UAAU,CAAC,SAAS;QACvB,OAAO,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB,MAAM,EACN,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,cAAc,CACnB,KAAK,EACL,UAAU,CAAC,OAAO,EAClB;YACE,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,qBAAsB,CAAW,CAAC,OAAO,IAAI,CAAC,EAAE;SACvD,EACD,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,QAA6B,EAC7B,KAAc;IAEd,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,GAAG,CAAC,MAAM,CAAC,eAAe;YACxB,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE;YAC7C,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,EAAE;YACP,cAAc,QAAQ,EAAE;YACxB,MAAM,CAAC,QAAQ;gBACb,CAAC,CAAC,yBAAyB;gBAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,SAAS;SACzC;KACF,CAAC;AACJ,CAAC;AAYD,iFAAiF;AACjF,MAAM,UAAU,oBAAoB,CAClC,OAAyB;IAEzB,MAAM,CAAC,GAAuB;QAC5B,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,YAAY,EAAE,CAAC;QACf,WAAW,EAAE,CAAC;QACd,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;KACZ,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC;QACjC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC;QAC/B,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC;QAC/B,IAAI,CAAC,CAAC,eAAe;YAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,CAAC,QAAQ;YAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAmB;IAK1D,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACpC,WAAW,IAAI,CAAC,CAAC;QACjB,WAAW,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC,eAAe;YAAE,UAAU,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAClD,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,wBAAwB,CAAC,CAAqB;IAC5D,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC;QAAE,OAAO,gCAAgC,CAAC;IACjE,MAAM,GAAG,GACP,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,KAAK,GAAG;QACZ,wBAAwB,CAAC,CAAC,WAAW,kBAAkB,GAAG,aAAa,CAAC,CAAC,WAAW,UAAU;QAC9F,GAAG,CAAC,CAAC,UAAU,uBAAuB;KACvC,CAAC;IACF,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,2BAA2B,CAAC,CAAC;IACzE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"context-compressor.js","sourceRoot":"","sources":["../src/context-compressor.ts"],"names":[],"mappings":"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"}
@@ -47,8 +47,8 @@ const PROFILES = [
47
47
  sources: [],
48
48
  tools: [headroomToolDefinition()],
49
49
  config: { contextCompressor: "headroom" },
50
- requires: ["headroom"],
51
- followUp: "Next: install the `headroom` binary, then otto-tools health to confirm it resolves.",
50
+ requires: ["python3", "headroom-ai[ml]"],
51
+ followUp: "Next: pip install 'headroom-ai[ml]' (local Python lib — base is passthrough; no API key), pre-warm the model once, then otto-tools health.",
52
52
  },
53
53
  {
54
54
  name: "security-review",
@@ -1 +1 @@
1
- {"version":3,"file":"extension-profiles.js","sourceRoot":"","sources":["../src/extension-profiles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extension-profiles.js","sourceRoot":"","sources":["../src/extension-profiles.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,45 @@
1
+ import { spawnSync } from "node:child_process";
1
2
  import type { CompressInput, ContextCompressor, SyncContextCompressor } from "./context-compressor.js";
2
- import type { ToolDefinition } from "./tools.js";
3
+ import type { SafetyPolicy } from "./safety-policy.js";
4
+ import type { SafetyEvent } from "./run-report.js";
5
+ import type { ToolConfig, ToolDefinition } from "./tools.js";
3
6
  /**
4
- * Headroom adapter (issue #112 P20) behind P19's external-tool contract.
7
+ * Headroom adapter (issue #112 P20).
5
8
  * [Headroom](https://github.com/headroomlabs-ai/headroom) compresses token-heavy
6
- * content (tool outputs, logs, RAG chunks, files, history). Otto talks to it as a
7
- * governed {@link ToolDefinition}, so the same registry/policy authority that
8
- * gates any tool gates the compressor — it can only run in allowed stages, with
9
- * the declared scope.
9
+ * content (tool outputs, logs, RAG chunks, files, history). A
10
+ * {@link headroomToolDefinition} entry under `.otto/tools/` makes it
11
+ * `otto-tools list`/`health`-visible and governs it: {@link authorizeCompressor}
12
+ * honors the tool's `enabled` flag and authorizes its command against
13
+ * `.otto/policy.json`. It is **not** *stage*-gated, though — the compressor runs
14
+ * at the render boundary, not per stage ([#192](https://github.com/phamvuhoang/otto/issues/192)).
10
15
  *
11
- * This slice implements **local-first command mode** (the roadmap's preferred,
12
- * service-free path): Otto shells out to a local `headroom` binary, piping the
13
- * content on stdin and reading the compressed result on stdout. MCP mode and the
14
- * TypeScript library path slot in behind the same {@link ContextCompressor}
15
- * interface without changing callers; proxy/wrapper mode stays an explicit
16
- * advanced option because it alters provider transport.
16
+ * Otto drives Headroom's real `compress(messages, model)` library through a
17
+ * synchronous subprocess (the render/`@spill` boundary cannot await). Two runners
18
+ * sit behind one {@link HeadroomRunner} contract:
17
19
  *
18
- * Everything is injectable ({@link HeadroomRunner}) so tests never spawn a real
19
- * process, and a missing binary degrades cleanly (the compressor reports
20
- * unavailable and the orchestrator keeps the original content).
20
+ * - **library mode (default):** spawn `python3 -c <bridge>` calling
21
+ * `from headroom import compress` Headroom's documented API (needs the
22
+ * `headroom-ai[ml]` extra; the base package leaves plain text unchanged).
23
+ * Inference is **local** with **no per-call API/cost** (`HEADROOM_MODEL` only
24
+ * selects the tokenizer), but the ML model is **downloaded once from Hugging
25
+ * Face** (~260–600 MB) on first use. Otto forces offline by default (no fetch);
26
+ * when you opt in ({@link authorizeCompressor} pre-authorizes the resolved
27
+ * endpoint against policy + declared domains, though it cannot intercept the
28
+ * subprocess's traffic), so pre-warm it (`HF_HUB_OFFLINE=0` / `HF_ENDPOINT`). The
29
+ * interpreter is overridable via `OTTO_HEADROOM_PYTHON`.
30
+ * - **command mode:** when `OTTO_HEADROOM_BIN` is set, shell out to that binary
31
+ * with `compress --category <c>` (stdin → compressed stdout) — an escape hatch
32
+ * for a custom compressor that already speaks this contract.
33
+ *
34
+ * {@link resolveHeadroomRunner} picks the mode. Everything is injectable (the
35
+ * runner and its `spawn`) so tests never spawn a real process, and a missing
36
+ * interpreter / library degrades cleanly (the compressor reports unavailable or
37
+ * `ok: false` and the orchestrator keeps the original content).
21
38
  */
22
- /** The default binary, overridable via `OTTO_HEADROOM_BIN`. */
23
- export declare const HEADROOM_VERSION = "headroom-cmd-1";
39
+ /** Compressor identity recorded on each compression (mode-agnostic). */
40
+ export declare const HEADROOM_VERSION = "headroom-1";
41
+ /** The injectable process spawner (defaults to `spawnSync`); tests pass a fake. */
42
+ type Spawn = typeof spawnSync;
24
43
  /**
25
44
  * The low-level transport the adapter drives. The default shells out to the
26
45
  * `headroom` CLI; tests inject a double. `available` is the health probe;
@@ -35,12 +54,54 @@ export type HeadroomRunner = {
35
54
  };
36
55
  };
37
56
  /**
38
- * Default command-mode runner: `headroom --version` for availability, and
39
- * `headroom compress --category <c>` (content on stdin compressed stdout) for
40
- * one compression. A non-zero exit / spawn error is a recoverable failure
41
- * (`ok: false`), which the orchestrator turns into a degraded passthrough.
57
+ * Whether the compressor subprocess runs offline. Otto forces `HF_HUB_OFFLINE=1`
58
+ * by default (the runner injects `env.HF_HUB_OFFLINE ?? "1"`), and this MUST match
59
+ * Hugging Face's own parsing so {@link authorizeCompressor}'s "can it reach the
60
+ * network?" matches reality: HF treats only `1`/`true`/`yes`/`on` (case-insensitive)
61
+ * as offline — every other value (e.g. `maybe`) is **online**. Treating an
62
+ * unrecognized value as offline would skip policy authorization while the run
63
+ * actually went online.
64
+ */
65
+ export declare function headroomOffline(env?: NodeJS.ProcessEnv): boolean;
66
+ /**
67
+ * The network host(s) the ML model fetch would ACTUALLY reach, resolved from env
68
+ * like Hugging Face does: `HF_ENDPOINT` (its host) overrides the default HF hosts.
69
+ * Authorizing the resolved endpoint — not the static `tool.networkDomains` — closes
70
+ * the gap where `HF_ENDPOINT=https://evil.example` would slip past a policy that
71
+ * only allows `huggingface.co`.
72
+ */
73
+ export declare function headroomNetworkDomains(env?: NodeJS.ProcessEnv): string[];
74
+ /**
75
+ * The Python bridge driven in library mode: read the spill text on stdin, run it
76
+ * through Headroom's `compress(messages, model)`, and write the compressed text to
77
+ * stdout. Built line-by-line (Python is whitespace-sensitive) so it survives as a
78
+ * `python3 -c` argument. Exit codes are diagnostic only — any non-zero exit is a
79
+ * recoverable failure the orchestrator turns into a degraded passthrough:
80
+ * 2 = library not importable, 1 = compress() raised (e.g. weights not cached
81
+ * while offline), 3 = empty output (never blank out a non-empty spill).
82
+ */
83
+ export declare const HEADROOM_BRIDGE: string;
84
+ /**
85
+ * Library-mode runner (default): probe {@link KOMPRESS_PROBE} for availability
86
+ * (Headroom's `is_kompress_available()` — the real ML backend, not just an import;
87
+ * base is passthrough-only), then run {@link HEADROOM_BRIDGE} per compression.
88
+ * Honors `OTTO_HEADROOM_PYTHON`; inference is local (no API key) and runs with
89
+ * `HF_HUB_OFFLINE=1` by default, so first use needs pre-cached model weights.
90
+ */
91
+ export declare function libraryHeadroomRunner(env?: NodeJS.ProcessEnv, timeoutMs?: number, spawn?: Spawn): HeadroomRunner;
92
+ /**
93
+ * Command-mode runner: `<bin> --version` for availability, and
94
+ * `<bin> compress --category <c>` (content on stdin → compressed stdout) for one
95
+ * compression. Selected only when `OTTO_HEADROOM_BIN` is set — a custom compressor
96
+ * already speaking this contract. A non-zero exit / spawn error degrades cleanly.
42
97
  */
43
- export declare function defaultHeadroomRunner(env?: NodeJS.ProcessEnv, timeoutMs?: number): HeadroomRunner;
98
+ export declare function defaultHeadroomRunner(env?: NodeJS.ProcessEnv, timeoutMs?: number, spawn?: Spawn): HeadroomRunner;
99
+ /**
100
+ * Pick the runner: command mode when `OTTO_HEADROOM_BIN` is set (custom binary),
101
+ * else library mode (Headroom's `compress()` via the Python bridge). The default
102
+ * for both compressor factories.
103
+ */
104
+ export declare function resolveHeadroomRunner(env?: NodeJS.ProcessEnv, timeoutMs?: number, spawn?: Spawn): HeadroomRunner;
44
105
  /**
45
106
  * Build a {@link ContextCompressor} over a {@link HeadroomRunner}. Availability
46
107
  * is cached per instance after the first probe so a run does not re-spawn
@@ -55,11 +116,61 @@ export declare function createHeadroomCompressor(runner?: HeadroomRunner): Conte
55
116
  */
56
117
  export declare function createHeadroomSyncCompressor(runner?: HeadroomRunner): SyncContextCompressor;
57
118
  /**
58
- * The {@link ToolDefinition} a repo drops into `.otto/tools/headroom.json` to put
59
- * the compressor under registry/policy authority. `stages: []` keeps it opt-in
60
- * (a repo enables it per stage); no network/write scope by default — local
61
- * command mode touches neither. Returned as a value so `otto-extensions`
62
- * (P21 `context-saver`) can generate it.
119
+ * The {@link ToolDefinition} a repo drops into `.otto/tools/headroom.json`. It is
120
+ * the registry/`otto-tools` surface and the governance hook ({@link
121
+ * authorizeCompressor} reads its `enabled` flag and authorizes its `command`
122
+ * against policy). `stages: []` is irrelevant to the compressor — it runs at the
123
+ * render boundary, not per stage — so it is NOT stage-gated. Returned as a value
124
+ * so `otto-extensions` (P21 `context-saver`) can generate it.
63
125
  */
64
126
  export declare function headroomToolDefinition(): ToolDefinition;
127
+ /**
128
+ * Every command a run could ACTUALLY execute, resolved from env exactly as
129
+ * {@link resolveHeadroomRunner} does — so policy authorizes what runs, not a
130
+ * static placeholder (issue #192 part 2 follow-up). Command mode emits one entry
131
+ * **per category** (`<bin> compress --category <c>`), matching the real argv, so
132
+ * an argument-specific `blockedCommands` pattern (e.g. `--category command-log`)
133
+ * cannot slip past. Library mode is a single `<python> -c <bridge>` (the bridge
134
+ * text carries `headroom`, so a pattern can match the interpreter or the library).
135
+ */
136
+ export declare function headroomCommands(env?: NodeJS.ProcessEnv): string[];
137
+ /** The compressor governance verdict (issue #192 part 2). */
138
+ export type CompressorAuthorization = {
139
+ allowed: boolean;
140
+ reason: string;
141
+ /** Blocked `policy-violation` events when a registered tool's command is denied. */
142
+ events: SafetyEvent[];
143
+ };
144
+ /**
145
+ * Gate the compressor on tool-registry + policy authority (issue #192 part 2).
146
+ * The compressor is a render-boundary concern, not a per-stage tool, so it is NOT
147
+ * stage-gated (a registered `headroom` tool's `stages: []` is irrelevant here).
148
+ * But when a repo registers the `headroom` tool, the registry and policy DO govern
149
+ * it:
150
+ *
151
+ * - no `headroom` tool registered → the **built-in** {@link headroomToolDefinition}
152
+ * is used for the policy checks (the compressor is enabled by flag/config, not the
153
+ * registry, so a flag/config-only run must still be pre-authorized). A bare repo
154
+ * under `DEFAULT_POLICY` still passes; a restrictive policy still gates it;
155
+ * - tool disabled (registry `enabled: false` or a config override) → denied;
156
+ * - any command that WOULD RUN ({@link headroomCommands}, resolved from `env` like
157
+ * the runtime — one per category in command mode, with `--category <c>`) blocked
158
+ * by `.otto/policy.json` → denied, with the blocked {@link SafetyEvent}s for the
159
+ * evidence bundle. Authorizing the resolved commands (not the static
160
+ * `tool.command`) closes the gap where `OTTO_HEADROOM_BIN` pointed at a
161
+ * policy-blocked binary, or an argument-specific pattern, that authorization
162
+ * never saw;
163
+ * - in **library mode** only, when the run is **not** offline (the user set an
164
+ * online `HF_HUB_OFFLINE`, opting into the in-run model download), the **resolved**
165
+ * endpoint ({@link headroomNetworkDomains}, honoring `HF_ENDPOINT`) is authorized
166
+ * against the repo's `allowedNetworkDomains` — so a network-restricted repo denies
167
+ * the compressor rather than letting it reach an ungoverned host. Offline (the
168
+ * default) reaches no network; command mode (a custom `OTTO_HEADROOM_BIN`) does
169
+ * not use the Python library, so neither triggers the HF check.
170
+ *
171
+ * Pure: the registry, config, policy, and `env` are injected (the loop passes the
172
+ * process env). Default policy + no override always allows.
173
+ */
174
+ export declare function authorizeCompressor(tools: ToolDefinition[], config: ToolConfig, policy: SafetyPolicy, env?: NodeJS.ProcessEnv): CompressorAuthorization;
175
+ export {};
65
176
  //# sourceMappingURL=headroom-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"headroom-adapter.d.ts","sourceRoot":"","sources":["../src/headroom-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,GAAG,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E,CAAC;AAQF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,SAAS,GACjB,cAAc,CA2BhB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,GAAE,cAAwC,GAC/C,iBAAiB,CAWnB;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,GAAE,cAAwC,GAC/C,qBAAqB,CAOvB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,cAAc,CAiBvD"}
1
+ {"version":3,"file":"headroom-adapter.d.ts","sourceRoot":"","sources":["../src/headroom-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C,mFAAmF;AACnF,KAAK,KAAK,GAAG,OAAO,SAAS,CAAC;AAE9B;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,GAAG,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E,CAAC;AA4BF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAG7E;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAUV;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,QA2BhB,CAAC;AAmBb;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,SAAS,EAClB,KAAK,GAAE,KAAiB,GACvB,cAAc,CA2ChB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,SAAS,EAClB,KAAK,GAAE,KAAiB,GACvB,cAAc,CAqBhB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,SAAS,EAClB,KAAK,GAAE,KAAiB,GACvB,cAAc,CAKhB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,GAAE,cAAwC,GAC/C,iBAAiB,CAWnB;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,GAAE,cAAwC,GAC/C,qBAAqB,CAOvB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,cAAc,CAqCvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAMV;AAED,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,YAAY,EACpB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,uBAAuB,CA2DzB"}