@isaacriehm/cairn-core 0.22.5 → 0.22.6

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 (94) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/attention/index.d.ts +0 -1
  3. package/dist/attention/index.js +0 -1
  4. package/dist/attention/index.js.map +1 -1
  5. package/dist/doctor/index.js +1 -86
  6. package/dist/doctor/index.js.map +1 -1
  7. package/dist/gc/apply.d.ts +1 -1
  8. package/dist/gc/apply.js +1 -1
  9. package/dist/gc/classify.d.ts +4 -8
  10. package/dist/gc/classify.js +6 -12
  11. package/dist/gc/classify.js.map +1 -1
  12. package/dist/gc/index.d.ts +1 -1
  13. package/dist/gc/index.js +1 -1
  14. package/dist/gc/sweep.d.ts +1 -3
  15. package/dist/gc/sweep.js +2 -7
  16. package/dist/gc/sweep.js.map +1 -1
  17. package/dist/gc/types.d.ts +5 -6
  18. package/dist/gc/types.js +4 -5
  19. package/dist/gc/types.js.map +1 -1
  20. package/dist/init/baseline-audit.js +3 -16
  21. package/dist/init/baseline-audit.js.map +1 -1
  22. package/dist/init/index.d.ts +0 -2
  23. package/dist/init/index.js +0 -1
  24. package/dist/init/index.js.map +1 -1
  25. package/dist/init/init.d.ts +2 -2
  26. package/dist/init/init.js +12 -27
  27. package/dist/init/init.js.map +1 -1
  28. package/dist/init/mapper-merge.d.ts +1 -4
  29. package/dist/init/mapper-merge.js +6 -22
  30. package/dist/init/mapper-merge.js.map +1 -1
  31. package/dist/init/mapper-parallel.d.ts +0 -4
  32. package/dist/init/mapper-parallel.js +3 -69
  33. package/dist/init/mapper-parallel.js.map +1 -1
  34. package/dist/init/mapper-prompts.d.ts +1 -25
  35. package/dist/init/mapper-prompts.js +2 -20
  36. package/dist/init/mapper-prompts.js.map +1 -1
  37. package/dist/init/mapper.d.ts +0 -4
  38. package/dist/init/mapper.js +2 -9
  39. package/dist/init/mapper.js.map +1 -1
  40. package/dist/init/overlay.js +6 -8
  41. package/dist/init/overlay.js.map +1 -1
  42. package/dist/init/phases/11-baseline.js +0 -10
  43. package/dist/init/phases/11-baseline.js.map +1 -1
  44. package/dist/init/phases/4-seed.js +0 -4
  45. package/dist/init/phases/4-seed.js.map +1 -1
  46. package/dist/init/source-comments/ingest.d.ts +0 -8
  47. package/dist/init/source-comments/ingest.js.map +1 -1
  48. package/dist/init/walker.d.ts +2 -3
  49. package/dist/init/walker.js +2 -3
  50. package/dist/init/walker.js.map +1 -1
  51. package/dist/init/workflow-block.d.ts +0 -4
  52. package/dist/init/workflow-block.js +0 -16
  53. package/dist/init/workflow-block.js.map +1 -1
  54. package/dist/mcp/schemas.d.ts +8 -8
  55. package/dist/mcp/tools/mission-set-exit-gate.d.ts +1 -1
  56. package/dist/migrate/migrations/0004-drop-glob-settings.d.ts +16 -0
  57. package/dist/migrate/migrations/0004-drop-glob-settings.js +34 -0
  58. package/dist/migrate/migrations/0004-drop-glob-settings.js.map +1 -0
  59. package/dist/migrate/registry.js +2 -0
  60. package/dist/migrate/registry.js.map +1 -1
  61. package/dist/profiles/types.d.ts +0 -2
  62. package/dist/profiles/unknown.d.ts +2 -2
  63. package/dist/profiles/unknown.js +2 -3
  64. package/dist/profiles/unknown.js.map +1 -1
  65. package/dist/sensors/diff.d.ts +1 -1
  66. package/dist/sensors/diff.js +1 -1
  67. package/dist/sensors/index.d.ts +2 -3
  68. package/dist/sensors/index.js +1 -2
  69. package/dist/sensors/index.js.map +1 -1
  70. package/dist/sensors/runner.d.ts +7 -10
  71. package/dist/sensors/runner.js +6 -39
  72. package/dist/sensors/runner.js.map +1 -1
  73. package/dist/sensors/types.d.ts +0 -13
  74. package/package.json +2 -2
  75. package/templates/.cairn/config/sensors.yaml +3 -89
  76. package/templates/.cairn/config/workflow.md +2 -5
  77. package/dist/attention/scoring.d.ts +0 -47
  78. package/dist/attention/scoring.js +0 -87
  79. package/dist/attention/scoring.js.map +0 -1
  80. package/dist/hooks/read-enrich.d.ts +0 -6
  81. package/dist/hooks/read-enrich.js +0 -11
  82. package/dist/hooks/read-enrich.js.map +0 -1
  83. package/dist/hooks/write-guard.d.ts +0 -6
  84. package/dist/hooks/write-guard.js +0 -11
  85. package/dist/hooks/write-guard.js.map +0 -1
  86. package/dist/init/glob-inference.d.ts +0 -16
  87. package/dist/init/glob-inference.js +0 -132
  88. package/dist/init/glob-inference.js.map +0 -1
  89. package/dist/init/phases/12-strip.d.ts +0 -10
  90. package/dist/init/phases/12-strip.js +0 -88
  91. package/dist/init/phases/12-strip.js.map +0 -1
  92. package/dist/sensors/structural.d.ts +0 -31
  93. package/dist/sensors/structural.js +0 -196
  94. package/dist/sensors/structural.js.map +0 -1
