@deftai/directive-core 0.98.0 → 0.99.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 (59) hide show
  1. package/dist/authz/classify.js +400 -56
  2. package/dist/consumer-check-contract/evaluate.d.ts +40 -0
  3. package/dist/consumer-check-contract/evaluate.js +188 -3
  4. package/dist/consumer-check-contract/index.d.ts +1 -1
  5. package/dist/consumer-check-contract/index.js +1 -1
  6. package/dist/content-contracts/skills/greptile-detector.d.ts +42 -0
  7. package/dist/content-contracts/skills/greptile-detector.js +202 -4
  8. package/dist/decision/index.d.ts +17 -0
  9. package/dist/decision/index.js +35 -0
  10. package/dist/decision/list.d.ts +47 -0
  11. package/dist/decision/list.js +250 -0
  12. package/dist/decision/schema.d.ts +88 -0
  13. package/dist/decision/schema.js +293 -0
  14. package/dist/decision/write.d.ts +82 -0
  15. package/dist/decision/write.js +427 -0
  16. package/dist/eval/report.d.ts +29 -0
  17. package/dist/eval/report.js +69 -0
  18. package/dist/eval/run.d.ts +9 -0
  19. package/dist/eval/run.js +40 -4
  20. package/dist/eval/version-pin.d.ts +99 -0
  21. package/dist/eval/version-pin.js +181 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +1 -0
  24. package/dist/platform/host-content-surface.d.ts +74 -0
  25. package/dist/platform/host-content-surface.js +214 -0
  26. package/dist/platform/index.d.ts +1 -0
  27. package/dist/platform/index.js +1 -0
  28. package/dist/policy/ceremony-dial.d.ts +233 -0
  29. package/dist/policy/ceremony-dial.js +829 -0
  30. package/dist/policy/deft-directive-disable.js +12 -2
  31. package/dist/policy/index.d.ts +1 -0
  32. package/dist/policy/index.js +15 -1
  33. package/dist/pr-merge-readiness/evaluate.js +10 -0
  34. package/dist/pr-merge-readiness/mergeability.js +5 -0
  35. package/dist/pr-merge-readiness/output.js +2 -0
  36. package/dist/pr-merge-readiness/parse.js +4 -0
  37. package/dist/pr-merge-readiness/types.d.ts +6 -0
  38. package/dist/scope/effort-activate-gate.d.ts +28 -0
  39. package/dist/scope/effort-activate-gate.js +64 -0
  40. package/dist/scope/index.d.ts +1 -0
  41. package/dist/scope/index.js +1 -0
  42. package/dist/scope/transition.js +8 -0
  43. package/dist/scope-provenance/evaluate.d.ts +21 -0
  44. package/dist/scope-provenance/evaluate.js +143 -33
  45. package/dist/scope-provenance/index.d.ts +1 -1
  46. package/dist/scope-provenance/index.js +1 -1
  47. package/dist/session/session-start.d.ts +24 -1
  48. package/dist/session/session-start.js +183 -26
  49. package/dist/swarm/index.d.ts +2 -0
  50. package/dist/swarm/index.js +2 -0
  51. package/dist/swarm/pre-dispatch-cli.d.ts +19 -0
  52. package/dist/swarm/pre-dispatch-cli.js +143 -0
  53. package/dist/swarm/pre-dispatch.d.ts +87 -0
  54. package/dist/swarm/pre-dispatch.js +373 -0
  55. package/dist/vbrief-activate/activate.js +6 -0
  56. package/dist/vbrief-validate/constants.d.ts +2 -0
  57. package/dist/vbrief-validate/constants.js +2 -0
  58. package/dist/vbrief-validate/schema.js +4 -1
  59. package/package.json +15 -3
@@ -1,3 +1,4 @@
1
+ import { type FrameworkVersionPin } from "./version-pin.js";
1
2
  export declare const GOLDEN_RUNS_HISTORY_REL = "results/golden-runs.jsonl";
2
3
  export declare const GOLDEN_RUN_SCHEMA_VERSION: 1;
3
4
  export declare const GOLDEN_CORPUS_VERSION = "2026-07-05-tier2-fixture-v1";
