@deskwork/core 0.45.2 → 0.46.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 (156) hide show
  1. package/dist/config.d.ts +14 -4
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +43 -12
  4. package/dist/config.js.map +1 -1
  5. package/dist/content-index.d.ts +25 -0
  6. package/dist/content-index.d.ts.map +1 -1
  7. package/dist/content-index.js +142 -15
  8. package/dist/content-index.js.map +1 -1
  9. package/dist/doctor/index.d.ts +3 -0
  10. package/dist/doctor/index.d.ts.map +1 -1
  11. package/dist/doctor/index.js +3 -0
  12. package/dist/doctor/index.js.map +1 -1
  13. package/dist/doctor/legacy-config.d.ts +98 -0
  14. package/dist/doctor/legacy-config.d.ts.map +1 -0
  15. package/dist/doctor/legacy-config.js +174 -0
  16. package/dist/doctor/legacy-config.js.map +1 -0
  17. package/dist/doctor/project-scope-gate.d.ts +12 -21
  18. package/dist/doctor/project-scope-gate.d.ts.map +1 -1
  19. package/dist/doctor/project-scope-gate.js +13 -25
  20. package/dist/doctor/project-scope-gate.js.map +1 -1
  21. package/dist/doctor/repair.d.ts +11 -0
  22. package/dist/doctor/repair.d.ts.map +1 -1
  23. package/dist/doctor/repair.js +10 -89
  24. package/dist/doctor/repair.js.map +1 -1
  25. package/dist/doctor/rules/duplicate-id.d.ts +7 -2
  26. package/dist/doctor/rules/duplicate-id.d.ts.map +1 -1
  27. package/dist/doctor/rules/duplicate-id.js +8 -5
  28. package/dist/doctor/rules/duplicate-id.js.map +1 -1
  29. package/dist/doctor/rules/duplicate-id.ts +8 -5
  30. package/dist/doctor/rules/legacy-top-level-id-migration.d.ts.map +1 -1
  31. package/dist/doctor/rules/legacy-top-level-id-migration.js +11 -8
  32. package/dist/doctor/rules/legacy-top-level-id-migration.js.map +1 -1
  33. package/dist/doctor/rules/legacy-top-level-id-migration.ts +10 -11
  34. package/dist/doctor/rules/sites-to-lanes-migration.d.ts +39 -0
  35. package/dist/doctor/rules/sites-to-lanes-migration.d.ts.map +1 -0
  36. package/dist/doctor/rules/sites-to-lanes-migration.js +395 -0
  37. package/dist/doctor/rules/sites-to-lanes-migration.js.map +1 -0
  38. package/dist/doctor/rules/sites-to-lanes-migration.ts +449 -0
  39. package/dist/doctor/rules/workflow-stale.d.ts.map +1 -1
  40. package/dist/doctor/rules/workflow-stale.js +5 -2
  41. package/dist/doctor/rules/workflow-stale.js.map +1 -1
  42. package/dist/doctor/rules/workflow-stale.ts +5 -1
  43. package/dist/doctor/runner.d.ts +15 -1
  44. package/dist/doctor/runner.d.ts.map +1 -1
  45. package/dist/doctor/runner.js +48 -41
  46. package/dist/doctor/runner.js.map +1 -1
  47. package/dist/doctor/sites-migration-backfill.d.ts +71 -0
  48. package/dist/doctor/sites-migration-backfill.d.ts.map +1 -0
  49. package/dist/doctor/sites-migration-backfill.js +164 -0
  50. package/dist/doctor/sites-migration-backfill.js.map +1 -0
  51. package/dist/doctor/validate.d.ts.map +1 -1
  52. package/dist/doctor/validate.js +34 -73
  53. package/dist/doctor/validate.js.map +1 -1
  54. package/dist/entry/resolve-artifact.d.ts +80 -0
  55. package/dist/entry/resolve-artifact.d.ts.map +1 -0
  56. package/dist/entry/resolve-artifact.js +102 -0
  57. package/dist/entry/resolve-artifact.js.map +1 -0
  58. package/dist/entry/shortform-path.d.ts +34 -0
  59. package/dist/entry/shortform-path.d.ts.map +1 -0
  60. package/dist/entry/shortform-path.js +50 -0
  61. package/dist/entry/shortform-path.js.map +1 -0
  62. package/dist/index.d.ts +1 -2
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +1 -2
  65. package/dist/index.js.map +1 -1
  66. package/dist/iterate/iterate.d.ts.map +1 -1
  67. package/dist/iterate/iterate.js +21 -26
  68. package/dist/iterate/iterate.js.map +1 -1
  69. package/dist/lanes/bootstrap.d.ts +11 -7
  70. package/dist/lanes/bootstrap.d.ts.map +1 -1
  71. package/dist/lanes/bootstrap.js +42 -17
  72. package/dist/lanes/bootstrap.js.map +1 -1
  73. package/dist/lanes/index.d.ts +1 -0
  74. package/dist/lanes/index.d.ts.map +1 -1
  75. package/dist/lanes/index.js +6 -0
  76. package/dist/lanes/index.js.map +1 -1
  77. package/dist/lanes/loader.d.ts +33 -6
  78. package/dist/lanes/loader.d.ts.map +1 -1
  79. package/dist/lanes/loader.js +44 -11
  80. package/dist/lanes/loader.js.map +1 -1
  81. package/dist/lanes/operations/create.d.ts +11 -2
  82. package/dist/lanes/operations/create.d.ts.map +1 -1
  83. package/dist/lanes/operations/create.js +15 -4
  84. package/dist/lanes/operations/create.js.map +1 -1
  85. package/dist/lanes/operations/list.d.ts +3 -2
  86. package/dist/lanes/operations/list.d.ts.map +1 -1
  87. package/dist/lanes/operations/list.js +3 -2
  88. package/dist/lanes/operations/list.js.map +1 -1
  89. package/dist/lanes/operations/move.d.ts +29 -25
  90. package/dist/lanes/operations/move.d.ts.map +1 -1
  91. package/dist/lanes/operations/move.js +45 -242
  92. package/dist/lanes/operations/move.js.map +1 -1
  93. package/dist/lanes/operations/update.d.ts +15 -5
  94. package/dist/lanes/operations/update.d.ts.map +1 -1
  95. package/dist/lanes/operations/update.js +32 -12
  96. package/dist/lanes/operations/update.js.map +1 -1
  97. package/dist/lanes/scaffold-path.d.ts +88 -0
  98. package/dist/lanes/scaffold-path.d.ts.map +1 -0
  99. package/dist/lanes/scaffold-path.js +122 -0
  100. package/dist/lanes/scaffold-path.js.map +1 -0
  101. package/dist/lanes/types.d.ts +54 -31
  102. package/dist/lanes/types.d.ts.map +1 -1
  103. package/dist/lanes/types.js +60 -21
  104. package/dist/lanes/types.js.map +1 -1
  105. package/dist/outline-split.d.ts +2 -3
  106. package/dist/outline-split.d.ts.map +1 -1
  107. package/dist/outline-split.js +2 -3
  108. package/dist/outline-split.js.map +1 -1
  109. package/dist/paths.d.ts +14 -87
  110. package/dist/paths.d.ts.map +1 -1
  111. package/dist/paths.js +21 -131
  112. package/dist/paths.js.map +1 -1
  113. package/dist/remark-strip-outline.mjs +2 -3
  114. package/dist/rename-slug.d.ts +3 -3
  115. package/dist/rename-slug.d.ts.map +1 -1
  116. package/dist/rename-slug.js +137 -44
  117. package/dist/rename-slug.js.map +1 -1
  118. package/dist/review/handlers.d.ts +3 -3
  119. package/dist/review/handlers.d.ts.map +1 -1
  120. package/dist/review/handlers.js +18 -14
  121. package/dist/review/handlers.js.map +1 -1
  122. package/dist/review/report.d.ts +13 -2
  123. package/dist/review/report.d.ts.map +1 -1
  124. package/dist/review/report.js +48 -18
  125. package/dist/review/report.js.map +1 -1
  126. package/dist/review/start-handlers.d.ts +4 -4
  127. package/dist/review/start-handlers.d.ts.map +1 -1
  128. package/dist/review/start-handlers.js +25 -25
  129. package/dist/review/start-handlers.js.map +1 -1
  130. package/dist/review/workflow-paths.d.ts +24 -26
  131. package/dist/review/workflow-paths.d.ts.map +1 -1
  132. package/dist/review/workflow-paths.js +70 -60
  133. package/dist/review/workflow-paths.js.map +1 -1
  134. package/dist/schema/draft-annotation.d.ts +8 -8
  135. package/dist/schema/entry.d.ts +6 -6
  136. package/dist/schema/journal-events.d.ts +56 -42
  137. package/dist/schema/journal-events.d.ts.map +1 -1
  138. package/dist/schema/journal-events.js +23 -9
  139. package/dist/schema/journal-events.js.map +1 -1
  140. package/dist/sidecar/read.d.ts +8 -0
  141. package/dist/sidecar/read.d.ts.map +1 -1
  142. package/dist/sidecar/read.js +36 -9
  143. package/dist/sidecar/read.js.map +1 -1
  144. package/dist/sidecar/write.d.ts +14 -0
  145. package/dist/sidecar/write.d.ts.map +1 -1
  146. package/dist/sidecar/write.js +25 -0
  147. package/dist/sidecar/write.js.map +1 -1
  148. package/package.json +9 -9
  149. package/dist/body-state.d.ts +0 -27
  150. package/dist/body-state.d.ts.map +0 -1
  151. package/dist/body-state.js +0 -62
  152. package/dist/body-state.js.map +0 -1
  153. package/dist/scaffold.d.ts +0 -67
  154. package/dist/scaffold.d.ts.map +0 -1
  155. package/dist/scaffold.js +0 -122
  156. package/dist/scaffold.js.map +0 -1