@@ -11,8 +11,8 @@ export declare const invariantGetInput: {
11
11
  export declare const inScopeInput: {
12
12
  path_globs: z.ZodArray<z.ZodString>;
13
13
  types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
14
- invariant: "invariant";
15
14
  decision: "decision";
15
+ invariant: "invariant";
16
16
  }>>>;
17
17
  status: z.ZodOptional<z.ZodArray<z.ZodString>>;
18
18
  };
@@ -50,11 +50,11 @@ export declare const searchInput: {
50
50
  query: z.ZodString;
51
51
  scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
52
  kinds: z.ZodOptional<z.ZodArray<z.ZodEnum<{
53
- invariant: "invariant";
54
53
  decision: "decision";
54
+ invariant: "invariant";
55
+ doc: "doc";
55
56
  task: "task";
56
57
  run: "run";
57
- doc: "doc";
58
58
  manifest: "manifest";
59
59
  }>>>;
60
60
  limit: z.ZodOptional<z.ZodNumber>;
@@ -109,9 +109,9 @@ export declare const resumeInput: {
109
109
  export declare const taskCompleteInput: {
110
110
  task_id: z.ZodOptional<z.ZodString>;
111
111
  outcome: z.ZodEnum<{
112
- aborted: "aborted";
113
112
  succeeded: "succeeded";
114
113
  failed: "failed";
114
+ aborted: "aborted";
115
115
  }>;
116
116
  summary: z.ZodOptional<z.ZodString>;
117
117
  };
@@ -177,9 +177,9 @@ export declare const resolveAttentionInput: {
177
177
  * kinds reject `d`.
178
178
  */
179
179
  choice: z.ZodEnum<{
180
- c: "c";
181
180
  d: "d";
182
181
  a: "a";
182
+ c: "c";
183
183
  b: "b";
184
184
  }>;
185
185
  /**
@@ -208,12 +208,12 @@ export declare const resolveAttentionInput: {
208
208
  * d=none-of-these (drop pending, leave source untouched).
209
209
  */
210
210
  kind: z.ZodEnum<{
211
+ bypass: "bypass";
212
+ review: "review";
211
213
  decision_draft: "decision_draft";
212
214
  baseline_finding: "baseline_finding";
213
215
  invalidation_event: "invalidation_event";
214
216
  drift: "drift";
215
- bypass: "bypass";
216
- review: "review";
217
217
  conflict: "conflict";
218
218
  alignment_pending: "alignment_pending";
219
219
  }>;
@@ -311,10 +311,10 @@ export declare const missionPlanPhaseInput: {
311
311
  export declare const missionAdvanceInput: {
312
312
  phase_id: z.ZodString;
313
313
  choice: z.ZodEnum<{
314
+ force: "force";
314
315
  exit: "exit";
315
316
  not_yet: "not_yet";
316
317
  defer: "defer";
317
- force: "force";
318
318
  drop: "drop";
319
319
  }>;
320
320
  defer_hours: z.ZodOptional<z.ZodNumber>;
@@ -21,8 +21,8 @@ import { z } from "zod";
21
21
  import type { ToolDef } from "./types.js";
22
22
  export declare const missionSetExitGateInput: {
23
23
  exit_gate: z.ZodEnum<{
24
- auto: "auto";
25
24
  prompt: "prompt";
25
+ auto: "auto";
26
26
  manual: "manual";
27
27
  }>;
28
28
  mission_id: z.ZodOptional<z.ZodString>;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 0004 — drop the glob-driven sensor settings.
3
+ *
4
+ * The Layer C structural sensors (route-handler / DTO) and the high-stakes GC
5
+ * tier were removed: stack-specific regex fed by LLM-guessed globs that were
6
+ * never validated against the tree or refreshed after adoption, so they failed
7
+ * silent and never fired. Their config surface — the whole `project_globs`
8
+ * block and the legacy top-level `high_stakes_globs` key — now has no runtime
9
+ * reader. Stripping it is value-preserving (`off_limits` and everything else
10
+ * stay), so this is a `safe` migration. New adoptions stop emitting these keys
11
+ * at the source (init/overlay.ts).
12
+ */
13
+ import type { Migration } from "../types.js";
14
+ /** Defunct top-level config keys with no runtime consumer. */
15
+ export declare const DEAD_GLOB_KEYS: readonly ["project_globs", "high_stakes_globs"];
16
+ export declare const dropGlobSettings: Migration;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * 0004 — drop the glob-driven sensor settings.
3
+ *
4
+ * The Layer C structural sensors (route-handler / DTO) and the high-stakes GC
5
+ * tier were removed: stack-specific regex fed by LLM-guessed globs that were
6
+ * never validated against the tree or refreshed after adoption, so they failed
7
+ * silent and never fired. Their config surface — the whole `project_globs`
8
+ * block and the legacy top-level `high_stakes_globs` key — now has no runtime
9
+ * reader. Stripping it is value-preserving (`off_limits` and everything else
10
+ * stay), so this is a `safe` migration. New adoptions stop emitting these keys
11
+ * at the source (init/overlay.ts).
12
+ */
13
+ import { configHasKeys, deleteConfigKeys } from "../config-io.js";
14
+ /** Defunct top-level config keys with no runtime consumer. */
15
+ export const DEAD_GLOB_KEYS = ["project_globs", "high_stakes_globs"];
16
+ export const dropGlobSettings = {
17
+ id: "0004-drop-glob-settings",
18
+ introducedIn: "0.22.6",
19
+ describe: "Remove the defunct glob-driven sensor settings (project_globs, high_stakes_globs) — the Layer C structural sensors + high-stakes GC tier were removed",
20
+ class: "safe",
21
+ detect(repoRoot, doc) {
22
+ return configHasKeys(repoRoot, DEAD_GLOB_KEYS, doc).length > 0;
23
+ },
24
+ apply(repoRoot) {
25
+ const removed = deleteConfigKeys(repoRoot, DEAD_GLOB_KEYS);
26
+ return {
27
+ changed: removed.length > 0,
28
+ detail: removed.length > 0
29
+ ? `removed ${removed.length} defunct glob key(s): ${removed.join(", ")}`
30
+ : "no glob settings present",
31
+ };
32
+ },
33
+ };
34
+ //# sourceMappingURL=0004-drop-glob-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0004-drop-glob-settings.js","sourceRoot":"","sources":["../../../src/migrate/migrations/0004-drop-glob-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAElE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,eAAe,EAAE,mBAAmB,CAAU,CAAC;AAE9E,MAAM,CAAC,MAAM,gBAAgB,GAAc;IACzC,EAAE,EAAE,yBAAyB;IAC7B,YAAY,EAAE,QAAQ;IACtB,QAAQ,EACN,uJAAuJ;IACzJ,KAAK,EAAE,MAAM;IACb,MAAM,CAAC,QAAgB,EAAE,GAAsB;QAC7C,OAAO,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACjE,CAAC;IACD,KAAK,CAAC,QAAgB;QACpB,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC3D,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC;YAC3B,MAAM,EACJ,OAAO,CAAC,MAAM,GAAG,CAAC;gBAChB,CAAC,CAAC,WAAW,OAAO,CAAC,MAAM,yBAAyB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACxE,CAAC,CAAC,0BAA0B;SACjC,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -8,9 +8,11 @@
8
8
  import { dropDeadConfigFields } from "./migrations/0001-drop-dead-config-fields.js";
9
9
  import { backfillGitignore } from "./migrations/0002-backfill-gitignore.js";
10
10
  import { pruneScaffolding } from "./migrations/0003-prune-scaffolding.js";
11
+ import { dropGlobSettings } from "./migrations/0004-drop-glob-settings.js";
11
12
  export const MIGRATIONS = [
12
13
  dropDeadConfigFields,
13
14
  backfillGitignore,
14
15
  pruneScaffolding,
16
+ dropGlobSettings,
15
17
  ];
16
18
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/migrate/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAE1E,MAAM,CAAC,MAAM,UAAU,GAAyB;IAC9C,oBAAoB;IACpB,iBAAiB;IACjB,gBAAgB;CACjB,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/migrate/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAE3E,MAAM,CAAC,MAAM,UAAU,GAAyB;IAC9C,oBAAoB;IACpB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;CACjB,CAAC"}
@@ -41,8 +41,6 @@ export interface Profile {
41
41
  extractors: ProfileExtractor[];
42
42
  /** Suggested off-limits paths on adoption. */
43
43
  offLimitsDefaults: string[];
44
- /** Suggested high-stakes globs on adoption. */
45
- highStakesDefaults: string[];
46
44
  /** Suggested start command for the project (e.g., `pnpm dev`). */
47
45
  startCommand?: string;
48
46
  }
@@ -3,7 +3,7 @@ import type { Profile } from "./types.js";
3
3
  * Fallback profile — applies when no other profile detects.
4
4
  *
5
5
  * Carries no extractors and no stack-specific sensors. The cairn still
6
- * runs every generic sensor (Layer A/B/C/D/E/U + decision-assertions +
7
- * invariant-suite) defined in templates/.cairn/config/sensors.yaml.
6
+ * runs the generic sensors (Layer A stub catalog + decision-assertions)
7
+ * defined in templates/.cairn/config/sensors.yaml.
8
8
  */
9
9
  export declare const unknownProfile: Profile;
@@ -2,8 +2,8 @@
2
2
  * Fallback profile — applies when no other profile detects.
3
3
  *
4
4
  * Carries no extractors and no stack-specific sensors. The cairn still
5
- * runs every generic sensor (Layer A/B/C/D/E/U + decision-assertions +
6
- * invariant-suite) defined in templates/.cairn/config/sensors.yaml.
5
+ * runs the generic sensors (Layer A stub catalog + decision-assertions)
6
+ * defined in templates/.cairn/config/sensors.yaml.
7
7
  */
8
8
  export const unknownProfile = {
9
9
  id: "unknown",
@@ -12,6 +12,5 @@ export const unknownProfile = {
12
12
  sensors: [],
13
13
  extractors: [],
14
14
  offLimitsDefaults: [".git/**", ".archive/**", "node_modules/**", ".env", ".env.local"],
15
- highStakesDefaults: [],
16
15
  };
17
16
  //# sourceMappingURL=unknown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"unknown.js","sourceRoot":"","sources":["../../src/profiles/unknown.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAY;IACrC,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,mBAAmB;IACzB,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI;IAClB,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,EAAE;IACd,iBAAiB,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,CAAC;IACtF,kBAAkB,EAAE,EAAE;CACvB,CAAC"}
1
+ {"version":3,"file":"unknown.js","sourceRoot":"","sources":["../../src/profiles/unknown.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAY;IACrC,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,mBAAmB;IACzB,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI;IAClB,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,EAAE;IACd,iBAAiB,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,CAAC;CACvF,CAAC"}
@@ -34,6 +34,6 @@ export declare function getRangeDiff(repoRoot: string, range: string): Promise<D
34
34
  export declare function diffHasGlobMatch(diff: DiffEntry[], globs: readonly string[], matcher: (path: string, glob: string) => boolean): boolean;
35
35
  /**
36
36
  * Filter a diff to entries whose path matches any of the supplied globs.
37
- * Useful for layered sensors that scope to e.g. route_handler_globs.
37
+ * Useful for any check that scopes to a glob set (e.g. a decision's scope_globs).
38
38
  */
39
39
  export declare function filterDiffByGlobs(diff: DiffEntry[], globs: readonly string[], matcher: (path: string, glob: string) => boolean): DiffEntry[];
@@ -267,7 +267,7 @@ export function diffHasGlobMatch(diff, globs, matcher) {
267
267
  }
268
268
  /**
269
269
  * Filter a diff to entries whose path matches any of the supplied globs.
270
- * Useful for layered sensors that scope to e.g. route_handler_globs.
270
+ * Useful for any check that scopes to a glob set (e.g. a decision's scope_globs).
271
271
  */
272
272
  export function filterDiffByGlobs(diff, globs, matcher) {
273
273
  return diff.filter((d) => globs.some((g) => matcher(d.path, g)));
@@ -1,12 +1,11 @@
1
- export type { DiffEntry, ProjectGlobs, SensorFinding, SensorLanguage, SensorResult, SensorSweepResult, StubCatalog, StubPattern, } from "./types.js";
1
+ export type { DiffEntry, SensorFinding, SensorLanguage, SensorResult, SensorSweepResult, StubCatalog, StubPattern, } from "./types.js";
2
2
  export { getDiff, getStagedDiff, getRangeDiff, diffHasGlobMatch, filterDiffByGlobs, } from "./diff.js";
3
3
  export { loadStubCatalog, parseStubCatalog, loadSensorRegistry } from "./catalog.js";
4
4
  export type { SensorRegistry, SensorRegistryEntry } from "./catalog.js";
5
5
  export { detectStubMatches, runStubCatalog, detectLanguage } from "./stub-catalog.js";
6
6
  export type { StubMatch } from "./stub-catalog.js";
7
- export { runRouteHandlerNonEmpty, runDtoNoFakeFields, } from "./structural.js";
8
7
  export { loadAcceptedDecisions, decisionsInScope, listMirrorFiles, runDecisionAssertions, } from "./decisions.js";
9
8
  export { formatRemediation } from "./remediation.js";
10
9
  export type { RemediationOptions } from "./remediation.js";
11
- export { runSensorsOnDiff, loadProjectGlobs } from "./runner.js";
10
+ export { runSensorsOnDiff } from "./runner.js";
12
11
  export type { RunSensorsOnDiffArgs } from "./runner.js";
@@ -1,8 +1,7 @@
1
1
  export { getDiff, getStagedDiff, getRangeDiff, diffHasGlobMatch, filterDiffByGlobs, } from "./diff.js";
2
2
  export { loadStubCatalog, parseStubCatalog, loadSensorRegistry } from "./catalog.js";
3
3
  export { detectStubMatches, runStubCatalog, detectLanguage } from "./stub-catalog.js";
4
- export { runRouteHandlerNonEmpty, runDtoNoFakeFields, } from "./structural.js";
5
4
  export { loadAcceptedDecisions, decisionsInScope, listMirrorFiles, runDecisionAssertions, } from "./decisions.js";
6
5
  export { formatRemediation } from "./remediation.js";
7
- export { runSensorsOnDiff, loadProjectGlobs } from "./runner.js";
6
+ export { runSensorsOnDiff } from "./runner.js";
8
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sensors/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,OAAO,EACP,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEtF,OAAO,EACL,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sensors/index.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,OAAO,EACP,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEtF,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -3,19 +3,20 @@
3
3
  *
4
4
  * Composes the sensors that actually have teeth into one diff-scoped sweep:
5
5
  * - Layer A — stub-pattern catalog (mechanical debt regex)
6
- * - Layer C — generic structural sensors (route handlers, DTOs)
7
6
  * - decision-assertions — "was the in-scope DEC honored?"
8
7
  *
9
8
  * Runs at the real gates: pre-commit (staged diff), CI (`--diff` range), and
10
9
  * advisory at the Stop hook (working-tree diff). The diff + repoRoot are the
11
10
  * only inputs — there is no mirror checkout or orchestrator runtime.
12
11
  *
13
- * Layer-B attestation cross-check was removed: it depended on an
14
- * agent-emitted attestation block that no production path produced, so it
15
- * never ran. Project-specific "proposed sensors" were likewise never wired
16
- * to an executor and have been dropped.
12
+ * Two theatre layers have been removed. (1) Layer-B attestation cross-check:
13
+ * depended on an agent-emitted attestation block no production path produced.
14
+ * (2) The Layer C structural sensors (route-handler / DTO) + their
15
+ * `project_globs` targeting: stack-specific regex fed by LLM-guessed globs that
16
+ * were never validated or refreshed, so they failed silent and never fired.
17
+ * Both are gone; the spine (Layer A + decision-assertions) is glob-independent.
17
18
  */
18
- import type { DiffEntry, ProjectGlobs, SensorLanguage, SensorSweepResult } from "./types.js";
19
+ import type { DiffEntry, SensorLanguage, SensorSweepResult } from "./types.js";
19
20
  export interface RunSensorsOnDiffArgs {
20
21
  /** Repo root — decisions, stub catalog, and config are read from here. */
21
22
  repoRoot: string;
@@ -23,8 +24,6 @@ export interface RunSensorsOnDiffArgs {
23
24
  diff: DiffEntry[];
24
25
  /** Languages to filter Layer A patterns. Omit = scan all known languages. */
25
26
  languages?: SensorLanguage[];
26
- /** Route/DTO globs. Omit = loaded from `.cairn/config.yaml`. */
27
- projectGlobs?: ProjectGlobs;
28
27
  /** Label for log lines (e.g. the gate name). */
29
28
  runId?: string;
30
29
  /** Retry context for the remediation prompt. Defaults to a single 1/1 pass. */
@@ -37,5 +36,3 @@ export interface RunSensorsOnDiffArgs {
37
36
  * the caller can surface to the agent.
38
37
  */
39
38
  export declare function runSensorsOnDiff(args: RunSensorsOnDiffArgs): Promise<SensorSweepResult>;
40
- /** Read route/DTO/high-stakes globs from `.cairn/config.yaml`. */
41
- export declare function loadProjectGlobs(repoRoot: string): ProjectGlobs;
@@ -3,25 +3,24 @@
3
3
  *
4
4
  * Composes the sensors that actually have teeth into one diff-scoped sweep:
5
5
  * - Layer A — stub-pattern catalog (mechanical debt regex)
6
- * - Layer C — generic structural sensors (route handlers, DTOs)
7
6
  * - decision-assertions — "was the in-scope DEC honored?"
8
7
  *
9
8
  * Runs at the real gates: pre-commit (staged diff), CI (`--diff` range), and
10
9
  * advisory at the Stop hook (working-tree diff). The diff + repoRoot are the
11
10
  * only inputs — there is no mirror checkout or orchestrator runtime.
12
11
  *
13
- * Layer-B attestation cross-check was removed: it depended on an
14
- * agent-emitted attestation block that no production path produced, so it
15
- * never ran. Project-specific "proposed sensors" were likewise never wired
16
- * to an executor and have been dropped.
12
+ * Two theatre layers have been removed. (1) Layer-B attestation cross-check:
13
+ * depended on an agent-emitted attestation block no production path produced.
14
+ * (2) The Layer C structural sensors (route-handler / DTO) + their
15
+ * `project_globs` targeting: stack-specific regex fed by LLM-guessed globs that
16
+ * were never validated or refreshed, so they failed silent and never fired.
17
+ * Both are gone; the spine (Layer A + decision-assertions) is glob-independent.
17
18
  */
18
19
  import { logger } from "../logger.js";
19
- import { loadCairnConfig } from "@isaacriehm/cairn-state";
20
20
  import { decisionsInScope, loadAcceptedDecisions, runDecisionAssertions, } from "./decisions.js";
21
21
  import { loadStubCatalog } from "./catalog.js";
22
22
  import { formatRemediation } from "./remediation.js";
23
23
  import { runStubCatalog } from "./stub-catalog.js";
24
- import { runDtoNoFakeFields, runRouteHandlerNonEmpty } from "./structural.js";
25
24
  const log = logger("sensors.runner");
26
25
  /**
27
26
  * Run the live sensor sweep over a diff. Returns per-sensor results, the
@@ -31,16 +30,12 @@ const log = logger("sensors.runner");
31
30
  export async function runSensorsOnDiff(args) {
32
31
  const startedAt = Date.now();
33
32
  const { repoRoot, diff } = args;
34
- const projectGlobs = args.projectGlobs ?? loadProjectGlobs(repoRoot);
35
33
  const stubCatalog = loadStubCatalog(repoRoot);
36
34
  const acceptedDecisions = loadAcceptedDecisions(repoRoot);
37
35
  const inScope = decisionsInScope(acceptedDecisions, diff);
38
36
  const results = [
39
37
  // Layer A — stub-pattern catalog.
40
38
  runStubCatalog({ diff, catalog: stubCatalog, languages: args.languages }),
41
- // Layer C — generic structural sensors.
42
- runRouteHandlerNonEmpty({ diff, globs: projectGlobs.route_handler_globs }),
43
- runDtoNoFakeFields({ diff, globs: projectGlobs.dto_globs }),
44
39
  // Decision-assertions — the core value prop.
45
40
  runDecisionAssertions({ mirrorPath: repoRoot, diff, decisions: inScope }),
46
41
  ];
@@ -74,32 +69,4 @@ export async function runSensorsOnDiff(args) {
74
69
  duration_ms: Date.now() - startedAt,
75
70
  };
76
71
  }
77
- /** Read route/DTO/high-stakes globs from `.cairn/config.yaml`. */
78
- export function loadProjectGlobs(repoRoot) {
79
- const cfg = loadCairnConfig(repoRoot);
80
- const out = {};
81
- const asStrings = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : undefined;
82
- const pg = cfg["project_globs"];
83
- if (typeof pg === "object" && pg !== null) {
84
- const p = pg;
85
- const rh = asStrings(p["route_handler_globs"]);
86
- if (rh)
87
- out.route_handler_globs = rh;
88
- const dto = asStrings(p["dto_globs"]);
89
- if (dto)
90
- out.dto_globs = dto;
91
- const gen = asStrings(p["generator_source_globs"]);
92
- if (gen)
93
- out.generator_source_globs = gen;
94
- const hs = asStrings(p["high_stakes_globs"]);
95
- if (hs)
96
- out.high_stakes_globs = hs;
97
- }
98
- if (out.high_stakes_globs === undefined) {
99
- const topHs = asStrings(cfg["high_stakes_globs"]);
100
- if (topHs)
101
- out.high_stakes_globs = topHs;
102
- }
103
- return out;
104
- }
105
72
  //# sourceMappingURL=runner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/sensors/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/sensors/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQnD,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAgBrC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAA0B;IAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAChC,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAE1D,MAAM,OAAO,GAAmB;QAC9B,kCAAkC;QAClC,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACzE,6CAA6C;QAC7C,qBAAqB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;KAC1E,CAAC;IAEF,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;IAC1D,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,EACpE,CAAC,CACF,CAAC;IACF,MAAM,EAAE,GAAG,aAAa,KAAK,CAAC,CAAC;IAC/B,MAAM,kBAAkB,GAAG,EAAE;QAC3B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC;YAC1B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;SACnC,CAAC,CAAC;IAEP,GAAG,CAAC,IAAI,CACN;QACE,MAAM,EAAE,IAAI,CAAC,KAAK,IAAI,cAAc;QACpC,EAAE;QACF,aAAa;QACb,aAAa;QACb,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,EAAE,EAAE,CAAC,CAAC,SAAS;YACf,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM;YAC3B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM;SAC3B,CAAC,CAAC;KACJ,EACD,uBAAuB,CACxB,CAAC;IAEF,OAAO;QACL,EAAE;QACF,aAAa;QACb,aAAa;QACb,OAAO;QACP,kBAAkB;QAClB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;KACpC,CAAC;AACJ,CAAC"}
@@ -56,19 +56,6 @@ export interface StubCatalog {
56
56
  version: number;
57
57
  patterns: StubPattern[];
58
58
  }
59
- /**
60
- * Project-extension block resolved from workflow.md `<project>:` extension.
61
- * Sensors that trigger on `glob_keys` look up the matching key here.
62
- */
63
- export interface ProjectGlobs {
64
- route_handler_globs?: string[];
65
- dto_globs?: string[];
66
- generator_source_globs?: string[];
67
- high_stakes_globs?: string[];
68
- /** Off-limits — file_must_not_be_modified assertions also enforce these. */
69
- off_limits?: string[];
70
- [key: string]: string[] | undefined;
71
- }
72
59
  export interface SensorFinding {
73
60
  /** id from sensors.yaml — e.g., "stub-pattern-catalog". */
74
61
  sensor_id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isaacriehm/cairn-core",
3
- "version": "0.22.5",
3
+ "version": "0.22.6",
4
4
  "description": "Cairn core — state + context layer. Curated `.cairn/ground/` (decisions, §INV invariants, canonical-map, brand, quality-grades), MCP server, init wizard, hook runners, sensors, GC drift sweep.",
5
5
  "author": "Isaac Riehm",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "simple-git": "^3.36.0",
40
40
  "yaml": "^2.9.0",
41
41
  "zod": "^4.4.3",
42
- "@isaacriehm/cairn-state": "0.22.5"
42
+ "@isaacriehm/cairn-state": "0.22.6"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/cli-progress": "^3.11.6",
@@ -27,48 +27,6 @@ sensors:
27
27
  - every_run
28
28
  fail_severity: hard
29
29
 
30
- # ── Layer B — attestation cross-check ─────────────────────────────────────
31
- - id: attestation-cross-check
32
- layer: B
33
- kind: attestation
34
- description: "Cross-checks agent's attestation.yaml against the actual diff. Mismatches (lying about completeness, files-touched count, todos/stubs introduced) fail the run."
35
- triggers:
36
- - every_run_completion
37
- fail_severity: hard
38
-
39
- # ── Layer C — project structural / contract sensors ──────────────────────
40
- - id: route-handler-non-empty
41
- layer: C
42
- kind: structural
43
- description: "For every route/controller method, body must contain non-trivial implementation (not just `return null` / empty / throw not-implemented)."
44
- triggers:
45
- - diff_touches_glob
46
- glob_keys:
47
- - route_handler_globs
48
- fail_severity: hard
49
-
50
- - id: dto-no-fake-fields
51
- layer: C
52
- kind: structural
53
- description: "DTO/schema fields that are declared optional and always evaluate undefined fail this sensor — they look thorough without doing work."
54
- triggers:
55
- - diff_touches_glob
56
- glob_keys:
57
- - dto_globs
58
- fail_severity: hard
59
-
60
- # ── Generator-drift sensors (profile-driven) ──────────────────────────────
61
- - id: generator-drift
62
- layer: D
63
- kind: generator_drift
64
- description: "Re-runs the project's declared generator commands (e.g. openapi:generate, db:generate, sqlc generate, alembic check). Any non-empty diff = source out of sync with artifact."
65
- triggers:
66
- - diff_touches_glob
67
- glob_keys:
68
- - generator_source_globs
69
- profile_hook: profile.generators
70
- fail_severity: hard
71
-
72
30
  # ── Decision-assertion sensor ─────────────────────────────────────────────
73
31
  - id: decision-assertions
74
32
  layer: decisions
@@ -89,37 +47,6 @@ sensors:
89
47
  - .cairn/ground/invariants/
90
48
  fail_severity: hard
91
49
 
92
- # ── Reviewer subagent (SessionStart Drain) ───────────────────────────────────────────
93
- - id: reviewer-subagent
94
- layer: D
95
- kind: inferential
96
- description: "Same model as implementer; fresh context. Reads only spec.tightened.md + diff + decisions ledger + in-scope assertions. Anti-completionist framing. For high-stakes runs, also enforces query-scope completeness."
97
- model_strategy: same_as_implementer
98
- triggers:
99
- - all_layer_c_sensors_passed
100
- fail_severity: soft
101
-
102
- # ── Layer E — high-stakes E2E / demo ─────────────────────────────────────
103
- - id: e2e-real-db
104
- layer: E
105
- kind: e2e
106
- description: "Runs the project's E2E suite against a real database (no mocks). High-stakes UAT MUST include a cross-tenant negative fixture — a request from user/org B against a resource owned by user/org A returning the expected denial."
107
- triggers:
108
- - high_stakes_glob_match
109
- profile_hook: profile.e2e_command
110
- fail_severity: hard
111
- requires:
112
- cross_tenant_fixture: true
113
-
114
- # ── Layer U — UAT headless ───────────────────────────────────────────────
115
- - id: uat-headless-chrome
116
- layer: U
117
- kind: uat
118
- description: "Headless Chrome via Playwright captures GIF + screenshots + console + network. Evidence-file gate: .uat-passed contains SHA256 of bundle. Bare touch rejected."
119
- triggers:
120
- - code_class_or_high_stakes
121
- fail_severity: hard
122
-
123
50
  # ── Frontmatter freshness (nightly GC pass) ──────────────────────────────
124
51
  - id: frontmatter-freshness
125
52
  layer: gc
@@ -140,23 +67,10 @@ sensors:
140
67
  fail_severity: soft
141
68
 
142
69
  # ──────────────────────────────────────────────────────────────────────────────
143
- # Scoped-glob keys.
144
- #
145
- # Each adopting project fills these in its `<project_name>:` block. Sensors that
146
- # trigger on `glob_keys` resolve them at dispatch from the project block.
147
- # ──────────────────────────────────────────────────────────────────────────────
148
-
149
- required_glob_keys:
150
- - route_handler_globs # e.g. core/src/**/*.controller.ts (NestJS) | app/controllers/**/*.rb (Rails)
151
- - dto_globs # e.g. core/src/**/*.dto.ts | apps/api/schemas/**/*.py
152
- - generator_source_globs # files that, when changed, mean the generator should re-run
153
- - high_stakes_globs # paths whose changes require Layer E + cross-tenant fixture
154
-
155
- # ──────────────────────────────────────────────────────────────────────────────
156
- # Copy-safety configuration (write guardian + Layer C sensor)
70
+ # Copy-safety configuration (write guardian + copy scanner)
157
71
  #
158
- # The write guardian (PostToolUse hook on Write/Edit) and the Layer C
159
- # copy-safety sensor both consume this block. Globs default to common frontend
72
+ # The write guardian and the copy scanner (both PostToolUse hooks on
73
+ # Write/Edit) consume this block. Globs default to common frontend
160
74
  # file extensions; extend per-project as needed. allowlist holds verbatim
161
75
  # strings that match a pattern but are intentional (technical error codes,
162
76
  # product names, etc.).
@@ -26,19 +26,16 @@ source-commits:
26
26
  - .env.local
27
27
  - node_modules/**
28
28
  # adopting project extends with its own off-limits paths at init
29
- high_stakes_globs: [] # populated at init from stack-profile heuristic + operator confirm
30
29
  trust_posture:
31
30
  safe_class_auto_merge: true
32
31
  code_class_auto_merge: false
33
- high_stakes_auto_merge: false
34
32
 
35
33
  ---
36
34
 
37
35
  # Workflow policy
38
36
 
39
- This file is the on-disk surface for the **project-extension block** that
40
- `cairn-core/src/sensors/runner.ts` reads (via `Object.keys()` lookup) and
41
- that the Phase-3 init mapper patches with discovered globs and sensors.
37
+ This file carries the **project-extension block** the project's `off_limits`
38
+ denylist and trust posture, seeded at adoption and extended by the operator.
42
39
 
43
40
  The plugin-era cairn does NOT use this file as a per-task prompt template
44
41
  — each task's spec lives at `.cairn/tasks/active/<task_id>/spec.tightened.md`
@@ -1,47 +0,0 @@
1
- /**
2
- * Confidence scoring for source-comment-derived DEC drafts and
3
- * invariant proposals.
4
- *
5
- * Phase 7b emits one DEC draft per "rationale"-class essay comment and
6
- * one invariant per "constraint"-class essay comment. On a busy
7
- * monorepo the classifier easily produces 400+ drafts — no human will
8
- * sort through that interactively, so we score each draft by a small
9
- * set of heuristics and bulk-accept the obvious ones during attention
10
- * drain. Operator triages only the medium / low-confidence remainder.
11
- *
12
- * Heuristic stance:
13
- * - **DEC drafts** are attribution-of-existing-prose. Cost of keeping
14
- * a borderline draft is near zero (queryable rationale metadata).
15
- * Bias accepts upward — score ≥7 → high.
16
- * - **Invariants** become enforcement signals; false positives turn
17
- * into noise during sensor sweeps. Bias accepts downward —
18
- * stricter signal required (modal verb + reason + high-stakes
19
- * location) before high-confidence accept.
20
- *
21
- * Scoring is pure. Inputs are the parsed draft fields; no filesystem.
22
- */
23
- import type { ProjectGlobs } from "../sensors/types.js";
24
- export type DraftConfidence = "high" | "medium" | "low";
25
- export interface DraftScoreInput {
26
- /** Repo-relative path to the source file the draft was extracted from. */
27
- sourceFile: string;
28
- /** Comment prose (markers stripped). */
29
- prose: string;
30
- /** Suggested DEC title or invariant text. */
31
- title: string;
32
- /** Raw block including markers + JSDoc tags. */
33
- rawComment: string;
34
- /** Project globs from `.cairn/config.yaml`. */
35
- globs: ProjectGlobs;
36
- }
37
- /**
38
- * Score a DEC draft. Max 8 / threshold 7→high / 4→medium.
39
- */
40
- export declare function scoreDecDraft(input: DraftScoreInput): DraftConfidence;
41
- /**
42
- * Score an invariant proposal. Max 9 / threshold 7→high / 4→medium.
43
- * Stricter than DEC scoring: requires modal verb + reason + high-stakes
44
- * location for high confidence, since false-positive invariants become
45
- * sensor-sweep noise downstream.
46
- */
47
- export declare function scoreInvariant(input: DraftScoreInput): DraftConfidence;