@ontrails/regrade 1.0.0-beta.41 → 1.0.0-beta.43

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # @ontrails/regrade
2
2
 
3
+ ## 1.0.0-beta.43
4
+
5
+ ### Minor Changes
6
+
7
+ - [`4fb20a6`](https://github.com/outfitter-dev/trails/commit/4fb20a68e1ed98972d99fed8b2df96bfa6804bd3): Derive deterministic, provenance-bearing vocabulary plan proposals from a minimal `from`/`to` seed, including morphology, public and compound identifier review, filename and reference-closure candidates, namespace census, and validated live-topo API preserves. Classified governed transitions retain their registry identity while routing every governed form to review instead of inventing a single safe successor.
8
+ - [`d3215b0`](https://github.com/outfitter-dev/trails/commit/d3215b0966f13af2a72ece9adbcc2c68c70f81b6): Add governed file renames to vocabulary Regrade plans, with move-first derived reference closure and persisted policy-aware evidence across CLI and MCP.
9
+ - [`5a7d22a`](https://github.com/outfitter-dev/trails/commit/5a7d22ab9d674f86b28758f23c3e94a17efb5be1): Add three-tier vocabulary migration scope. Protected historical paths remain
10
+ scanned and counted as `historical-by-policy` without being rewritten, while
11
+ reports expose scope-tier totals and census-expected teaching-surface coverage
12
+ through equivalent CLI and MCP plan schemas. Applied vocabulary occurrences
13
+ remain auditable in history with an `applied` verdict, while policy-only
14
+ evidence does not make an active plan stale merely by being recorded.
15
+ - [`88a6a62`](https://github.com/outfitter-dev/trails/commit/88a6a62a9e9e230ca6d368fa78dc3ece6c816204): Complete the v1 classification-first cutover from projection/project vocabulary
16
+ to derive/derived for contract-owned fact production and render/rendered for
17
+ surface presentation. Public type, helper, rule, relation, and report names move
18
+ without compatibility aliases; ordinary repository/project nouns remain
19
+ explicit preserves or structured review inventory.
20
+ - [`9f0842e`](https://github.com/outfitter-dev/trails/commit/9f0842ee9d7c7155d86a4fd023760ac0a5636f5d): Retire the temporary root vocabulary-cutover toolchain now that Regrade owns
21
+ structured migration plans, safe rewrites, classification, census, CLI/MCP
22
+ reports, and immutable history. Remove the obsolete source exemptions so
23
+ Oxlint and Warden enforce the durable transition contract directly, and add a
24
+ history-driven Regrade audit surface for current-tree regression checks.
25
+ - [`bd1bd96`](https://github.com/outfitter-dev/trails/commit/bd1bd96b90cd8b55f73061e4078a14cd75bed745): Require committed Regrade provenance for governed vocabulary transitions.
26
+
27
+ Applied governed plans now expose deterministic transition, plan, source,
28
+ safe-apply, and review-follow-up evidence through history results. Warden loads
29
+ committed history into project context, cites it for reintroduced symbols, and
30
+ rejects invalid or missing provenance for transitions that require Regrade in
31
+ the workspace that owns the governed registry, without making downstream apps
32
+ prove the framework's own migrations.
33
+ Portable validation accepts the authoritative numeric file-rename counters
34
+ persisted by Regrade history.
35
+
36
+ ### Patch Changes
37
+
38
+ - [`53014a4`](https://github.com/outfitter-dev/trails/commit/53014a4593170edd5adfbaa2c94c895c67a320d1): Exclude immutable Regrade history artifacts from downstream migration source scans while preserving active plan and other policy-classified evidence. Warden continues to validate committed history through its dedicated provenance loader.
39
+ - [`18a14e2`](https://github.com/outfitter-dev/trails/commit/18a14e220728be7108f3fe2864455c52305aef9f): Finish the v1 vocabulary reset cleanup by retaining the facet guard, adding a
40
+ durable TopoGraph artifact-family guard, teaching the live lexicon directly in
41
+ agent guidance, and replacing completed reset-family placeholders in public
42
+ Regrade examples and CLI schema help.
43
+
44
+ ## 1.0.0-beta.42
45
+
3
46
  ## 1.0.0-beta.41
4
47
 
5
48
  ## 1.0.0-beta.40
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ontrails/regrade",
3
- "version": "1.0.0-beta.41",
3
+ "version": "1.0.0-beta.43",
4
4
  "description": "Downstream migration reporting and safe rewrite helpers for Trails.",
5
5
  "files": [
6
6
  "src/**/*.ts",
@@ -22,13 +22,13 @@
22
22
  "clean": "rm -rf dist *.tsbuildinfo"
23
23
  },
24
24
  "dependencies": {
25
- "@ontrails/core": "^1.0.0-beta.41",
26
- "@ontrails/source": "^1.0.0-beta.41",
27
- "@ontrails/warden": "^1.0.0-beta.41",
25
+ "@ontrails/core": "^1.0.0-beta.43",
26
+ "@ontrails/source": "^1.0.0-beta.43",
27
+ "@ontrails/warden": "^1.0.0-beta.43",
28
28
  "zod": "^4.3.5"
29
29
  },
30
30
  "devDependencies": {
31
- "@ontrails/testing": "^1.0.0-beta.41",
32
- "@ontrails/topography": "^1.0.0-beta.41"
31
+ "@ontrails/testing": "^1.0.0-beta.43",
32
+ "@ontrails/topography": "^1.0.0-beta.43"
33
33
  }
34
34
  }
@@ -233,6 +233,8 @@ export interface AstIdentifierRenameClassOptions {
233
233
  readonly from: string;
234
234
  readonly id?: string;
235
235
  readonly match?: AstIdentifierRenameMatchMode;
236
+ /** Route every matching identifier to review instead of producing an edit. */
237
+ readonly reviewAllMatches?: boolean;
236
238
  readonly reviewDeclarationTypes?: ReadonlySet<string>;
237
239
  readonly reviewExistingTargetSegments?: readonly string[];
238
240
  readonly shouldPreserve?: (
@@ -258,6 +260,7 @@ export interface AstStringLiteralRenameClassOptions {
258
260
  readonly from: string;
259
261
  readonly id?: string;
260
262
  readonly match?: 'exact' | 'property-key' | 'review';
263
+ readonly moduleSpecifierOnly?: boolean;
261
264
  readonly shouldPreserve?: (
262
265
  occurrence: AstIdentifierRenameOccurrence
263
266
  ) => boolean;
@@ -580,6 +583,34 @@ export const createAstIdentifierRenameClass = (
580
583
  };
581
584
  }
582
585
 
586
+ if (options.reviewAllMatches === true) {
587
+ const location = offsetToLineColumn(context.source, span.start);
588
+ const caution = `Identifier "${match.from}" is a derived naming candidate; routed to review.`;
589
+ return {
590
+ detail: {
591
+ candidateReplacement: match.to,
592
+ expectedTarget: `Review identifier "${match.from}" before renaming it to "${match.to}".`,
593
+ judgment: 'unresolved',
594
+ matchedForm: match.from,
595
+ nodeKind: node.type,
596
+ preserveCautions: [caution],
597
+ reason: 'ast-identifier-plan-review',
598
+ signals: ['ast:identifier-rename'],
599
+ span: {
600
+ column: location.column,
601
+ end: span.end,
602
+ line: location.line,
603
+ start: span.start,
604
+ },
605
+ suggestedValidation: 'bun run typecheck',
606
+ symbol: match.from,
607
+ },
608
+ kind: 'review',
609
+ note: caution,
610
+ reason: 'ast-identifier-plan-review',
611
+ };
612
+ }
613
+
583
614
  if (
584
615
  options.shouldPreserve?.({
585
616
  end: span.end,
@@ -755,6 +786,12 @@ export const createAstStringLiteralRenameClass = (
755
786
  if (match === null) {
756
787
  return null;
757
788
  }
789
+ if (
790
+ options.moduleSpecifierOnly === true &&
791
+ !isModuleSpecifierPosition(context)
792
+ ) {
793
+ return null;
794
+ }
758
795
  const { adjacentModuleRoute, value } = match;
759
796
 
760
797
  const span = stringLiteralValueSpan(node, context.source, value);
@@ -24,8 +24,8 @@ import { z } from 'zod';
24
24
  /** Directory names never descended into during collection. */
25
25
  export const DEFAULT_IGNORED_DIRECTORIES: readonly string[] = Object.freeze([
26
26
  '.git',
27
- '.turbo',
28
27
  '.trails',
28
+ '.turbo',
29
29
  'dist',
30
30
  'node_modules',
31
31
  ]);
@@ -129,6 +129,10 @@ const toPosixRelative = (root: string, absolutePath: string): string => {
129
129
  return sep === posix.sep ? rel : rel.split(sep).join(posix.sep);
130
130
  };
131
131
 
132
+ const isImmutableRegradeHistoryDirectory = (path: string): boolean =>
133
+ path === '.trails/regrade/history' ||
134
+ path.endsWith('/.trails/regrade/history');
135
+
132
136
  const direntKind = (dirent: {
133
137
  isDirectory(): boolean;
134
138
  isFile(): boolean;
@@ -200,6 +204,13 @@ export const collectDownstreamSources = (
200
204
  skipped.push({ path, reason: 'ignored-glob' });
201
205
  continue;
202
206
  }
207
+ if (
208
+ entry.kind === 'directory' &&
209
+ isImmutableRegradeHistoryDirectory(path)
210
+ ) {
211
+ skipped.push({ path, reason: 'immutable-regrade-history' });
212
+ continue;
213
+ }
203
214
  const classification = classifyDownstreamEntry(
204
215
  entry.name,
205
216
  entry.kind,
@@ -1563,7 +1563,7 @@ export const loadWardenRegradeClasses = async (
1563
1563
  const restructureRules = [...wardenRules.values()];
1564
1564
  if (root !== undefined) {
1565
1565
  // Project diagnostics are already carried by the term-rewrite loader; this
1566
- // second pass only projects export-restructure-capable project rules.
1566
+ // second pass only derives export-restructure-capable project rules.
1567
1567
  const projectRules = await loadProjectWardenRules(root);
1568
1568
  restructureRules.push(...projectRules.sourceRules);
1569
1569
  }