@@ -9,7 +9,7 @@
9
9
  * Sibling-relative imports per the project convention.
10
10
  */
11
11
  import { readCalendar } from "../calendar.js";
12
- import { buildContentIndex } from "../content-index.js";
12
+ import { buildContentIndexFromSidecars } from "../content-index.js";
13
13
  import { resolveCalendarPath } from "../paths.js";
14
14
  import { readWorkflows } from "../review/pipeline.js";
15
15
  import orphanFrontmatterId from "./rules/orphan-frontmatter-id.js";
@@ -21,6 +21,7 @@ import calendarUuidMissing from "./rules/calendar-uuid-missing.js";
21
21
  import legacyTopLevelIdMigration from "./rules/legacy-top-level-id-migration.js";
22
22
  import legacyStageArtifactPath from "./rules/legacy-stage-artifact-path.js";
23
23
  import laneConfigMissingTemplate from "./rules/lane-config-missing-template.js";
24
+ import sitesToLanesMigration from "./rules/sites-to-lanes-migration.js";
24
25
  import entryLaneMissing from "./rules/entry-lane-missing.js";
25
26
  import entryAnchorShape from "./rules/entry-anchor-shape.js";
26
27
  import entryAddressReasonMissing from "./rules/entry-address-reason-missing.js";
