ctxr-cli 0.4.0 → 0.5.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 (137) hide show
  1. package/dist/adapters/harness/claude-code.d.ts +0 -6
  2. package/dist/adapters/harness/claude-code.d.ts.map +1 -1
  3. package/dist/adapters/harness/claude-code.js +44 -25
  4. package/dist/adapters/harness/claude-code.js.map +1 -1
  5. package/dist/adapters/types.d.ts +28 -9
  6. package/dist/adapters/types.d.ts.map +1 -1
  7. package/dist/commands/adapters-generate.d.ts.map +1 -1
  8. package/dist/commands/adapters-generate.js +15 -3
  9. package/dist/commands/adapters-generate.js.map +1 -1
  10. package/dist/commands/adapters-write-gate.d.ts +20 -0
  11. package/dist/commands/adapters-write-gate.d.ts.map +1 -0
  12. package/dist/commands/adapters-write-gate.js +77 -0
  13. package/dist/commands/adapters-write-gate.js.map +1 -0
  14. package/dist/commands/init.d.ts.map +1 -1
  15. package/dist/commands/init.js +57 -9
  16. package/dist/commands/init.js.map +1 -1
  17. package/dist/commands/rollup-write.d.ts.map +1 -1
  18. package/dist/commands/rollup-write.js +8 -0
  19. package/dist/commands/rollup-write.js.map +1 -1
  20. package/dist/commands/session-land.d.ts.map +1 -1
  21. package/dist/commands/session-land.js +55 -24
  22. package/dist/commands/session-land.js.map +1 -1
  23. package/dist/commands/verify.d.ts +9 -2
  24. package/dist/commands/verify.d.ts.map +1 -1
  25. package/dist/commands/verify.js +50 -27
  26. package/dist/commands/verify.js.map +1 -1
  27. package/dist/config/defaults.d.ts +20 -4
  28. package/dist/config/defaults.d.ts.map +1 -1
  29. package/dist/config/defaults.js +20 -4
  30. package/dist/config/defaults.js.map +1 -1
  31. package/dist/config/schema.d.ts +29 -5
  32. package/dist/config/schema.d.ts.map +1 -1
  33. package/dist/config/schema.js +73 -5
  34. package/dist/config/schema.js.map +1 -1
  35. package/dist/core/agents-doc.d.ts +71 -16
  36. package/dist/core/agents-doc.d.ts.map +1 -1
  37. package/dist/core/agents-doc.js +220 -139
  38. package/dist/core/agents-doc.js.map +1 -1
  39. package/dist/core/checks/harness-portability-checks.d.ts +12 -0
  40. package/dist/core/checks/harness-portability-checks.d.ts.map +1 -0
  41. package/dist/core/checks/harness-portability-checks.js +39 -0
  42. package/dist/core/checks/harness-portability-checks.js.map +1 -0
  43. package/dist/core/checks/integrity-checks.d.ts +25 -1
  44. package/dist/core/checks/integrity-checks.d.ts.map +1 -1
  45. package/dist/core/checks/integrity-checks.js +136 -3
  46. package/dist/core/checks/integrity-checks.js.map +1 -1
  47. package/dist/core/checks/manifest.d.ts.map +1 -1
  48. package/dist/core/checks/manifest.js +2 -0
  49. package/dist/core/checks/manifest.js.map +1 -1
  50. package/dist/core/checks/organize-checks.d.ts +12 -0
  51. package/dist/core/checks/organize-checks.d.ts.map +1 -1
  52. package/dist/core/checks/organize-checks.js +51 -1
  53. package/dist/core/checks/organize-checks.js.map +1 -1
  54. package/dist/core/convention-doc.d.ts +33 -0
  55. package/dist/core/convention-doc.d.ts.map +1 -0
  56. package/dist/core/convention-doc.js +110 -0
  57. package/dist/core/convention-doc.js.map +1 -0
  58. package/dist/core/conventions.d.ts +25 -5
  59. package/dist/core/conventions.d.ts.map +1 -1
  60. package/dist/core/conventions.js +65 -3
  61. package/dist/core/conventions.js.map +1 -1
  62. package/dist/core/errors.d.ts.map +1 -1
  63. package/dist/core/errors.js +2 -1
  64. package/dist/core/errors.js.map +1 -1
  65. package/dist/core/fs/fenced-region.d.ts +38 -0
  66. package/dist/core/fs/fenced-region.d.ts.map +1 -1
  67. package/dist/core/fs/fenced-region.js +88 -2
  68. package/dist/core/fs/fenced-region.js.map +1 -1
  69. package/dist/core/git/repo.d.ts +10 -0
  70. package/dist/core/git/repo.d.ts.map +1 -1
  71. package/dist/core/git/repo.js +28 -0
  72. package/dist/core/git/repo.js.map +1 -1
  73. package/dist/core/git/worktree.d.ts +8 -0
  74. package/dist/core/git/worktree.d.ts.map +1 -1
  75. package/dist/core/git/worktree.js +11 -0
  76. package/dist/core/git/worktree.js.map +1 -1
  77. package/dist/core/hooks.d.ts +10 -0
  78. package/dist/core/hooks.d.ts.map +1 -1
  79. package/dist/core/hooks.js +37 -10
  80. package/dist/core/hooks.js.map +1 -1
  81. package/dist/core/json-config-merge.d.ts +26 -2
  82. package/dist/core/json-config-merge.d.ts.map +1 -1
  83. package/dist/core/json-config-merge.js +61 -7
  84. package/dist/core/json-config-merge.js.map +1 -1
  85. package/dist/core/migrations/registry.d.ts.map +1 -1
  86. package/dist/core/migrations/registry.js +7 -1
  87. package/dist/core/migrations/registry.js.map +1 -1
  88. package/dist/core/migrations/rename-conventions-path.d.ts +26 -0
  89. package/dist/core/migrations/rename-conventions-path.d.ts.map +1 -0
  90. package/dist/core/migrations/rename-conventions-path.js +86 -0
  91. package/dist/core/migrations/rename-conventions-path.js.map +1 -0
  92. package/dist/core/migrations/rename-procedures-path.d.ts +17 -0
  93. package/dist/core/migrations/rename-procedures-path.d.ts.map +1 -0
  94. package/dist/core/migrations/rename-procedures-path.js +45 -0
  95. package/dist/core/migrations/rename-procedures-path.js.map +1 -0
  96. package/dist/core/notes/list.js +5 -5
  97. package/dist/core/notes/list.js.map +1 -1
  98. package/dist/core/reconcile.d.ts.map +1 -1
  99. package/dist/core/reconcile.js +32 -5
  100. package/dist/core/reconcile.js.map +1 -1
  101. package/dist/core/rollup.d.ts +2 -2
  102. package/dist/core/rollup.d.ts.map +1 -1
  103. package/dist/core/rollup.js +24 -3
  104. package/dist/core/rollup.js.map +1 -1
  105. package/dist/core/{procedures.d.ts → skills.d.ts} +12 -12
  106. package/dist/core/skills.d.ts.map +1 -0
  107. package/dist/core/{procedures.js → skills.js} +25 -41
  108. package/dist/core/skills.js.map +1 -0
  109. package/dist/core/templates.d.ts +20 -0
  110. package/dist/core/templates.d.ts.map +1 -0
  111. package/dist/core/templates.js +68 -0
  112. package/dist/core/templates.js.map +1 -0
  113. package/dist/core/write-lifecycle/path-gate.d.ts +28 -0
  114. package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
  115. package/dist/core/write-lifecycle/path-gate.js +78 -22
  116. package/dist/core/write-lifecycle/path-gate.js.map +1 -1
  117. package/dist/run.d.ts.map +1 -1
  118. package/dist/run.js +12 -1
  119. package/dist/run.js.map +1 -1
  120. package/dist/version.d.ts +1 -1
  121. package/dist/version.js +1 -1
  122. package/package.json +1 -1
  123. package/templates/agents/canonical.md +20 -0
  124. package/templates/agents/capture-and-ingest.md +17 -0
  125. package/templates/agents/conventions.md +5 -0
  126. package/templates/agents/mission.md +5 -0
  127. package/templates/agents/placement-no-layers.md +5 -0
  128. package/templates/agents/placement.md +7 -0
  129. package/templates/agents/retrieval-leg-routing.md +14 -0
  130. package/templates/conventions/baseline-convention.md +60 -0
  131. package/templates/conventions/custom-convention-seed.md +21 -0
  132. package/templates/hooks/claude-code-write-gate.sh +15 -0
  133. package/templates/skills/ctxr-connection-finding.md +1 -1
  134. package/templates/skills/ctxr-ingest-orchestration.md +1 -1
  135. package/templates/skills/ctxr-land.md +11 -6
  136. package/dist/core/procedures.d.ts.map +0 -1
  137. package/dist/core/procedures.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,16 @@
