@isaacriehm/cairn-core 0.22.4 → 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 (83) 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/migrate/migrations/0004-drop-glob-settings.d.ts +16 -0
  55. package/dist/migrate/migrations/0004-drop-glob-settings.js +34 -0
  56. package/dist/migrate/migrations/0004-drop-glob-settings.js.map +1 -0
  57. package/dist/migrate/registry.js +2 -0
  58. package/dist/migrate/registry.js.map +1 -1
  59. package/dist/profiles/types.d.ts +0 -2
  60. package/dist/profiles/unknown.d.ts +2 -2
  61. package/dist/profiles/unknown.js +2 -3
  62. package/dist/profiles/unknown.js.map +1 -1
  63. package/dist/sensors/diff.d.ts +1 -1
  64. package/dist/sensors/diff.js +1 -1
  65. package/dist/sensors/index.d.ts +2 -3
  66. package/dist/sensors/index.js +1 -2
  67. package/dist/sensors/index.js.map +1 -1
  68. package/dist/sensors/runner.d.ts +7 -10
  69. package/dist/sensors/runner.js +6 -39
  70. package/dist/sensors/runner.js.map +1 -1
  71. package/dist/sensors/types.d.ts +0 -13
  72. package/package.json +2 -2
  73. package/templates/.cairn/config/sensors.yaml +3 -89
  74. package/templates/.cairn/config/workflow.md +2 -5
  75. package/dist/attention/scoring.d.ts +0 -47
  76. package/dist/attention/scoring.js +0 -87
  77. package/dist/attention/scoring.js.map +0 -1
  78. package/dist/init/glob-inference.d.ts +0 -16
  79. package/dist/init/glob-inference.js +0 -132
  80. package/dist/init/glob-inference.js.map +0 -1
  81. package/dist/sensors/structural.d.ts +0 -31
  82. package/dist/sensors/structural.js +0 -196
  83. package/dist/sensors/structural.js.map +0 -1
@@ -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.4",
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.4"
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;
@@ -1,87 +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 { matchAnyGlob } from "@isaacriehm/cairn-state";
24
- const DECISION_VERBS = /\b(chose|chosen|choose|decided|prefer|preferred|because|locked|enforce|enforced|require|required|adopt|adopted|standardize|standardized|switch|migrated|deprecate|reject|rejected)\b/i;
25
- const JSDOC_TAGS = /@(domain|scope|orgScope|see|param|returns|throws|deprecated|since|module|namespace|file|fileoverview|public|private|protected|internal|readonly|override|sealed|immutable|invariant)\b/;
26
- const INVARIANT_MODALS = /\b(MUST|MUSTN'T|MUST NOT|NEVER|ALWAYS|SHALL|SHALL NOT|CANNOT|FORBID|FORBIDDEN|REQUIRED|REQUIRES)\b/i;
27
- const REASON_MARKERS = /\b(because|to (prevent|ensure|avoid|guarantee|preserve|enforce|stop)|otherwise)\b/i;
28
- function inHighStakes(file, globs) {
29
- return matchAnyGlob(file, globs.high_stakes_globs ?? []);
30
- }
31
- function inRoutesOrDtos(file, globs) {
32
- const combined = [
33
- ...(globs.route_handler_globs ?? []),
34
- ...(globs.dto_globs ?? []),
35
- ];
36
- return matchAnyGlob(file, combined);
37
- }
38
- /**
39
- * Score a DEC draft. Max 8 / threshold 7→high / 4→medium.
40
- */
41
- export function scoreDecDraft(input) {
42
- let score = 0;
43
- if (inHighStakes(input.sourceFile, input.globs))
44
- score += 3;
45
- if (inRoutesOrDtos(input.sourceFile, input.globs))
46
- score += 1;
47
- const proseLen = input.prose.trim().length;
48
- if (proseLen >= 80 && proseLen <= 800)
49
- score += 2;
50
- const titleLen = input.title.trim().length;
51
- if (titleLen >= 10 && titleLen <= 80)
52
- score += 1;
53
- if (DECISION_VERBS.test(input.prose))
54
- score += 2;
55
- if (JSDOC_TAGS.test(input.rawComment))
56
- score += 1;
57
- if (score >= 7)
58
- return "high";
59
- if (score >= 4)
60
- return "medium";
61
- return "low";
62
- }
63
- /**
64
- * Score an invariant proposal. Max 9 / threshold 7→high / 4→medium.
65
- * Stricter than DEC scoring: requires modal verb + reason + high-stakes
66
- * location for high confidence, since false-positive invariants become
67
- * sensor-sweep noise downstream.
68
- */
69
- export function scoreInvariant(input) {
70
- let score = 0;
71
- if (inHighStakes(input.sourceFile, input.globs))
72
- score += 3;
73
- const modalText = `${input.title}\n${input.prose}`;
74
- if (INVARIANT_MODALS.test(modalText))
75
- score += 3;
76
- if (REASON_MARKERS.test(input.prose))
77
- score += 2;
78
- const proseLen = input.prose.trim().length;
79
- if (proseLen >= 50 && proseLen <= 600)
80
- score += 1;
81
- if (score >= 7)
82
- return "high";
83
- if (score >= 4)
84
- return "medium";
85
- return "low";
86
- }
87
- //# sourceMappingURL=scoring.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/attention/scoring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAkBvD,MAAM,cAAc,GAClB,uLAAuL,CAAC;AAE1L,MAAM,UAAU,GAAG,wLAAwL,CAAC;AAE5M,MAAM,gBAAgB,GACpB,qGAAqG,CAAC;AAExG,MAAM,cAAc,GAAG,oFAAoF,CAAC;AAE5G,SAAS,YAAY,CAAC,IAAY,EAAE,KAAmB;IACrD,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAAmB;IACvD,MAAM,QAAQ,GAAG;QACf,GAAG,CAAC,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC;QACpC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;KAC3B,CAAC;IACF,OAAO,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAsB;IAClD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,YAAY,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IAC5D,IAAI,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;IAC3C,IAAI,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,GAAG;QAAE,KAAK,IAAI,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;IAC3C,IAAI,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,EAAE;QAAE,KAAK,IAAI,CAAC,CAAC;IACjD,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IACjD,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IAElD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB;IACnD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,YAAY,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,GAAG,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;IACnD,IAAI,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IACjD,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;IAC3C,IAAI,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,GAAG;QAAE,KAAK,IAAI,CAAC,CAAC;IAElD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChC,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,16 +0,0 @@
1
- /**
2
- * Deterministic glob baseline derived from framework conventions detected
3
- * in Phase 1. The mapper LLM still adds project-specific globs on top;
4
- * these are always included regardless of LLM output.
5
- *
6
- * Pure function. Uses existsSync for file-presence checks only.
7
- */
8
- import type { DetectionResult } from "./types.js";
9
- export interface InferredGlobs {
10
- route_handler_globs: string[];
11
- dto_globs: string[];
12
- generator_source_globs: string[];
13
- high_stakes_globs: string[];
14
- off_limits_globs: string[];
15
- }
16
- export declare function inferGlobsFromDetection(detection: DetectionResult, repoRoot: string): InferredGlobs;