@@ -40,6 +41,7 @@ export const RULES = [
40
41
  calendarUuidMissing,
41
42
  legacyTopLevelIdMigration,
42
43
  legacyStageArtifactPath,
44
+ sitesToLanesMigration,
43
45
  laneConfigMissingTemplate,
44
46
  entryLaneMissing,
45
47
  entryAnchorShape,
@@ -79,32 +81,35 @@ export function parseFixArgument(arg) {
79
81
  }
80
82
  return ids;
81
83
  }
82
- /** Build the per-site context once for a run. */
83
- function buildContext(opts, site, interaction) {
84
- const calendarPath = resolveCalendarPath(opts.projectRoot, opts.config, site);
84
+ /**
85
+ * The single project scope label. Phase 39c collapsed the doctor's
86
+ * per-site loop (location is no longer the identifying axis — the
87
+ * sidecar set is the source of truth) into one project pass. Findings
88
+ * carry this as their `site` label so existing consumers that group by
89
+ * `finding.site` still see a stable key.
90
+ */
91
+ export const PROJECT_SCOPE = 'project';
92
+ /** Build the single project-scoped context for a run. */
93
+ async function buildContext(opts, interaction) {
94
+ // Phase 39c: the calendar is the single project-level
95
+ // `.deskwork/calendar.md`; the content index is driven by the sidecar
96
+ // set (the SSOT), not a configured site `contentDir`. Workflows are no
97
+ // longer site-filtered — the runner exposes the whole workflow store
98
+ // and the workflow-stale rule reconciles against the single calendar.
99
+ const calendarPath = resolveCalendarPath(opts.projectRoot, opts.config);
85
100
  const calendar = readCalendar(calendarPath);
86
- const index = buildContentIndex(opts.projectRoot, opts.config, site);
87
- const allWorkflows = readWorkflows(opts.projectRoot, opts.config);
88
- const workflows = allWorkflows.filter((w) => w.site === site);
101
+ const index = await buildContentIndexFromSidecars(opts.projectRoot);
102
+ const workflows = readWorkflows(opts.projectRoot, opts.config);
89
103
  return {
90
104
  projectRoot: opts.projectRoot,
91
105
  config: opts.config,
92
- site,
106
+ site: PROJECT_SCOPE,
93
107
  calendar,
94
108
  index,
95
109
  workflows,
96
110
  interaction,
97
111
  };
98
112
  }
99
- function selectSites(opts) {
100
- if (opts.site !== undefined) {
101
- if (!(opts.site in opts.config.sites)) {
102
- throw new Error(`Unknown site "${opts.site}". Configured sites: ${Object.keys(opts.config.sites).join(', ')}`);
103
- }
104
- return [opts.site];
105
- }
106
- return Object.keys(opts.config.sites);
107
- }
108
113
  function selectRules(available, ruleIds) {
109
114
  if (ruleIds === undefined)
110
115
  return [...available];
@@ -133,24 +138,31 @@ async function buildEffectiveRules(projectRoot) {
133
138
  const projectRules = await loadProjectRules(projectRoot);
134
139
  return mergeRules(RULES, projectRules);
135
140
  }
141
+ /**
142
+ * Shared setup for both doctor entry points: resolve the effective rule
143
+ * set (built-ins + project overrides, filtered by `ruleIds`) and build the
144
+ * run context. `runAudit` and `runRepair` differ only in what they DO with
145
+ * the rules + ctx, not in how they obtain them.
146
+ */
147
+ async function prepareRun(opts, interaction) {
148
+ const available = await buildEffectiveRules(opts.projectRoot);
149
+ const rules = selectRules(available, opts.ruleIds);
150
+ const ctx = await buildContext(opts, interaction);
151
+ return { rules, ctx };
152
+ }
136
153
  /**
137
154
  * Audit: collect findings without mutating the world. Returns a fully-
138
155
  * built report with empty `repairs`. Suitable for pre-commit hooks
139
156
  * that just want a non-zero exit code on any finding.
140
157
  */
141
158
  export async function runAudit(opts, interaction) {
142
- const sites = selectSites(opts);
143
- const available = await buildEffectiveRules(opts.projectRoot);
144
- const rules = selectRules(available, opts.ruleIds);
159
+ const { rules, ctx } = await prepareRun(opts, interaction);
145
160
  const findings = [];
146
- for (const site of sites) {
147
- const ctx = buildContext(opts, site, interaction);
148
- for (const rule of rules) {
149
- const out = await rule.audit(ctx);
150
- findings.push(...out);
151
- }
161
+ for (const rule of rules) {
162
+ const out = await rule.audit(ctx);
163
+ findings.push(...out);
152
164
  }
153
- return { findings, repairs: [], sites };
165
+ return { findings, repairs: [], sites: [PROJECT_SCOPE] };
154
166
  }
155
167
  /**
156
168
  * Repair: run audit → plan → (consult interaction) → apply. Returns
@@ -162,24 +174,19 @@ export async function runAudit(opts, interaction) {
162
174
  * `interaction.confirmApply`. `report-only` plans never apply.
163
175
  */
164
176
  export async function runRepair(opts, interaction) {
165
- const sites = selectSites(opts);
166
- const available = await buildEffectiveRules(opts.projectRoot);
167
- const rules = selectRules(available, opts.ruleIds);
177
+ const { rules, ctx } = await prepareRun(opts, interaction);
168
178
  const findings = [];
169
179
  const repairs = [];
170
- for (const site of sites) {
171
- const ctx = buildContext(opts, site, interaction);
172
- for (const rule of rules) {
173
- const ruleFindings = await rule.audit(ctx);
174
- findings.push(...ruleFindings);
175
- for (const finding of ruleFindings) {
176
- const plan = await rule.plan(ctx, finding);
177
- const result = await resolveAndApply(rule, ctx, plan, interaction);
178
- repairs.push(result);
179
- }
180
+ for (const rule of rules) {
181
+ const ruleFindings = await rule.audit(ctx);
182
+ findings.push(...ruleFindings);
183
+ for (const finding of ruleFindings) {
184
+ const plan = await rule.plan(ctx, finding);
185
+ const result = await resolveAndApply(rule, ctx, plan, interaction);
186
+ repairs.push(result);
180
187
  }
181
188
  }
182
- return { findings, repairs, sites };
189
+ return { findings, repairs, sites: [PROJECT_SCOPE] };
183
190
  }
184
191
  /**
185
192
  * Resolve a `prompt` plan via the interaction adapter and apply it.
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/doctor/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/doctor/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Sites-to-lanes migration backfiller (Phase 39b).
3
+ *
4
+ * This is the LAST legitimate use of the slug+stage heuristic (per the
5
+ * sites→lanes retirement spec §"Migration" step 2). For every entry
6
+ * lacking `artifactPath`, it derives the artifact location ONCE from the
7
+ * current resolved location and stamps it onto the sidecar.
8
+ *
9
+ * AMBIGUITY-HALT (AUDIT-20260602-03 — the critical guard):
10
+ *
11
+ * The heuristic is the SAME slug+stage search that causes the #394
12
+ * multi-site false-positive. When a slug exists under more than one
13
+ * legacy `site.contentDir` (or on more than one filesystem), the
14
+ * heuristic resolves to MORE THAN ONE candidate file. The migration
15
+ * MUST NOT silently stamp one of them — doing so would launder a
16
+ * known-ambiguous guess into permanent, trusted `artifactPath` data
17
+ * and make the bug undetectable afterward (no more search to flag it).
18
+ *
19
+ * So this backfiller enumerates ALL candidate files across EVERY
20
+ * legacy `site.contentDir` for the entry's slug+stage. Only an
21
+ * entry with EXACTLY ONE candidate is stamped. An entry with two or
22
+ * more candidates is REFUSED: it is reported on `ambiguous[]` with the
23
+ * colliding paths, requiring operator disambiguation. An entry with
24
+ * zero candidates is reported on `noCandidate[]` (nothing on disk to
25
+ * stamp from). Never guess.
26
+ *
27
+ * The pre-existing `repair.ts:backfillArtifactPaths` checked exactly one
28
+ * heuristic path (a single base dir). This widens that to a
29
+ * multi-candidate search across every legacy contentDir precisely so it
30
+ * can DETECT the collision it must refuse to launder.
31
+ *
32
+ * Sibling-relative imports per the doctor convention.
33
+ */
34
+ /**
35
+ * One legacy content base the backfiller searches, paired with the lane
36
+ * id the migration assigns to entries resolving under it. `laneId` is the
37
+ * legacy site slug (= the lane id `laneFromSite` creates). Threading the
38
+ * lane id through the search lets the backfiller stamp BOTH `artifactPath`
39
+ * AND `lane` on an unambiguously-resolved entry (AUDIT-20260603-12), so a
40
+ * migrated entry is not left lane-less for `entry-lane-missing` to flag.
41
+ */
42
+ export interface LaneBase {
43
+ readonly laneId: string;
44
+ readonly contentDir: string;
45
+ }
46
+ /** One entry the migration could not stamp because the slug+stage search
47
+ * resolved to more than one candidate (the #394 collision). */
48
+ export interface AmbiguousBackfill {
49
+ readonly entryUuid: string;
50
+ readonly slug: string;
51
+ readonly stage: string;
52
+ /** Project-relative candidate paths — operator must disambiguate. */
53
+ readonly candidates: readonly string[];
54
+ }
55
+ /** Result of the backfill pass. */
56
+ export interface BackfillResult {
57
+ /** UUIDs whose sidecar was stamped with a single unambiguous path. */
58
+ readonly stamped: readonly string[];
59
+ /** Entries refused because >1 candidate existed (ambiguity-halt). */
60
+ readonly ambiguous: readonly AmbiguousBackfill[];
61
+ }
62
+ export declare function backfillFromLegacySites(projectRoot: string, bases: readonly LaneBase[]): Promise<BackfillResult>;
63
+ /**
64
+ * Audit-only variant: enumerate the ambiguity collisions WITHOUT writing
65
+ * anything. Used by the doctor rule's `audit()` to surface
66
+ * `migration-ambiguous` findings before any `--fix` mutation. Shares
67
+ * `planBackfills` with the apply path so the audit and the apply agree on
68
+ * what is ambiguous by construction.
69
+ */
70
+ export declare function detectAmbiguousBackfills(projectRoot: string, bases: readonly LaneBase[]): Promise<AmbiguousBackfill[]>;
71
+ //# sourceMappingURL=sites-migration-backfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sites-migration-backfill.d.ts","sourceRoot":"","sources":["../../src/doctor/sites-migration-backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAmDH;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAkCD;gEACgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAClD;AAsDD,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,QAAQ,EAAE,GACzB,OAAO,CAAC,cAAc,CAAC,CAmBzB;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,QAAQ,EAAE,GACzB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAS9B"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Sites-to-lanes migration backfiller (Phase 39b).
3
+ *
4
+ * This is the LAST legitimate use of the slug+stage heuristic (per the
5
+ * sites→lanes retirement spec §"Migration" step 2). For every entry
6
+ * lacking `artifactPath`, it derives the artifact location ONCE from the
7
+ * current resolved location and stamps it onto the sidecar.
8
+ *
9
+ * AMBIGUITY-HALT (AUDIT-20260602-03 — the critical guard):
10
+ *
11
+ * The heuristic is the SAME slug+stage search that causes the #394
12
+ * multi-site false-positive. When a slug exists under more than one
13
+ * legacy `site.contentDir` (or on more than one filesystem), the
14
+ * heuristic resolves to MORE THAN ONE candidate file. The migration
15
+ * MUST NOT silently stamp one of them — doing so would launder a
16
+ * known-ambiguous guess into permanent, trusted `artifactPath` data
17
+ * and make the bug undetectable afterward (no more search to flag it).
18
+ *
19
+ * So this backfiller enumerates ALL candidate files across EVERY
20
+ * legacy `site.contentDir` for the entry's slug+stage. Only an
21
+ * entry with EXACTLY ONE candidate is stamped. An entry with two or
22
+ * more candidates is REFUSED: it is reported on `ambiguous[]` with the
23
+ * colliding paths, requiring operator disambiguation. An entry with
24
+ * zero candidates is reported on `noCandidate[]` (nothing on disk to
25
+ * stamp from). Never guess.
26
+ *
27
+ * The pre-existing `repair.ts:backfillArtifactPaths` checked exactly one
28
+ * heuristic path (a single base dir). This widens that to a
29
+ * multi-candidate search across every legacy contentDir precisely so it
30
+ * can DETECT the collision it must refuse to launder.
31
+ *
32
+ * Sibling-relative imports per the doctor convention.
33
+ */
34
+ import { stat } from 'node:fs/promises';
35
+ import { isAbsolute, join, relative } from 'node:path';
36
+ import { sidecarsDir } from "../sidecar/paths.js";
37
+ import { writeSidecar } from "../sidecar/write.js";
38
+ import { readAllSidecars } from "../sidecar/read-all.js";
39
+ /**
40
+ * Stage-conventional artifact leaf path RELATIVE to a content base dir.
41
+ * Mirrors the heuristic in `repair.ts` / `validate.ts` but parameterized
42
+ * over the base dir (each legacy `site.contentDir`) instead of hardcoding
43
+ * `docs/`. Returns null for stages with no on-disk artifact.
44
+ *
45
+ * Path shape per slug+stage:
46
+ * - Ideas → <slug>/scrapbook/idea.md
47
+ * - Planned → <slug>/scrapbook/plan.md
48
+ * - Outlining → <slug>/scrapbook/outline.md
49
+ * - Drafting / Final / Published → <slug>/index.md
50
+ * - Blocked / Cancelled / other → null (no editorial-default path)
51
+ */
52
+ function stageRelativeLeaf(slug, stage) {
53
+ switch (stage) {
54
+ case 'Ideas':
55
+ return join(slug, 'scrapbook', 'idea.md');
56
+ case 'Planned':
57
+ return join(slug, 'scrapbook', 'plan.md');
58
+ case 'Outlining':
59
+ return join(slug, 'scrapbook', 'outline.md');
60
+ case 'Drafting':
61
+ case 'Final':
62
+ case 'Published':
63
+ return join(slug, 'index.md');
64
+ default:
65
+ return null;
66
+ }
67
+ }
68
+ async function fileExists(absPath) {
69
+ return stat(absPath).then((s) => s.isFile(), () => false);
70
+ }
71
+ /** Resolve a legacy contentDir to an absolute path under the project. */
72
+ function contentDirAbs(projectRoot, contentDir) {
73
+ return isAbsolute(contentDir) ? contentDir : join(projectRoot, contentDir);
74
+ }
75
+ /**
76
+ * Enumerate EVERY on-disk candidate for an entry's slug+stage across all
77
+ * legacy content bases. Returns project-relative paths (the form stored on
78
+ * the sidecar) paired with the owning lane id, de-duplicated by path and
79
+ * in stable order.
80
+ */
81
+ async function enumerateCandidates(projectRoot, bases, entry) {
82
+ const leaf = stageRelativeLeaf(entry.slug, entry.currentStage);
83
+ if (leaf === null)
84
+ return [];
85
+ const seen = new Set();
86
+ const out = [];
87
+ for (const base of bases) {
88
+ const abs = join(contentDirAbs(projectRoot, base.contentDir), leaf);
89
+ if (!(await fileExists(abs)))
90
+ continue;
91
+ const rel = relative(projectRoot, abs);
92
+ if (seen.has(rel))
93
+ continue;
94
+ seen.add(rel);
95
+ out.push({ path: rel, laneId: base.laneId });
96
+ }
97
+ return out;
98
+ }
99
+ /** The shared backfill plan — what would be stamped + what is ambiguous.
100
+ * Pure read: enumerates candidates, classifies each entry, writes nothing.
101
+ * Both `backfillFromLegacySites` (apply) and `detectAmbiguousBackfills`
102
+ * (audit) derive from this, so audit and apply agree by construction. */
103
+ async function planBackfills(projectRoot, bases) {
104
+ const entries = await readAllSidecars(projectRoot);
105
+ const toStamp = [];
106
+ const ambiguous = [];
107
+ for (const entry of entries) {
108
+ if (entry.artifactPath !== undefined && entry.artifactPath !== '')
109
+ continue;
110
+ const candidates = await enumerateCandidates(projectRoot, bases, entry);
111
+ if (candidates.length === 0)
112
+ continue;
113
+ if (candidates.length > 1) {
114
+ ambiguous.push({
115
+ entryUuid: entry.uuid,
116
+ slug: entry.slug,
117
+ stage: entry.currentStage,
118
+ candidates: candidates.map((c) => c.path),
119
+ });
120
+ continue;
121
+ }
122
+ toStamp.push({ entry, path: candidates[0].path, laneId: candidates[0].laneId });
123
+ }
124
+ return { toStamp, ambiguous };
125
+ }
126
+ export async function backfillFromLegacySites(projectRoot, bases) {
127
+ const { toStamp, ambiguous } = await planBackfills(projectRoot, bases);
128
+ const stamped = [];
129
+ for (const { entry, path, laneId } of toStamp) {
130
+ const updated = {
131
+ ...entry,
132
+ artifactPath: path,
133
+ // Assign the entry to the lane the migration created for its owning
134
+ // site (AUDIT-20260603-12). Without this, the migrated entry stays
135
+ // lane-less and `entry-lane-missing` flags it as an error in the
136
+ // very same `--fix=all` run. Only set when the entry has no lane;
137
+ // an entry already on a lane keeps its membership.
138
+ ...(entry.lane === undefined ? { lane: laneId } : {}),
139
+ updatedAt: new Date().toISOString(),
140
+ };
141
+ await writeSidecar(projectRoot, updated);
142
+ stamped.push(entry.uuid);
143
+ }
144
+ return { stamped, ambiguous };
145
+ }
146
+ /**
147
+ * Audit-only variant: enumerate the ambiguity collisions WITHOUT writing
148
+ * anything. Used by the doctor rule's `audit()` to surface
149
+ * `migration-ambiguous` findings before any `--fix` mutation. Shares
150
+ * `planBackfills` with the apply path so the audit and the apply agree on
151
+ * what is ambiguous by construction.
152
+ */
153
+ export async function detectAmbiguousBackfills(projectRoot, bases) {
154
+ // The sidecars dir may not exist yet; treat absence as "no entries".
155
+ try {
156
+ await stat(sidecarsDir(projectRoot));
157
+ }
158
+ catch {
159
+ return [];
160
+ }
161
+ const { ambiguous } = await planBackfills(projectRoot, bases);
162
+ return ambiguous;
163
+ }
164
+ //# sourceMappingURL=sites-migration-backfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sites-migration-backfill.js","sourceRoot":"","sources":["../../src/doctor/sites-migration-backfill.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/doctor/validate.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EACJ,QAAQ,GACR,kBAAkB,GAClB,qBAAqB,GACrB,iBAAiB,GACjB,mBAAmB,GACnB,eAAe,GACf,kBAAkB,GAClB,aAAa,GACb,WAAW,GACX,uBAAuB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AA4eD,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAYhF"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/doctor/validate.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EACJ,QAAQ,GACR,kBAAkB,GAClB,qBAAqB,GACrB,iBAAiB,GACjB,mBAAmB,GACnB,eAAe,GACf,kBAAkB,GAClB,aAAa,GACb,WAAW,GACX,uBAAuB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAqcD,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAYhF"}
@@ -3,6 +3,7 @@ import { join } from 'node:path';
3
3
  import { EntrySchema, isLinearPipelineStage, isOffPipelineStage, } from "../schema/entry.js";
4
4
  import { extractEntriesForMigration } from "../calendar/parse.js";
5
5
  import { readJournalEvents } from "../journal/read.js";
6
+ import { resolveStoredArtifactPath } from "../entry/resolve-artifact.js";
6
7
  async function validateSchema(projectRoot) {
7
8
  const failures = [];
8
9
  const dir = join(projectRoot, '.deskwork', 'entries');
@@ -48,15 +49,11 @@ async function readSidecarUuids(projectRoot) {
48
49
  }
49
50
  async function validateCalendarSidecar(projectRoot) {
50
51
  const failures = [];
51
- // NOTE (#232 residual tracked in #357): this entry-centric
52
- // sidecar-consistency check reads the hardcoded `.deskwork/calendar.md`,
53
- // NOT the per-site `calendarPath`. regenerate/repair now write the
54
- // configured calendar (#232), so for a custom calendarPath this `--check`
55
- // reads the wrong file and returns false-clean. Fixing it requires
56
- // deciding whether the entry-centric calendar and the per-site
57
- // calendarPath are one surface or two (entangled with #234); see #357.
58
- // For the default config (calendarPath == .deskwork/calendar.md) the two
59
- // coincide and there is no gap.
52
+ // This entry-centric check reads the single project calendar at
53
+ // `.deskwork/calendar.md`. Per the sites→lanes retirement spec §"Calendar"
54
+ // the calendar is a single derived projection (per-site `calendarPath` is
55
+ // retired); the de-parameterization of regenerate/repair lands in 39c
56
+ // (#223/#234/#357). This read-side target already matches that endpoint.
60
57
  const calendarPath = join(projectRoot, '.deskwork', 'calendar.md');
61
58
  let md;
62
59
  try {
@@ -138,51 +135,19 @@ async function loadSidecars(projectRoot) {
138
135
  return out;
139
136
  }
140
137
  /**
141
- * Stage-conventional artifact path. Returns null when a stage does not have a
142
- * primary on-disk artifact (e.g. Blocked / Cancelled) OR when the stage is
143
- * outside the editorial pipeline's eight known values (per Phase 3 / Phase
144
- * 4 — lane-aware path conventions land in the lane code, not in this
145
- * editorial-specific heuristic).
138
+ * Resolve the on-disk artifact path for an entry STORED PATH ONLY
139
+ * (Phase 39d, sites→lanes retirement).
146
140
  *
147
- * Note: Published shares the Drafting/Final path (`docs/<slug>/index.md`).
148
- */
149
- function artifactPathForStage(projectRoot, slug, stage) {
150
- switch (stage) {
151
- case 'Ideas':
152
- return join(projectRoot, 'docs', slug, 'scrapbook', 'idea.md');
153
- case 'Planned':
154
- return join(projectRoot, 'docs', slug, 'scrapbook', 'plan.md');
155
- case 'Outlining':
156
- return join(projectRoot, 'docs', slug, 'scrapbook', 'outline.md');
157
- case 'Drafting':
158
- case 'Final':
159
- case 'Published':
160
- return join(projectRoot, 'docs', slug, 'index.md');
161
- case 'Blocked':
162
- case 'Cancelled':
163
- return null;
164
- default:
165
- // Lane-specific or unrecognized stage; no editorial-default path
166
- // applies. Phase 4 introduces template-driven path resolution.
167
- return null;
168
- }
169
- }
170
- /**
171
- * Resolve the on-disk artifact path for an entry.
172
- *
173
- * Precedence:
174
- * 1. entry.artifactPath (when set — see #140 / migration)
175
- * 2. slug+stage heuristic (`artifactPathForStage`) for entries without
176
- * an explicit path. Off-pipeline stages (Blocked / Cancelled) still
177
- * return null.
178
- *
179
- * Returns null when no artifact is expected for this stage.
141
+ * Per the spec §"Resolution": `entry.artifactPath` → the file, full
142
+ * stop. There is no base-searching and no slug+stage heuristic, so the
143
+ * #394-class multi-site ambiguity cannot recur. An entry that lacks
144
+ * `artifactPath` resolves to `null` here (callers treat null as "no
145
+ * artifact to check"); the `missing-artifact-path` rule surfaces the
146
+ * gap and the 39b migration backfiller (`sites-migration-backfill.ts`)
147
+ * owns stamping it — the runtime resolver never guesses.
180
148
  */
181
149
  function resolveArtifactPath(projectRoot, entry) {
182
- if (entry.artifactPath) {
183
- return join(projectRoot, entry.artifactPath);
184
- }
185
- return artifactPathForStage(projectRoot, entry.slug, entry.currentStage);
150
+ return resolveStoredArtifactPath(entry, projectRoot);
186
151
  }
187
152
  /**
188
153
  * Minimal frontmatter `deskwork.stage` extractor.
@@ -326,24 +291,22 @@ async function validateIterationHistory(projectRoot) {
326
291
  return failures;
327
292
  }
328
293
  /**
329
- * #182 Phase 34 ship-pass surface entries that lack `artifactPath`
330
- * but DO have a discoverable file via the slug+stage heuristic.
294
+ * Surface entries that lack `artifactPath` on a stage that expects an
295
+ * on-disk artifact.
331
296
  *
332
- * Pre-fix, these entries worked at request time (via the
333
- * `resolveArtifactPath` heuristic fallback) but the path was
334
- * re-derived on every read. Stamping `artifactPath` into the sidecar
335
- * makes the binding explicit + survives slug renames + lets the
336
- * version-strip / scrapbook / audit layers stop guessing.
297
+ * Phase 39d (sites→lanes retirement): resolution reads the stored path
298
+ * ONLY the runtime no longer derives a path from the slug+stage
299
+ * heuristic, so this rule no longer SUGGESTS a heuristic location.
300
+ * It reports the missing field and points the operator at the migration
301
+ * backfiller, which is the spec-sanctioned LAST use of the heuristic
302
+ * (`sites-migration-backfill.ts`, 39b). The migration enumerates
303
+ * candidates across legacy content dirs, halts on ambiguity, and stamps
304
+ * the unambiguous ones.
337
305
  *
338
306
  * Returns nothing for entries that:
339
- * - Already have artifactPath set (no gap).
340
- * - Have a stage with no on-disk artifact (Blocked / Cancelled).
341
- * - Have a heuristic path that doesn't exist on disk (file-presence
342
- * handles those — backfilling a non-existent path would be
343
- * misleading).
344
- *
345
- * Repair: write `artifactPath = <heuristic-relative-path>` into the
346
- * sidecar.
307
+ * - Already have a non-empty `artifactPath` (no gap).
308
+ * - Are at an off-pipeline stage with no on-disk artifact
309
+ * (Blocked / Cancelled) those legitimately carry no path.
347
310
  */
348
311
  async function validateMissingArtifactPath(projectRoot) {
349
312
  const failures = [];
@@ -351,16 +314,14 @@ async function validateMissingArtifactPath(projectRoot) {
351
314
  for (const { entry, path } of sidecars) {
352
315
  if (entry.artifactPath !== undefined && entry.artifactPath !== '')
353
316
  continue;
354
- const heuristic = artifactPathForStage(projectRoot, entry.slug, entry.currentStage);
355
- if (!heuristic)
356
- continue;
357
- if (!(await fileExists(heuristic)))
317
+ // Off-pipeline stages (Blocked / Cancelled) carry no on-disk
318
+ // artifact, so a missing artifactPath is expected, not a gap.
319
+ if (isOffPipelineStage(entry.currentStage))
358
320
  continue;
359
- // Sidecar lacks artifactPath; the heuristic resolves and the file
360
- // exists — this is a backfillable case.
361
321
  failures.push({
362
322
  category: 'missing-artifact-path',
363
- message: `sidecar lacks artifactPath; heuristic resolves to ${heuristic} (run with --fix=all to stamp)`,
323
+ message: `sidecar lacks artifactPath (currentStage=${entry.currentStage}); ` +
324
+ `run \`deskwork doctor --fix\` to backfill it from the sites→lanes migration`,
364
325
  entryId: entry.uuid,
365
326
  path,
366
327
  });