1
1
  import type { StoreConfig } from '../config/schema.js';
2
2
  import { type ScannedDoc } from './conventions.js';
3
+ export declare function agentsMdPath(root: string): string;
3
4
  /**
4
5
  * context-retrieval spec (task 4.5): the leg-routing rule that tells an
5
6
  * agent which of its two retrieval legs to use for a given question — the
6
7
  * catalog/graph (contexture-built-and-maintained) or its own direct content
7
8
  * matching (grep, scoped by the store's declared exclusion paths). This is
8
9
  * one fenced region within AGENTS.md; Phase 8 adds the canonical template's
9
- * other sections (root-resolution, frontmatter schema, write-path, procedure
10
+ * other sections (root-resolution, frontmatter schema, write-path, skill
10
11
  * index) as sibling regions in the same file, never touching this one.
11
12
  */
12
13
  export declare const AGENTS_MD_LEG_ROUTING_FENCE: import("./markers.js").Fence;
13
- export declare function agentsMdPath(root: string): string;
14
14
  export declare function renderLegRoutingSection(config: StoreConfig): string[];
15
15
  /** Idempotently reconciles AGENTS.md's leg-routing section from current config — called at init and on re-init. */
16
16
  export declare function buildAgentsLegRoutingSection(root: string, config: StoreConfig): Promise<{
@@ -30,12 +30,14 @@ export declare function buildAgentsCaptureSection(root: string, config: StoreCon
30
30
  changed: boolean;
31
31
  }>;
32
32
  /**
33
- * context-organize spec (task 7.1): the placement procedure is
34
- * documentation driven entirely by the configured taxonomy, never a
35
- * hardcoded layout — this section is generated purely from
33
+ * context-organize spec (task 7.1): the placement skill's documentation is
34
+ * driven entirely by the configured taxonomy, never a
35
+ * hardcoded layout — the layer list is generated purely from
36
36
  * `config.taxonomy.layers`, so it reads correctly under PARA, Zettelkasten,
37
37
  * Diátaxis, or any custom taxonomy without a single layer name appearing in
38
- * this file's own source.
38
+ * this file's own source. A store with no declared layers gets its own
39
+ * template rather than a swapped-out middle, so both variants read as
40
+ * complete documents.
39
41
  */
40
42
  export declare const AGENTS_MD_PLACEMENT_FENCE: import("./markers.js").Fence;
41
43
  export declare function renderPlacementSection(config: StoreConfig): string[];
@@ -43,26 +45,79 @@ export declare function buildAgentsPlacementSection(root: string, config: StoreC
43
45
  changed: boolean;
44
46
  }>;
45
47
  /**
46
- * harness-portability spec (task 8.5): the canonical template's four
47
- * required pieces — root-resolution rule, frontmatter schema pointer,
48
- * write-path rule, and a procedure index — so an agent that has read only
49
- * this file, with no harness-specific context, has everything it needs
50
- * (the spec's own "Reading only AGENTS.md is sufficient" scenario).
48
+ * harness-portability spec (inline-conventions-and-mission): the canonical
49
+ * template's required pieces — root-resolution rule, frontmatter schema
50
+ * pointer, write-path rule, and the harness/store identity boundary — so an
51
+ * agent that has read only this file, with no harness-specific context, has
52
+ * everything it needs (the spec's own "Reading only AGENTS.md is
53
+ * sufficient" scenario). The skill index this section used to carry is gone
54
+ * (see the REMOVED "The skill index reflects the files on disk" requirement)
55
+ * — on a harness with native skill auto-discovery it duplicated content
56
+ * already in context; a harness without one still reaches every skill by
57
+ * path at the configured skills path.
51
58
  */
52
59
  export declare const AGENTS_MD_CANONICAL_FENCE: import("./markers.js").Fence;
53
- export declare function renderCanonicalSection(config: StoreConfig, procedures: readonly ScannedDoc[]): string[];
60
+ export declare function renderCanonicalSection(config: StoreConfig): string[];
54
61
  export declare function buildAgentsCanonicalSection(root: string, config: StoreConfig): Promise<{
55
62
  changed: boolean;
56
63
  }>;
57
64
  /**
58
- * entry-doc-generation spec: operator conventions as referenced documents.
59
- * The index lists what is actually on disk at the configured conventions
60
- * path; contexture ships no seeds here — conventions are definitionally
61
- * operator-authored, so an empty store's section explains the mechanism.
65
+ * inline-conventions-and-mission: the store's current mission, inlined as
66
+ * its own fenced section — replacing the pointer-only rendering this used to
67
+ * get. `missionRaw` is the mission note's raw file content, read by the
68
+ * caller (`buildAgentsMissionSection`) so this stays a pure, synchronous
69
+ * renderer like every other section in this file; `null` means unconfigured
70
+ * or the note doesn't exist, either of which renders nothing at all.
71
+ */
72
+ export declare const AGENTS_MD_MISSION_FENCE: import("./markers.js").Fence;
73
+ export declare function renderMissionSection(config: StoreConfig, missionRaw: string | null): string[];
74
+ export declare function buildAgentsMissionSection(root: string, config: StoreConfig): Promise<{
75
+ changed: boolean;
76
+ }>;
77
+ /**
78
+ * harness-portability spec (inline-conventions-and-mission, folded into one
79
+ * template by compose-store-guidance-documents): operator conventions
80
+ * inlined in full. What's on disk at the configured conventions path is
81
+ * inlined body-and-all — heading-demoted under a heading naming its title,
82
+ * with a provenance line naming its source path — never referenced by a
83
+ * link alone; contexture ships no seeds here — conventions are
84
+ * definitionally operator-authored, so an empty store gets an explanation of
85
+ * the mechanism instead. One template (`conventions.md`) carries both: the
86
+ * empty-vs-populated difference is entirely in the lines `renderConventionsSection`
87
+ * computes for its one `__CONVENTION_BODY__` slot, so the surrounding frame
88
+ * (heading, harness-specific-note paragraph) exists in exactly one place and
89
+ * cannot drift between two copies the way it could when it shipped as two
90
+ * separate template files.
62
91
  */
63
92
  export declare const AGENTS_MD_CONVENTIONS_FENCE: import("./markers.js").Fence;
93
+ /** Exported so doctor/verify can check a specific convention file's inlined block for drift without re-deriving the format. */
94
+ export declare function renderConventionBlock(doc: ScannedDoc): string[];
64
95
  export declare function renderConventionsSection(config: StoreConfig, conventions: readonly ScannedDoc[]): string[];
65
96
  export declare function buildAgentsConventionsSection(root: string, config: StoreConfig): Promise<{
66
97
  changed: boolean;
67
98
  }>;
99
+ /**
100
+ * harness-portability spec: "Generated sections render in a fixed order" —
101
+ * hard rules and current state first, operating mechanics next, the long
102
+ * operator reference last. `reconcileStore` passes this straight to
103
+ * `reorderFencedRegionsInFile`; a mission-less store simply never has the
104
+ * mission fence present, which the reorder primitive already treats as
105
+ * "skip it," not an error.
106
+ */
107
+ export declare const AGENTS_MD_SECTION_ORDER: import("./markers.js").Fence[];
108
+ export interface AgentsMdDrift {
109
+ /** Store-relative paths of convention files whose inlined block no longer matches the source. */
110
+ driftedConventions: string[];
111
+ /** The configured mission path, when its inlined section no longer matches the source; null otherwise. */
112
+ driftedMission: string | null;
113
+ }
114
+ /**
115
+ * harness-portability spec: "The entry document's inlined content matches
116
+ * its sources" — shared by `ctxr doctor` (reports every drifted file) and
117
+ * `ctxr verify --portable` (stops at the first one), per design.md's
118
+ * "Drift detection reuses render, not a hash": re-runs the same renderers
119
+ * `buildAgents*Section` uses and diffs against what is currently inside each
120
+ * fence, rather than storing a separate content hash anywhere.
121
+ */
122
+ export declare function checkAgentsMdDrift(root: string, config: StoreConfig): Promise<AgentsMdDrift>;
68
123
  //# sourceMappingURL=agents-doc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agents-doc.d.ts","sourceRoot":"","sources":["../../src/core/agents-doc.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKpE;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,8BAA4C,CAAC;AAErF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAkBrE;AAED,mHAAmH;AACnH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAEnH;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,8BAAyC,CAAC;AAE9E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAoBlE;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAEhH;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,8BAAgC,CAAC;AAEvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CA8BpE;AAED,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAElH;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,8BAAgC,CAAC;AAsBvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,EAAE,CAwCvG;AAED,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAGlH;AAED;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,8BAAwC,CAAC;AAOjF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,EAAE,CAkB1G;AAED,wBAAsB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAGpH"}
1
+ {"version":3,"file":"agents-doc.d.ts","sourceRoot":"","sources":["../../src/core/agents-doc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD,OAAO,EAAsD,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAgBvG,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,8BAA4C,CAAC;AAgCrF,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAOrE;AAED,mHAAmH;AACnH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAEnH;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,8BAAyC,CAAC;AAE9E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAElE;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAEhH;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,8BAAgC,CAAC;AAEvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAapE;AAED,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAElH;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,8BAAgC,CAAC;AAuBvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAUpE;AAED,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAElH;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAS7F;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAoBhH;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,2BAA2B,8BAAkC,CAAC;AAE3E,+HAA+H;AAC/H,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,EAAE,CAE/D;AAeD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,EAAE,CAE1G;AAED,wBAAsB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAGpH;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,gCAOnC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,iGAAiG;IACjG,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,0GAA0G;IAC1G,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAoClG"}
@@ -1,42 +1,67 @@
1
+ import { readFile } from 'node:fs/promises';
1
2
  import path from 'node:path';
2
3
  import { GRAPH_DOCUMENT_RELATIVE_PATH } from './graph/persist.js';
3
4
  import { CONFIG_FILE_NAME } from './root.js';
4
5
  import { excludedPrefixesFor } from './notes/list.js';
5
- import { scanConventions } from './conventions.js';
6
- import { scanProcedures } from './procedures.js';
7
- import { upsertFencedRegionInFile } from './fs/fenced-region.js';
6
+ import { extractDocMetadata, inlineDocBody, scanConventions } from './conventions.js';
7
+ import { readFencedRegionFromFile, removeFencedRegionFromFile, upsertFencedRegionInFile } from './fs/fenced-region.js';
8
8
  import { htmlCommentFence } from './markers.js';
9
+ import { packagedTemplate, substituteBlock } from './templates.js';
10
+ /**
11
+ * extract-agents-doc-templates: each generated AGENTS.md section's prose
12
+ * lives in `templates/agents/<fence-slug>.md`, named for the fence it lands
13
+ * in, so the file a reviewer opens and the region it writes share a name.
14
+ * Only genuinely per-store data — the exclusion list, the taxonomy layers,
15
+ * the scanned indexes — is computed here and substituted in.
16
+ */
17
+ function agentsTemplate(name) {
18
+ return packagedTemplate('agents', name);
19
+ }
20
+ export function agentsMdPath(root) {
21
+ return path.join(root, 'AGENTS.md');
22
+ }
9
23
  /**
10
24
  * context-retrieval spec (task 4.5): the leg-routing rule that tells an
11
25
  * agent which of its two retrieval legs to use for a given question — the
12
26
  * catalog/graph (contexture-built-and-maintained) or its own direct content
13
27
  * matching (grep, scoped by the store's declared exclusion paths). This is
14
28
  * one fenced region within AGENTS.md; Phase 8 adds the canonical template's
15
- * other sections (root-resolution, frontmatter schema, write-path, procedure
29
+ * other sections (root-resolution, frontmatter schema, write-path, skill
16
30
  * index) as sibling regions in the same file, never touching this one.
17
31
  */
18
32
  export const AGENTS_MD_LEG_ROUTING_FENCE = htmlCommentFence('retrieval-leg-routing');
19
- export function agentsMdPath(root) {
20
- return path.join(root, 'AGENTS.md');
33
+ function trimTrailingSlash(prefix) {
34
+ return prefix.replace(/\/+$/, '');
35
+ }
36
+ /**
37
+ * inline-conventions-and-mission: `excludedPrefixesFor` deliberately includes
38
+ * both a parent path (e.g. `.contexture/`) and paths nested under it (e.g.
39
+ * `.contexture/cache/`) — each has its own reason to be there, and the note
40
+ * walker (`notes/list.ts`) needs the full, unfiltered set to skip directories
41
+ * early rather than descend and filter every file. Rendering that list
42
+ * verbatim produces a dozen-plus redundant bullets, so this collapses any
43
+ * prefix already covered by an ancestor prefix for display only — the
44
+ * exclusion logic itself is untouched.
45
+ */
46
+ function collapseNestedPrefixes(prefixes) {
47
+ // Original (possibly trailing-slash) form preserved per trimmed key, since
48
+ // this list mixes directory prefixes and bare file exclusions (AGENTS.md,
49
+ // log.md) — the collapse test itself compares on the trimmed form only.
50
+ const originalByTrimmed = new Map();
51
+ for (const prefix of prefixes) {
52
+ const trimmed = trimTrailingSlash(prefix);
53
+ if (!originalByTrimmed.has(trimmed))
54
+ originalByTrimmed.set(trimmed, prefix);
55
+ }
56
+ const trimmed = [...originalByTrimmed.keys()];
57
+ return trimmed
58
+ .filter((path) => !trimmed.some((other) => other !== path && path.startsWith(`${other}/`)))
59
+ .sort()
60
+ .map((path) => originalByTrimmed.get(path));
21
61
  }
22
62
  export function renderLegRoutingSection(config) {
23
- const exclusions = [...new Set(excludedPrefixesFor(config))];
24
- return [
25
- '## Retrieval: which leg to use',
26
- '',
27
- 'contexture builds and maintains two retrieval tools ahead of time — consult them first:',
28
- '',
29
- '- **Catalog** (`ctxr catalog show --section <id>`): a curated, coverage-guaranteed index of every retrievable note, one section per taxonomy layer.',
30
- '- **Graph** (`ctxr graph query ...`): the wikilink graph between notes — neighbors, shortest path, hubs, orphans, clusters, bridges; `--type <relation>` follows one configured relation.',
31
- `- **Graph document** (\`${GRAPH_DOCUMENT_RELATIVE_PATH}\`, rebuilt by \`ctxr graph build\`): hub notes by cluster, cross-cluster bridges, and orphans — read it for cluster context before writing.`,
32
- '',
33
- 'For a literal or entity question the catalog and graph do not answer (a specific string, an exact identifier, a phrase),',
34
- 'use your own direct content-matching tool (e.g. grep/ripgrep) against the store, scoped to exclude:',
35
- '',
36
- ...exclusions.map((prefix) => `- \`${prefix}\``),
37
- '',
38
- 'There is no `ctxr search` command. Ranked or semantic search is deferred to a future version — do not look for one.',
39
- ];
63
+ const exclusions = collapseNestedPrefixes(excludedPrefixesFor(config));
64
+ return substituteBlock(agentsTemplate('retrieval-leg-routing').replaceAll('__GRAPH_DOCUMENT_PATH__', GRAPH_DOCUMENT_RELATIVE_PATH), '__EXCLUSION_PATHS__', [exclusions.map((prefix) => `\`${prefix}\``).join(', ')]).split('\n');
40
65
  }
41
66
  /** Idempotently reconciles AGENTS.md's leg-routing section from current config — called at init and on re-init. */
42
67
  export async function buildAgentsLegRoutingSection(root, config) {
@@ -52,81 +77,57 @@ export async function buildAgentsLegRoutingSection(root, config) {
52
77
  */
53
78
  export const AGENTS_MD_CAPTURE_FENCE = htmlCommentFence('capture-and-ingest');
54
79
  export function renderCaptureSection(config) {
55
- return [
56
- '## Capturing and ingesting new material',
57
- '',
58
- `To capture something new, write a plain markdown file directly into \`${config.ingest.inbox_path}\` —`,
59
- 'no CLI command wraps this. That file MUST NOT contain any of these frontmatter fields; contexture assigns',
60
- 'them once, at ingest, and never before:',
61
- '',
62
- '- `source_type`',
63
- '- `source_id`',
64
- '- `source_hash`',
65
- '- `ingested`',
66
- '',
67
- 'Before ingesting, run `ctxr source check <path> --source-id <id>` to get one of four verdicts:',
68
- '`new`, `already_ingested`, `alternate_source_match`, or `multiple_matches` — the last one means stop and',
69
- 'resolve the ambiguity yourself rather than guessing which existing note it is.',
70
- '',
71
- 'To ingest, run `ctxr ingest <path> --source-type <type> --source-id <id>`. It stamps the four fields',
72
- 'above onto the file in place and rebuilds the catalog, so the result already has a catalog entry.',
73
- ];
80
+ return agentsTemplate('capture-and-ingest').replaceAll('__INBOX_PATH__', config.ingest.inbox_path).split('\n');
74
81
  }
75
82
  export async function buildAgentsCaptureSection(root, config) {
76
83
  return upsertFencedRegionInFile(agentsMdPath(root), AGENTS_MD_CAPTURE_FENCE, renderCaptureSection(config));
77
84
  }
78
85
  /**
79
- * context-organize spec (task 7.1): the placement procedure is
80
- * documentation driven entirely by the configured taxonomy, never a
81
- * hardcoded layout — this section is generated purely from
86
+ * context-organize spec (task 7.1): the placement skill's documentation is
87
+ * driven entirely by the configured taxonomy, never a
88
+ * hardcoded layout — the layer list is generated purely from
82
89
  * `config.taxonomy.layers`, so it reads correctly under PARA, Zettelkasten,
83
90
  * Diátaxis, or any custom taxonomy without a single layer name appearing in
84
- * this file's own source.
91
+ * this file's own source. A store with no declared layers gets its own
92
+ * template rather than a swapped-out middle, so both variants read as
93
+ * complete documents.
85
94
  */
86
95
  export const AGENTS_MD_PLACEMENT_FENCE = htmlCommentFence('placement');
87
96
  export function renderPlacementSection(config) {
88
97
  const { layers } = config.taxonomy;
89
- if (layers.length === 0) {
90
- return [
91
- '## Placing a new note',
92
- '',
93
- 'This store\'s taxonomy declares no top-level layers — place new notes directly at the store root (or',
94
- 'wherever related notes already live) and rely on wikilinks and `ctxr graph` for organization,',
95
- 'rather than a folder hierarchy.',
96
- ];
97
- }
98
- const lines = [
99
- '## Placing a new note',
100
- '',
101
- 'This store\'s taxonomy declares these layers — choose the one whose description best matches the note:',
102
- '',
103
- ];
104
- for (const layer of layers) {
98
+ if (layers.length === 0)
99
+ return agentsTemplate('placement-no-layers').split('\n');
100
+ const layerLines = layers.map((layer) => {
105
101
  const directoryDefault = Object.entries(config.visibility.directory_defaults).find(([prefix]) => prefix === layer.path || prefix === `${layer.path}/`)?.[1];
106
- lines.push(`- **${layer.name}** (\`${layer.path}/\`): ${layer.description}${directoryDefault ? ` Notes here default to visibility "${directoryDefault}" unless given an explicit value.` : ''}`);
107
- }
108
- lines.push('', "If no layer fits, use the store's uncategorized/catch-all location and revisit placement later.");
109
- return lines;
102
+ return `- **${layer.name}** (\`${layer.path}/\`): ${layer.description}${directoryDefault ? ` Notes here default to visibility "${directoryDefault}" unless given an explicit value.` : ''}`;
103
+ });
104
+ return substituteBlock(agentsTemplate('placement'), '__LAYER_LIST__', layerLines).split('\n');
110
105
  }
111
106
  export async function buildAgentsPlacementSection(root, config) {
112
107
  return upsertFencedRegionInFile(agentsMdPath(root), AGENTS_MD_PLACEMENT_FENCE, renderPlacementSection(config));
113
108
  }
114
109
  /**
115
- * harness-portability spec (task 8.5): the canonical template's four
116
- * required pieces — root-resolution rule, frontmatter schema pointer,
117
- * write-path rule, and a procedure index — so an agent that has read only
118
- * this file, with no harness-specific context, has everything it needs
119
- * (the spec's own "Reading only AGENTS.md is sufficient" scenario).
110
+ * harness-portability spec (inline-conventions-and-mission): the canonical
111
+ * template's required pieces — root-resolution rule, frontmatter schema
112
+ * pointer, write-path rule, and the harness/store identity boundary — so an
113
+ * agent that has read only this file, with no harness-specific context, has
114
+ * everything it needs (the spec's own "Reading only AGENTS.md is
115
+ * sufficient" scenario). The skill index this section used to carry is gone
116
+ * (see the REMOVED "The skill index reflects the files on disk" requirement)
117
+ * — on a harness with native skill auto-discovery it duplicated content
118
+ * already in context; a harness without one still reaches every skill by
119
+ * path at the configured skills path.
120
120
  */
121
121
  export const AGENTS_MD_CANONICAL_FENCE = htmlCommentFence('canonical');
122
122
  /**
123
- * context-organize spec: when `organize.mission_path` is configured, the
124
- * canonical section names it as a document to load at session start,
125
- * immediately after the identity-boundary paragraph. Content is written and
126
- * its staleness reported through the existing rollup mechanism (`ctxr
127
- * rollup write` / `ctxr rollup stale`) — this pointer only names the path,
128
- * it names no mechanism of its own. Nothing is rendered when unset, so a
129
- * store that never configures it sees this line disappear entirely, not a
123
+ * context-organize spec, kept through inline-conventions-and-mission's
124
+ * design decision "the identity/mission pointer coexists with the inlined
125
+ * Mission section": when `organize.mission_path` is configured, the
126
+ * canonical section still names it as a document to load at session start,
127
+ * immediately followed (as its own fenced section — see
128
+ * `renderMissionSection` below) by that document's full inlined body.
129
+ * Nothing is rendered when unset: the `__MISSION_POINTER__` template line
130
+ * disappears entirely (via `substituteBlock`'s empty-list case), not a
130
131
  * placeholder.
131
132
  */
132
133
  function renderMissionPointer(config) {
@@ -136,79 +137,159 @@ function renderMissionPointer(config) {
136
137
  return [
137
138
  '',
138
139
  `Load \`${missionPath}\` at the start of every session — this store's standing current-state document, ` +
139
- 'kept current by the mission skill (see the procedure index below) and written through `ctxr rollup write`.',
140
+ 'kept current by the mission skill and written through `ctxr rollup write`; its full content follows in the "Mission" section below.',
140
141
  ];
141
142
  }
142
- export function renderCanonicalSection(config, procedures) {
143
- const lines = [
144
- '## Store fundamentals',
145
- '',
146
- '### Root resolution',
147
- '',
148
- `Every contexture command resolves the store root in this order: an explicit ` +
149
- '`--root <path>` flag; the `CONTEXTURE_ROOT` environment variable; walking up from the current directory ' +
150
- `looking for \`${CONFIG_FILE_NAME}\`. No other flag or environment variable selects the root.`,
151
- '',
152
- '### Frontmatter schema',
153
- '',
154
- `- Visibility field: \`${config.fields.visibility}:\` — resolves explicit value, then directory default, then the ` +
155
- `configured fail-closed default (\`${config.visibility.default_context}\`). See \`ctxr note resolve <path>\`.`,
156
- '- Source-identity fields (assigned only by `ctxr ingest`, never hand-written): `source_type`, `source_id`, `source_hash`, `ingested`.',
157
- '- Disclosure audience tags (optional, hand-written): `audience: [<name>, ...]`.',
158
- '',
159
- '### Write path',
160
- '',
161
- 'Every write to this store happens inside a session worktree, never directly on the default branch: `ctxr ' +
162
- 'session start` creates one, then `ctxr session submit` validates, commits, pushes, and opens (or ' +
163
- 'reports how to open) a pull request. Do not edit files in the store root directly.',
164
- '',
165
- '### Identity and memory',
166
- '',
167
- 'Identity, persona, and durable cross-session memory for the agent working this store belong to its harness, ' +
168
- 'not to this store — the store holds knowledge and procedures, documented as portable markdown under ' +
169
- `\`${config.harness.procedures_path}\` (see the procedure index below), never a persona or memory file of its own.`,
170
- ...renderMissionPointer(config),
171
- '',
172
- '### Procedure index',
173
- '',
174
- 'Judgment-driven operations, documented as portable markdown under ' +
175
- `\`${config.harness.procedures_path}\` — read one directly, no harness-specific discovery required:`,
176
- '',
177
- ];
178
- for (const procedure of procedures) {
179
- lines.push(`- [${procedure.title}](${procedure.path})${procedure.description ? ` — ${procedure.description}` : ''}`);
180
- }
181
- return lines;
143
+ export function renderCanonicalSection(config) {
144
+ return substituteBlock(agentsTemplate('canonical')
145
+ .replaceAll('__CONFIG_FILE_NAME__', CONFIG_FILE_NAME)
146
+ .replaceAll('__VISIBILITY_FIELD__', config.fields.visibility)
147
+ .replaceAll('__DEFAULT_CONTEXT__', config.visibility.default_context)
148
+ .replaceAll('__SKILLS_PATH__', config.harness.skills_path), '__MISSION_POINTER__', renderMissionPointer(config)).split('\n');
182
149
  }
183
150
  export async function buildAgentsCanonicalSection(root, config) {
184
- const procedures = await scanProcedures(root, config);
185
- return upsertFencedRegionInFile(agentsMdPath(root), AGENTS_MD_CANONICAL_FENCE, renderCanonicalSection(config, procedures));
151
+ return upsertFencedRegionInFile(agentsMdPath(root), AGENTS_MD_CANONICAL_FENCE, renderCanonicalSection(config));
186
152
  }
187
153
  /**
188
- * entry-doc-generation spec: operator conventions as referenced documents.
189
- * The index lists what is actually on disk at the configured conventions
190
- * path; contexture ships no seeds here — conventions are definitionally
191
- * operator-authored, so an empty store's section explains the mechanism.
154
+ * inline-conventions-and-mission: the store's current mission, inlined as
155
+ * its own fenced section — replacing the pointer-only rendering this used to
156
+ * get. `missionRaw` is the mission note's raw file content, read by the
157
+ * caller (`buildAgentsMissionSection`) so this stays a pure, synchronous
158
+ * renderer like every other section in this file; `null` means unconfigured
159
+ * or the note doesn't exist, either of which renders nothing at all.
192
160
  */
193
- export const AGENTS_MD_CONVENTIONS_FENCE = htmlCommentFence('store-conventions');
194
- const HARNESS_SPECIFIC_NOTE_GUIDANCE = 'A note that applies to only one agent harness (not every harness reading this store) belongs below ' +
195
- "that harness's own managed import in its own entry file, never here — every file in this directory " +
196
- 'is indexed into every harness\'s entry document equally.';
197
- export function renderConventionsSection(config, conventions) {
198
- const lines = ['## Store conventions', ''];
199
- if (conventions.length === 0) {
200
- lines.push(`This store declares no convention documents yet. Operator-authored conventions (content style, field`, `semantics, house rules) belong as markdown files under \`${config.harness.conventions_path}\` — each is`, 'indexed here on regeneration, referenced by path, never inlined.', '', HARNESS_SPECIFIC_NOTE_GUIDANCE);
201
- return lines;
161
+ export const AGENTS_MD_MISSION_FENCE = htmlCommentFence('mission');
162
+ export function renderMissionSection(config, missionRaw) {
163
+ const { mission_path: missionPath } = config.organize;
164
+ if (!missionPath || missionRaw === null)
165
+ return [];
166
+ const doc = extractDocMetadata(missionRaw, missionPath);
167
+ return substituteBlock(agentsTemplate('mission').replaceAll('__MISSION_PATH__', missionPath), '__MISSION_BODY__', inlineDocBody(doc, 1)).split('\n');
168
+ }
169
+ export async function buildAgentsMissionSection(root, config) {
170
+ const { mission_path: missionPath } = config.organize;
171
+ let missionRaw = null;
172
+ if (missionPath) {
173
+ try {
174
+ missionRaw = await readFile(path.join(root, missionPath), 'utf8');
175
+ }
176
+ catch (err) {
177
+ if (err.code !== 'ENOENT')
178
+ throw err;
179
+ }
180
+ }
181
+ const body = renderMissionSection(config, missionRaw);
182
+ // `upsertFencedRegionInFile` appends a fence pair unconditionally when it's
183
+ // absent, even with an empty body — wrong here, where "unconfigured" must
184
+ // mean the section is absent entirely, never an empty fence pair. Removal
185
+ // is idempotent (a no-op when the fence isn't there), so this also cleans
186
+ // up correctly if a store had a mission configured and then unset it.
187
+ if (body.length === 0) {
188
+ return removeFencedRegionFromFile(agentsMdPath(root), AGENTS_MD_MISSION_FENCE);
202
189
  }
203
- lines.push('Operator-authored conventions for this store — read the ones relevant to your task:', '');
204
- for (const doc of conventions) {
205
- lines.push(`- [${doc.title}](${doc.path})${doc.description ? ` — ${doc.description}` : ''}`);
190
+ return upsertFencedRegionInFile(agentsMdPath(root), AGENTS_MD_MISSION_FENCE, body);
191
+ }
192
+ /**
193
+ * harness-portability spec (inline-conventions-and-mission, folded into one
194
+ * template by compose-store-guidance-documents): operator conventions
195
+ * inlined in full. What's on disk at the configured conventions path is
196
+ * inlined body-and-all — heading-demoted under a heading naming its title,
197
+ * with a provenance line naming its source path — never referenced by a
198
+ * link alone; contexture ships no seeds here — conventions are
199
+ * definitionally operator-authored, so an empty store gets an explanation of
200
+ * the mechanism instead. One template (`conventions.md`) carries both: the
201
+ * empty-vs-populated difference is entirely in the lines `renderConventionsSection`
202
+ * computes for its one `__CONVENTION_BODY__` slot, so the surrounding frame
203
+ * (heading, harness-specific-note paragraph) exists in exactly one place and
204
+ * cannot drift between two copies the way it could when it shipped as two
205
+ * separate template files.
206
+ */
207
+ export const AGENTS_MD_CONVENTIONS_FENCE = htmlCommentFence('conventions');
208
+ /** Exported so doctor/verify can check a specific convention file's inlined block for drift without re-deriving the format. */
209
+ export function renderConventionBlock(doc) {
210
+ return [`### ${doc.title}`, '', ...inlineDocBody(doc, 2), '', `_Source: ${doc.path}_`];
211
+ }
212
+ function conventionsBody(config, conventions) {
213
+ if (conventions.length === 0) {
214
+ return [
215
+ 'This store declares no convention documents yet. Operator-authored conventions (content style, field',
216
+ `semantics, house rules) belong as markdown files under \`${config.harness.guidance_path}\` — each is`,
217
+ 'inlined here in full on regeneration.',
218
+ ];
206
219
  }
207
- lines.push('', HARNESS_SPECIFIC_NOTE_GUIDANCE);
208
- return lines;
220
+ const blocks = conventions.map(renderConventionBlock);
221
+ const bodies = blocks.flatMap((block, i) => (i === blocks.length - 1 ? block : [...block, '']));
222
+ return ['Operator-authored conventions for this store, inlined in full:', '', ...bodies];
223
+ }
224
+ export function renderConventionsSection(config, conventions) {
225
+ return substituteBlock(agentsTemplate('conventions'), '__CONVENTION_BODY__', conventionsBody(config, conventions)).split('\n');
209
226
  }
210
227
  export async function buildAgentsConventionsSection(root, config) {
211
228
  const conventions = await scanConventions(root, config);
212
229
  return upsertFencedRegionInFile(agentsMdPath(root), AGENTS_MD_CONVENTIONS_FENCE, renderConventionsSection(config, conventions));
213
230
  }
231
+ /**
232
+ * harness-portability spec: "Generated sections render in a fixed order" —
233
+ * hard rules and current state first, operating mechanics next, the long
234
+ * operator reference last. `reconcileStore` passes this straight to
235
+ * `reorderFencedRegionsInFile`; a mission-less store simply never has the
236
+ * mission fence present, which the reorder primitive already treats as
237
+ * "skip it," not an error.
238
+ */
239
+ export const AGENTS_MD_SECTION_ORDER = [
240
+ AGENTS_MD_CANONICAL_FENCE,
241
+ AGENTS_MD_MISSION_FENCE,
242
+ AGENTS_MD_LEG_ROUTING_FENCE,
243
+ AGENTS_MD_CAPTURE_FENCE,
244
+ AGENTS_MD_PLACEMENT_FENCE,
245
+ AGENTS_MD_CONVENTIONS_FENCE,
246
+ ];
247
+ /**
248
+ * harness-portability spec: "The entry document's inlined content matches
249
+ * its sources" — shared by `ctxr doctor` (reports every drifted file) and
250
+ * `ctxr verify --portable` (stops at the first one), per design.md's
251
+ * "Drift detection reuses render, not a hash": re-runs the same renderers
252
+ * `buildAgents*Section` uses and diffs against what is currently inside each
253
+ * fence, rather than storing a separate content hash anywhere.
254
+ */
255
+ export async function checkAgentsMdDrift(root, config) {
256
+ const filePath = agentsMdPath(root);
257
+ const conventions = await scanConventions(root, config);
258
+ const conventionsRegion = (await readFencedRegionFromFile(filePath, AGENTS_MD_CONVENTIONS_FENCE)).join('\n');
259
+ const freshConventionsSection = renderConventionsSection(config, conventions).join('\n');
260
+ const driftedConventions = [];
261
+ if (freshConventionsSection !== conventionsRegion) {
262
+ if (conventions.length === 0) {
263
+ driftedConventions.push(config.harness.guidance_path);
264
+ }
265
+ else {
266
+ for (const doc of conventions) {
267
+ if (!conventionsRegion.includes(renderConventionBlock(doc).join('\n')))
268
+ driftedConventions.push(doc.path);
269
+ }
270
+ // Every individual block present, yet the whole section still differs
271
+ // (a reordering, an added/removed file, a template change): still real
272
+ // drift, just not attributable to one file — report the whole set.
273
+ if (driftedConventions.length === 0)
274
+ driftedConventions.push(...conventions.map((doc) => doc.path));
275
+ }
276
+ }
277
+ let driftedMission = null;
278
+ const missionPath = config.organize.mission_path;
279
+ if (missionPath) {
280
+ let missionRaw = null;
281
+ try {
282
+ missionRaw = await readFile(path.join(root, missionPath), 'utf8');
283
+ }
284
+ catch (err) {
285
+ if (err.code !== 'ENOENT')
286
+ throw err;
287
+ }
288
+ const missionRegion = (await readFencedRegionFromFile(filePath, AGENTS_MD_MISSION_FENCE)).join('\n');
289
+ const freshMissionSection = renderMissionSection(config, missionRaw).join('\n');
290
+ if (freshMissionSection !== missionRegion)
291
+ driftedMission = missionPath;
292
+ }
293
+ return { driftedConventions, driftedMission };
294
+ }
214
295
  //# sourceMappingURL=agents-doc.js.map