@@ -32,7 +33,13 @@ export interface GoldenTaskResult {
32
33
  export interface GoldenRunRecord {
33
34
  readonly schemaVersion: typeof GOLDEN_RUN_SCHEMA_VERSION;
34
35
  readonly runId: string;
36
+ /** Framework version pin for this run (alias of frameworkVersionPin.frameworkVersion). */
35
37
  readonly directiveVersion: string;
38
+ /**
39
+ * Resolved framework version pin captured at run start (#3215).
40
+ * Optional for ledger rows written before the purity gate shipped.
41
+ */
42
+ readonly frameworkVersionPin?: FrameworkVersionPin;
36
43
  readonly model: string;
37
44
  readonly harness: string;
38
45
  readonly seeds: readonly number[];
@@ -63,6 +70,8 @@ export interface RunGoldenEvalResult {
63
70
  readonly code: 0 | 1 | 2;
64
71
  readonly record: GoldenRunRecord | null;
65
72
  readonly message: string;
73
+ /** #1584 shared-benchmark manifest after version pin wire, when present on disk. */
74
+ readonly sharedBenchmarkManifest?: Record<string, unknown> | null;
66
75
  }
67
76
  /** Fixed golden corpus with objective graders (#1703 Tier 2). */
68
77
  export declare const GOLDEN_CORPUS: readonly GoldenTaskDefinition[];
package/dist/eval/run.js CHANGED
@@ -2,11 +2,11 @@ import { createHash } from "node:crypto";
2
2
  import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join, resolve } from "node:path";
5
- import { readCorePackageVersion } from "../engine-version.js";
6
5
  import { containedWrite } from "../fs/contained-write.js";
7
6
  import { resolveEvalPath } from "../layout/resolve.js";
8
7
  import { BYTE_DIFF_WHOLE_FILE_THRESHOLD, InstrumentedVbriefCrud } from "./crud-telemetry.js";
9
8
  import { evaluateHealth } from "./health.js";
9
+ import { applyVersionPinToSharedBenchmark, resolveFrameworkVersionPin, } from "./version-pin.js";
10
10
  export const GOLDEN_RUNS_HISTORY_REL = "results/golden-runs.jsonl";
11
11
  export const GOLDEN_RUN_SCHEMA_VERSION = 1;
12
12
  export const GOLDEN_CORPUS_VERSION = "2026-07-05-tier2-fixture-v1";
@@ -250,10 +250,15 @@ export function runGoldenEval(options) {
250
250
  return { code: 2, record: null, message: "eval:run: --model is required" };
251
251
  }
252
252
  const projectRoot = options.projectRoot ?? process.cwd();
253
- const directiveVersion = options.directiveVersion ?? readCorePackageVersion();
253
+ const now = options.now ?? (() => new Date());
254
+ // #3215: resolve framework version once at run start (package.json pin or override).
255
+ const frameworkVersionPin = resolveFrameworkVersionPin({
256
+ override: options.directiveVersion,
257
+ now,
258
+ });
259
+ const directiveVersion = frameworkVersionPin.frameworkVersion;
254
260
  const harness = options.harness ?? "deterministic-fixture";
255
261
  const seeds = options.seeds ?? [1, 2, 3];
256
- const now = options.now ?? (() => new Date());
257
262
  const persist = options.persist ?? true;
258
263
  if (seeds.length === 0) {
259
264
  return { code: 2, record: null, message: "eval:run: at least one seed is required" };
@@ -293,6 +298,7 @@ export function runGoldenEval(options) {
293
298
  schemaVersion: GOLDEN_RUN_SCHEMA_VERSION,
294
299
  runId: runIdFor(directiveVersion, options.model, harness, seeds),
295
300
  directiveVersion,
301
+ frameworkVersionPin,
296
302
  model: options.model,
297
303
  harness,
298
304
  seeds,
@@ -303,6 +309,8 @@ export function runGoldenEval(options) {
303
309
  results,
304
310
  summary,
305
311
  };
312
+ // Persist ledger first so a failed golden-run write never leaves a dangling
313
+ // shared-benchmark pin without a matching run row (#3215 Greptile).
306
314
  if (persist) {
307
315
  try {
308
316
  persistGoldenRun(projectRoot, record);
@@ -312,16 +320,44 @@ export function runGoldenEval(options) {
312
320
  code: 2,
313
321
  record,
314
322
  message: `eval:run: failed to persist golden run: ${String(err)}`,
323
+ sharedBenchmarkManifest: null,
315
324
  };
316
325
  }
317
326
  }
327
+ // #1584 / #3215: wire (+ persist when ledger was written) shared-benchmark pin.
328
+ let sharedBenchmark;
329
+ try {
330
+ sharedBenchmark = applyVersionPinToSharedBenchmark(projectRoot, frameworkVersionPin, {
331
+ persist,
332
+ });
333
+ }
334
+ catch (err) {
335
+ return {
336
+ code: 2,
337
+ record,
338
+ message: `eval:run: failed to wire shared-benchmark pin: ${String(err)}`,
339
+ sharedBenchmarkManifest: null,
340
+ };
341
+ }
318
342
  const lines = [
319
343
  `eval:run v${record.directiveVersion} model=${record.model} harness=${record.harness} seeds=[${record.seeds.join(",")}]`,
344
+ ` framework version pin: ${frameworkVersionPin.frameworkVersion} (source=${frameworkVersionPin.source})`,
320
345
  ` primary pass rate: ${(summary.primaryPassRate * 100).toFixed(1)}% (${summary.primaryTotal} trials)`,
321
346
  ` holdout pass rate: ${(summary.holdoutPassRate * 100).toFixed(1)}% (${summary.holdoutTotal} trials)`,
322
347
  ` rotating holdout task: ${rotatingHoldout?.id ?? "none"}`,
323
348
  ` runId=${record.runId}`,
324
349
  ];
325
- return { code: 0, record, message: lines.join("\n") };
350
+ if (sharedBenchmark.persisted) {
351
+ lines.push(" shared-benchmark manifest: frameworkVersion pin persisted (#1584 / #3215)");
352
+ }
353
+ else if (sharedBenchmark.applied) {
354
+ lines.push(" shared-benchmark manifest: frameworkVersion wired in-memory (#1584 / #3215)");
355
+ }
356
+ return {
357
+ code: 0,
358
+ record,
359
+ message: lines.join("\n"),
360
+ sharedBenchmarkManifest: sharedBenchmark.manifest,
361
+ };
326
362
  }
327
363
  //# sourceMappingURL=run.js.map
@@ -0,0 +1,99 @@
1
+ /**
2
+ * #3215 — pin and record framework version per eval cell; refuse mixed-version aggregation.
3
+ * Extends #3081 empiricism; wires into the #1584 shared-benchmark manifest shape when present.
4
+ */
5
+ /** Repo-relative path for the #1584 shared-benchmark manifest. */
6
+ export declare const SHARED_BENCHMARK_MANIFEST_REL = "evals/shared-benchmark.json";
7
+ /** How the framework version was resolved at eval run start. */
8
+ export type FrameworkVersionSource = "package.json" | "override";
9
+ /** Policy when a treatment cell contains disagreeing framework versions. */
10
+ export type MixedVersionPolicy = "refuse" | "flag";
11
+ /** Resolved framework version pin captured once at eval run start. */
12
+ export interface FrameworkVersionPin {
13
+ readonly frameworkVersion: string;
14
+ readonly source: FrameworkVersionSource;
15
+ readonly resolvedAt: string;
16
+ }
17
+ /** Minimal run identity for cell purity checks (version + treatment grouping). */
18
+ export interface VersionedEvalRun {
19
+ readonly frameworkVersion: string;
20
+ readonly treatment?: string;
21
+ readonly model?: string;
22
+ readonly harness?: string;
23
+ readonly runId?: string;
24
+ }
25
+ /** Result of checking whether one treatment cell is version-pure. */
26
+ export interface CellVersionPurity {
27
+ readonly pure: boolean;
28
+ readonly frameworkVersion: string | null;
29
+ readonly versions: readonly string[];
30
+ readonly runCount: number;
31
+ readonly treatment: string;
32
+ readonly message: string;
33
+ }
34
+ export interface AggregateCellOptions {
35
+ readonly runs: readonly VersionedEvalRun[];
36
+ /** Treatment key when runs omit `treatment` (e.g. model or with_skill). */
37
+ readonly treatment?: string;
38
+ /** Default `refuse`: mixed cells block aggregation. `flag` allows with purity evidence. */
39
+ readonly policy?: MixedVersionPolicy;
40
+ }
41
+ export interface AggregateCellResult {
42
+ readonly purity: CellVersionPurity;
43
+ readonly allowed: boolean;
44
+ readonly policy: MixedVersionPolicy;
45
+ readonly frameworkVersion: string | null;
46
+ }
47
+ /** Version block stamped onto a #1584-shaped shared-benchmark manifest. */
48
+ export interface SharedBenchmarkVersionBlock {
49
+ readonly frameworkVersion: string;
50
+ readonly frameworkVersionSource: FrameworkVersionSource;
51
+ readonly frameworkVersionResolvedAt: string;
52
+ readonly versionPurityGate: "#3215";
53
+ }
54
+ /**
55
+ * Resolve the directive framework version once at eval run start.
56
+ * Prefers an explicit override (tests / pinned doctor output); else package.json pin.
57
+ */
58
+ export declare function resolveFrameworkVersionPin(options?: {
59
+ readonly override?: string;
60
+ readonly now?: () => Date;
61
+ }): FrameworkVersionPin;
62
+ /**
63
+ * Cell-level purity: all runs in one treatment must share a single framework version.
64
+ * Empty run sets are vacuously pure.
65
+ */
66
+ export declare function evaluateCellVersionPurity(runs: readonly VersionedEvalRun[], treatment?: string): CellVersionPurity;
67
+ /**
68
+ * Aggregate (or refuse) runs for one treatment under the mixed-version policy.
69
+ * `refuse` (default) sets `allowed=false` when versions disagree; `flag` allows with evidence.
70
+ */
71
+ export declare function aggregateCellWithVersionPurity(options: AggregateCellOptions): AggregateCellResult;
72
+ /**
73
+ * Group runs by treatment (or model×harness fallback) and evaluate purity per cell.
74
+ */
75
+ export declare function evaluateLedgerVersionPurity(runs: readonly VersionedEvalRun[]): {
76
+ readonly pure: boolean;
77
+ readonly cells: readonly CellVersionPurity[];
78
+ readonly summary: string;
79
+ };
80
+ /**
81
+ * Merge a framework version pin into a #1584-shaped shared-benchmark manifest object.
82
+ * Stamps top-level `frameworkVersion` plus metadata for external consumers.
83
+ */
84
+ export declare function wireFrameworkVersionIntoManifest(manifest: Record<string, unknown>, pin: FrameworkVersionPin): Record<string, unknown>;
85
+ /** Load `evals/shared-benchmark.json` when present; otherwise null. */
86
+ export declare function loadSharedBenchmarkManifest(projectRoot: string): Record<string, unknown> | null;
87
+ /**
88
+ * When a #1584 shared-benchmark manifest exists under the project root, return it
89
+ * with the framework version pin wired in. When `persist` is true, write the
90
+ * wired manifest back to disk so subsequent consumers see the pin (#3215 Greptile).
91
+ */
92
+ export declare function applyVersionPinToSharedBenchmark(projectRoot: string, pin: FrameworkVersionPin, options?: {
93
+ readonly persist?: boolean;
94
+ }): {
95
+ readonly applied: boolean;
96
+ readonly persisted: boolean;
97
+ readonly manifest: Record<string, unknown> | null;
98
+ };
99
+ //# sourceMappingURL=version-pin.d.ts.map
@@ -0,0 +1,181 @@
1
+ /**
2
+ * #3215 — pin and record framework version per eval cell; refuse mixed-version aggregation.
3
+ * Extends #3081 empiricism; wires into the #1584 shared-benchmark manifest shape when present.
4
+ */
5
+ import { existsSync, readFileSync } from "node:fs";
6
+ import { resolve } from "node:path";
7
+ import { readCorePackageVersion } from "../engine-version.js";
8
+ import { containedWrite } from "../fs/contained-write.js";
9
+ /** Repo-relative path for the #1584 shared-benchmark manifest. */
10
+ export const SHARED_BENCHMARK_MANIFEST_REL = "evals/shared-benchmark.json";
11
+ function toIsoZ(date) {
12
+ return date.toISOString().replace(/\.\d{3}Z$/, "Z");
13
+ }
14
+ /**
15
+ * Resolve the directive framework version once at eval run start.
16
+ * Prefers an explicit override (tests / pinned doctor output); else package.json pin.
17
+ */
18
+ export function resolveFrameworkVersionPin(options) {
19
+ const now = options?.now ?? (() => new Date());
20
+ const override = options?.override?.trim();
21
+ if (override !== undefined && override.length > 0) {
22
+ return {
23
+ frameworkVersion: override,
24
+ source: "override",
25
+ resolvedAt: toIsoZ(now()),
26
+ };
27
+ }
28
+ return {
29
+ frameworkVersion: readCorePackageVersion(),
30
+ source: "package.json",
31
+ resolvedAt: toIsoZ(now()),
32
+ };
33
+ }
34
+ /**
35
+ * Cell-level purity: all runs in one treatment must share a single framework version.
36
+ * Empty run sets are vacuously pure.
37
+ */
38
+ export function evaluateCellVersionPurity(runs, treatment) {
39
+ const label = treatment?.trim() ||
40
+ runs.find((r) => typeof r.treatment === "string" && r.treatment.length > 0)?.treatment ||
41
+ "default";
42
+ const versions = [
43
+ ...new Set(runs.map((r) => r.frameworkVersion.trim()).filter((v) => v.length > 0)),
44
+ ].sort();
45
+ if (runs.length === 0) {
46
+ return {
47
+ pure: true,
48
+ frameworkVersion: null,
49
+ versions: [],
50
+ runCount: 0,
51
+ treatment: label,
52
+ message: `Cell "${label}": no runs (vacuously pure).`,
53
+ };
54
+ }
55
+ if (versions.length <= 1) {
56
+ const version = versions[0] ?? null;
57
+ return {
58
+ pure: true,
59
+ frameworkVersion: version,
60
+ versions,
61
+ runCount: runs.length,
62
+ treatment: label,
63
+ message: `Cell "${label}": version-pure (v${version ?? "unknown"}, ${runs.length} run(s)).`,
64
+ };
65
+ }
66
+ return {
67
+ pure: false,
68
+ frameworkVersion: null,
69
+ versions,
70
+ runCount: runs.length,
71
+ treatment: label,
72
+ message: `Cell "${label}": mixed framework versions [${versions.join(", ")}] across ${runs.length} run(s) — mixed-version aggregation blocked (#3215).`,
73
+ };
74
+ }
75
+ /**
76
+ * Aggregate (or refuse) runs for one treatment under the mixed-version policy.
77
+ * `refuse` (default) sets `allowed=false` when versions disagree; `flag` allows with evidence.
78
+ */
79
+ export function aggregateCellWithVersionPurity(options) {
80
+ const policy = options.policy ?? "refuse";
81
+ const purity = evaluateCellVersionPurity(options.runs, options.treatment);
82
+ const allowed = purity.pure || policy === "flag";
83
+ return {
84
+ purity,
85
+ allowed,
86
+ policy,
87
+ frameworkVersion: purity.frameworkVersion,
88
+ };
89
+ }
90
+ /**
91
+ * Group runs by treatment (or model×harness fallback) and evaluate purity per cell.
92
+ */
93
+ export function evaluateLedgerVersionPurity(runs) {
94
+ const groups = new Map();
95
+ for (const run of runs) {
96
+ const key = run.treatment?.trim() ||
97
+ [run.model ?? "", run.harness ?? ""].filter((p) => p.length > 0).join("@") ||
98
+ "default";
99
+ const list = groups.get(key) ?? [];
100
+ list.push(run);
101
+ groups.set(key, list);
102
+ }
103
+ const cells = [...groups.entries()]
104
+ .sort(([a], [b]) => a.localeCompare(b))
105
+ .map(([key, group]) => evaluateCellVersionPurity(group, key));
106
+ const pure = cells.every((c) => c.pure);
107
+ const mixed = cells.filter((c) => !c.pure);
108
+ const summary = cells.length === 0
109
+ ? "Version purity: no cells."
110
+ : pure
111
+ ? `Version purity: all ${cells.length} cell(s) pure.`
112
+ : `Version purity: ${mixed.length}/${cells.length} cell(s) mixed — ${mixed.map((c) => c.treatment).join(", ")}.`;
113
+ return { pure, cells, summary };
114
+ }
115
+ /**
116
+ * Merge a framework version pin into a #1584-shaped shared-benchmark manifest object.
117
+ * Stamps top-level `frameworkVersion` plus metadata for external consumers.
118
+ */
119
+ export function wireFrameworkVersionIntoManifest(manifest, pin) {
120
+ const priorMeta = typeof manifest.metadata === "object" &&
121
+ manifest.metadata !== null &&
122
+ !Array.isArray(manifest.metadata)
123
+ ? { ...manifest.metadata }
124
+ : {};
125
+ const versionBlock = {
126
+ frameworkVersion: pin.frameworkVersion,
127
+ frameworkVersionSource: pin.source,
128
+ frameworkVersionResolvedAt: pin.resolvedAt,
129
+ versionPurityGate: "#3215",
130
+ };
131
+ return {
132
+ ...manifest,
133
+ frameworkVersion: pin.frameworkVersion,
134
+ metadata: {
135
+ ...priorMeta,
136
+ ...versionBlock,
137
+ },
138
+ };
139
+ }
140
+ /** Load `evals/shared-benchmark.json` when present; otherwise null. */
141
+ export function loadSharedBenchmarkManifest(projectRoot) {
142
+ const path = resolve(projectRoot, SHARED_BENCHMARK_MANIFEST_REL);
143
+ if (!existsSync(path)) {
144
+ return null;
145
+ }
146
+ try {
147
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
148
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
149
+ return parsed;
150
+ }
151
+ return null;
152
+ }
153
+ catch {
154
+ return null;
155
+ }
156
+ }
157
+ /**
158
+ * When a #1584 shared-benchmark manifest exists under the project root, return it
159
+ * with the framework version pin wired in. When `persist` is true, write the
160
+ * wired manifest back to disk so subsequent consumers see the pin (#3215 Greptile).
161
+ */
162
+ export function applyVersionPinToSharedBenchmark(projectRoot, pin, options) {
163
+ const existing = loadSharedBenchmarkManifest(projectRoot);
164
+ if (existing === null) {
165
+ return { applied: false, persisted: false, manifest: null };
166
+ }
167
+ const manifest = wireFrameworkVersionIntoManifest(existing, pin);
168
+ const shouldPersist = options?.persist === true;
169
+ if (!shouldPersist) {
170
+ return { applied: true, persisted: false, manifest };
171
+ }
172
+ // #2980: product write sink routes through containedWrite.
173
+ containedWrite({
174
+ root: resolve(projectRoot),
175
+ target: SHARED_BENCHMARK_MANIFEST_REL,
176
+ data: `${JSON.stringify(manifest, null, 2)}\n`,
177
+ mode: "replace",
178
+ });
179
+ return { applied: true, persisted: true, manifest };
180
+ }
181
+ //# sourceMappingURL=version-pin.js.map
package/dist/index.d.ts CHANGED
@@ -24,6 +24,7 @@ export * as evalCrud from "./eval/crud-telemetry.js";
24
24
  export * as evalHealth from "./eval/health.js";
25
25
  export * as evalReport from "./eval/report.js";
26
26
  export * as evalRun from "./eval/run.js";
27
+ export * as evalVersionPin from "./eval/version-pin.js";
27
28
  export * as events from "./events/attribution-ledger.js";
28
29
  export * from "./forward-coverage/evaluate.js";
29
30
  export * as freshness from "./freshness/index.js";
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ export * as evalCrud from "./eval/crud-telemetry.js";
24
24
  export * as evalHealth from "./eval/health.js";
25
25
  export * as evalReport from "./eval/report.js";
26
26
  export * as evalRun from "./eval/run.js";
27
+ export * as evalVersionPin from "./eval/version-pin.js";
27
28
  export * as events from "./events/attribution-ledger.js";
28
29
  export * from "./forward-coverage/evaluate.js";
29
30
  export * as freshness from "./freshness/index.js";
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Host content-surface class + managed-section drift (#3162).
3
+ *
4
+ * Directive file gates and #830/#2508 pins assume filesystem-visible work product
5
+ * and a host that does not rewrite constitution mid-run. REPL-first and
6
+ * self-mutating hosts break those assumptions. This module classifies the host
7
+ * surface (capability pointer #1461/#1357) and reports managed AGENTS section
8
+ * drift without inventing a full pin product.
9
+ *
10
+ * Never blocks session-start — advisory only.
11
+ */
12
+ import { type AgentsMdSeams } from "./agents-md.js";
13
+ /** Host content-surface classes for gate / pin honesty (#3162). */
14
+ export declare const HOST_CONTENT_SURFACE_CLASSES: readonly ["file-first", "repl-first", "self-mutating", "unknown"];
15
+ export type HostContentSurfaceClass = (typeof HOST_CONTENT_SURFACE_CLASSES)[number];
16
+ /** Env key for explicit class override (capability descriptor pointer). */
17
+ export declare const ENV_HOST_CONTENT_SURFACE = "DEFT_HOST_CONTENT_SURFACE";
18
+ /** Env opt-in: host holds executable work product before files exist. */
19
+ export declare const ENV_HOST_REPL_FIRST = "DEFT_HOST_REPL_FIRST";
20
+ /** Env opt-in: host refine/kernel may CRUD skills/prompts mid-run. */
21
+ export declare const ENV_HOST_SELF_MUTATE = "DEFT_HOST_SELF_MUTATE";
22
+ export interface HostContentSurfaceClassResult {
23
+ readonly contentClass: HostContentSurfaceClass;
24
+ readonly source: string;
25
+ /** Signals observed (env keys present). */
26
+ readonly signals: readonly string[];
27
+ }
28
+ export type ManagedSectionDriftState = "current" | "stale" | "missing" | "absent" | "unreadable" | "template-missing" | "template-malformed" | "unknown";
29
+ export interface ManagedSectionDriftReport {
30
+ readonly state: ManagedSectionDriftState;
31
+ readonly embeddedSha: string | null;
32
+ /** SHA-256 (12 hex) of stripped managed-section body when readable. */
33
+ readonly bodyHash: string | null;
34
+ readonly path: string;
35
+ }
36
+ export interface HostContentSurfaceReport {
37
+ readonly contentClass: HostContentSurfaceClass;
38
+ readonly classSource: string;
39
+ readonly signals: readonly string[];
40
+ readonly managedSection: ManagedSectionDriftReport;
41
+ /** Runtime mode from platform capability descriptor when provided. */
42
+ readonly runtimeMode: string | null;
43
+ }
44
+ export interface HostContentSurfaceSeams {
45
+ readonly environ?: Readonly<Record<string, string | undefined>>;
46
+ readonly agentsMdSeams?: AgentsMdSeams;
47
+ readonly runtimeMode?: string | null;
48
+ }
49
+ /**
50
+ * Classify host content surface from explicit env / capability signals (#1461/#1357 pointer).
51
+ * Defaults to file-first (historical Directive assumption) when no signal is set.
52
+ */
53
+ export declare function classifyHostContentSurface(environ?: Readonly<Record<string, string | undefined>>): HostContentSurfaceClassResult;
54
+ /**
55
+ * Probe managed AGENTS.md section drift (tamper-evident boundary, not full #830 pins).
56
+ * Uses agents:refresh plan state + embedded marker sha + body hash.
57
+ */
58
+ export declare function probeManagedSectionDrift(projectRoot: string, seams?: HostContentSurfaceSeams): ManagedSectionDriftReport;
59
+ /** Full host-surface report for session-start payload + lines. */
60
+ export declare function probeHostContentSurface(projectRoot: string, seams?: HostContentSurfaceSeams): HostContentSurfaceReport;
61
+ export declare function hostContentSurfaceToDict(report: HostContentSurfaceReport): Record<string, unknown>;
62
+ /**
63
+ * Format operator-facing host-surface lines (#3162).
64
+ * Always emits one summary line; adds honesty note for non-file-first or drift.
65
+ */
66
+ export declare function formatHostContentSurfaceLines(report: HostContentSurfaceReport): string[];
67
+ /**
68
+ * Probe + format; fail-open for session-start (never throws to callers that wrap).
69
+ */
70
+ export declare function maybeFormatHostContentSurfaceLines(projectRoot: string, seams?: HostContentSurfaceSeams): {
71
+ report: HostContentSurfaceReport;
72
+ lines: string[];
73
+ };
74
+ //# sourceMappingURL=host-content-surface.d.ts.map