Skip to content

Conversation

@aridyckovsky
Copy link
Owner

@aridyckovsky aridyckovsky commented Nov 7, 2025

What

Normalized Schema (BREAKING): Replace duplicated byFile/byRule structures with deduplicated index-based schema that reduces audit.json size by 40-70%.

Loaders Migration: Move config/preset business logic from CLI to core, making CLI a thin orchestrator.

Why

Large projects (10k+ findings) generate 5-10MB audit.json files with significant duplication. This PR:

  • Reduces file size by 40-70% (verified in tests)
  • Enables future delta computation via stable content-based keys
  • Improves architecture by centralizing business logic in core

Scope

Packages affected:

  • @effect-migrate/core - BREAKING schema change (0.1.0 → 0.2.0) + new business logic
  • @effect-migrate/cli - Thin orchestrator using core services

Changeset

  • Changeset added

Changeset summary:

Add normalized schema for 40-70% audit.json size reduction and move business logic to core. Breaking changes: (1) Schema 0.1.0 → 0.2.0 - replaces byFile/byRule with deduplicated arrays. (2) CLI loaders removed - use @effect-migrate/core exports instead.

Testing

pnpm build:types && pnpm typecheck && pnpm lint && pnpm build && pnpm test

All checks pass: ✅ (308 tests)

New tests added:

  • packages/core/test/amp/normalizer.test.ts (40+ tests) - Normalization, deduplication, stable keys
  • packages/core/test/config/merge.test.ts (9 tests)
  • packages/core/test/utils/merge.test.ts (21 tests)
  • packages/core/test/presets/PresetLoader.test.ts (6 tests)
  • packages/core/test/rules/builders.test.ts (14 tests)
  • packages/cli/test/layers/PresetLoaderWorkspace.test.ts (6 tests)

Size reduction verified: 1000 findings → 70% reduction (500KB → 150KB)

Schema Migration

BEFORE (v0.1.0):

{
  "findings": {
    "byFile": {
      "file1.ts": [{ "id": "no-async", "message": "...", "file": "file1.ts", ... }]
    },
    "byRule": { "..." }
  }
}

AFTER (v0.2.0):

{
  "findings": {
    "rules": [{ "id": "no-async", "kind": "pattern", "severity": "warning", "message": "..." }],
    "files": ["file1.ts"],
    "results": [{ "rule": 0, "file": 0, "range": [1, 1, 1, 10] }],
    "groups": {
      "byFile": { "0": [0] },
      "byRule": { "0": [0] }
    }
  }
}

Key changes:

  • Rules/files deduplicated (stored once, referenced by index)
  • Compact range tuples (67% smaller than objects)
  • Deterministic ordering (sorted rules/files)
  • Content-based keys for future delta computation

Checklist

  • Code follows Effect-TS best practices
  • TypeScript strict mode passes
  • All tests pass (308 total)
  • Linter passes
  • Build succeeds
  • Changeset created
  • Breaking change documented (schema version bump, migration guide)

Agent Context

Implementation approach:

Normalized schema:

  • Extracted RULE_KINDS constant for type safety
  • Implemented normalizeResults() with deterministic ordering (sorted rules/files)
  • Stable content-based keys via deriveResultKey() for cross-checkpoint diffing
  • Integrated into context-writer with path normalization

Loaders migration:

  • Moved mergeConfig, PresetLoader, rulesFromConfig to core
  • Created PresetLoaderWorkspaceLive layer for CLI workspace resolution
  • Refactored CLI loaders to orchestrate core services

TypeScript project references:

  • Split tsconfig.json into solution with src/test projects
  • Fixed NodeNext module resolution (.js extensions)
  • Removed redundant tests

Amp Threads:

Related docs:

  • @docs/agents/plans/pr2-normalized-schema.md
  • @docs/agents/plans/loaders-to-core-migration.md
  • @docs/agents/prs/reviews/amp/pr2-normalized-schema.md

Migration Impact

For external consumers: None (pre-1.0, no published versions)

For internal development: Regenerate via effect-migrate audit (no migration script needed)

Commits

26 commits organized in 3 phases:

  1. Normalized schema (commits 1-17) - Schema design, normalizer, tests, changeset
  2. Loaders migration (commits 18-23) - Move business logic to core, refactor CLI
  3. Build quality (commits 24-26) - TypeScript project references, import fixes

aridyckovsky and others added 26 commits November 7, 2025 11:49
- Add RULE_KINDS array and RuleKind type to rules/types.ts
- Ensures Schema.Literal stays in sync with RuleResult.ruleKind
- Addresses PR review recommendation for shared rule kind constant
- Define RuleDef, CompactRange, CompactResult, FindingsGroup schemas
- Replace byFile/byRule with deduplicated rules[], files[], results[]
- Add groups field with documented optionality rationale
- Document info severity counting behavior in FindingsSummary
- Use RULE_KINDS constant for kind literal values
- Bump schema version to 0.2.0 (breaking change)
- Add normalizeResults() for rule/file deduplication
- Implement deterministic ordering (sorted rules/files)
- Add expandResult() for reconstructing full RuleResult
- Add deriveResultKey() for content-based stable keys
- Add rebuildGroups() for reconstructing groups from results
- Achieves 40-70% size reduction through deduplication
- Call normalizeResults() in writeAuditContext()
- Pre-normalize file paths to forward slashes
- Sort rulesEnabled and failOn for determinism
- Emit normalized findings structure to audit.json
- Export normalizeResults, expandResult, deriveResultKey from main index
- Export all normalizer functions from amp submodule
- Enables consumers to use deduplication utilities
- Add 1000+ line test suite with 40+ test cases
- Verify deterministic ordering and stable indices
- Test cross-checkpoint delta computation with stable keys
- Verify 40-70% size reduction on realistic datasets
- Add edge cases: empty results, file-less results, message overrides
- Enhance context-writer and schema tests for normalized output
- Add implementation plan for normalized schema approach
- Document alternative dual-emit approach (not pursued)
- Add comprehensive PR review with recommendations
- Record implementation thread and design decisions
…ecking

- Split packages/core/tsconfig.json into solution with 3 project references:
  - tsconfig.src.json: source files (src/**/*.ts)
  - tsconfig.test.json: test files (test/**/*.ts) with reference to src
  - tsconfig.build.json: production build (inherits from src)

- Updated typecheck script to use 'tsc -b' for project reference builds
- Added tsconfig.src.json to ESLint parserOptions.project

Enables proper type checking of test files via project references while
maintaining separate build contexts for source and tests.

Amp-Thread-ID: https://ampcode.com/threads/T-799ad280-c3d4-4589-b19a-6131844858bb
Co-authored-by: Amp <amp@ampcode.com>
- Add .js extensions to fixture imports (NodeNext requires explicit extensions)
- Fix ImportIndex reverse index test to query with .js extension
- Remove type assertions in service mock implementations
- Use proper Effect return types in test mocks

Fixes test failures caused by NodeNext module resolution requirements.

Amp-Thread-ID: https://ampcode.com/threads/T-799ad280-c3d4-4589-b19a-6131844858bb
Co-authored-by: Amp <amp@ampcode.com>
- Remove packages/core/test/rules.test.ts (redundant with test/rules/helpers.test.ts)
- Add JSDoc header documenting that helpers tests cover PatternEngine and BoundaryEngine
- Clarify that engines are internal implementation details not exported from public API

Boundary rule tests exist in test/rules/helpers.test.ts (5 tests) and
test/services/RuleRunner.test.ts (integration tests).

Amp-Thread-ID: https://ampcode.com/threads/T-799ad280-c3d4-4589-b19a-6131844858bb
Co-authored-by: Amp <amp@ampcode.com>
Auto-formatted files per @effect/dprint rules:
- packages/core/src/amp/normalizer.ts
- packages/core/src/amp/thread-manager.ts
- packages/core/test/amp/thread-manager.test.ts
- babel.config.cjs

Amp-Thread-ID: https://ampcode.com/threads/T-799ad280-c3d4-4589-b19a-6131844858bb
Co-authored-by: Amp <amp@ampcode.com>
- Add config merging utilities (deepMerge, isPlainObject, mergeConfig)
- Add PresetLoader service with Effect patterns (Context.Tag, Layer)
- Add rulesFromConfig builder for constructing rules from config
- Export new utilities and services in core/index.ts
- Add Config.presets field for preset names array
- Delete duplicate util/glob.ts (consolidated into utils/)

Tests:
- Add 50 new tests covering config merge, preset loading, rule builders
- All tests use Effect-first patterns

Related thread: T-dadffd74-9b38-4d2d-bb50-2f7dfcebd980

Amp-Thread-ID: https://ampcode.com/threads/T-725adb55-57d9-49d1-a637-3a756efeb447
Co-authored-by: Amp <amp@ampcode.com>
- Add PresetLoaderWorkspace layer for workspace-aware preset resolution
- Refactor rules loader to orchestrate core services (loadConfig, PresetLoader, mergeConfig, rulesFromConfig)
- Delete old CLI loaders (config.ts, presets.ts) - logic moved to core
- Update commands to use new loadRulesAndConfig orchestrator
- Use Effect.catchTag for precise error handling

Reduces CLI by ~1291 lines (60% reduction in loaders).
CLI now focuses on user-facing concerns (logging, errors) while core owns business logic.

Tests:
- Add 6 tests for workspace preset resolution layer
- Delete obsolete loader tests (replaced by core tests)

Related thread: T-dadffd74-9b38-4d2d-bb50-2f7dfcebd980

Amp-Thread-ID: https://ampcode.com/threads/T-725adb55-57d9-49d1-a637-3a756efeb447
Co-authored-by: Amp <amp@ampcode.com>
- Move all tests from src/__tests__/ to test/ (standard location)
- Update test imports to use ../../src/ paths
- Fix test schemas to match actual Config (migrations is array, MigrationGoalSchema uses type not mode)
- Add type guards for Effect error handling
- Fix barrel import violations (use direct imports)
- Update tsconfig files for new test structure

All 308 tests pass.

Related thread: T-dadffd74-9b38-4d2d-bb50-2f7dfcebd980

Amp-Thread-ID: https://ampcode.com/threads/T-725adb55-57d9-49d1-a637-3a756efeb447
Co-authored-by: Amp <amp@ampcode.com>
1. Fix docstrings: @effect-migrate/cli/amp → @effect-migrate/core/amp
2. Windows compatibility: use pathToFileURL for workspace preset imports
3. Precise error handling: Effect.catchTag('PresetLoadError') instead of catchAll
4. Documentation clarity:
   - Document module.default precedence in PresetLoader
   - Emphasize array replacement (not concatenation) in merge utilities

These improvements address Oracle review recommendations for production readiness.

Related thread: T-dadffd74-9b38-4d2d-bb50-2f7dfcebd980

Amp-Thread-ID: https://ampcode.com/threads/T-725adb55-57d9-49d1-a637-3a756efeb447
Co-authored-by: Amp <amp@ampcode.com>
- Add migration plan for future reference
- Update PR draft with migration scope
- Update changeset to include core exports

Related thread: T-dadffd74-9b38-4d2d-bb50-2f7dfcebd980

Amp-Thread-ID: https://ampcode.com/threads/T-725adb55-57d9-49d1-a637-3a756efeb447
Co-authored-by: Amp <amp@ampcode.com>
- Update tsconfig.json to solution-style with project references (cli, preset-basic)
- Fix import paths: util/glob.ts → utils/glob.ts after folder consolidation
- Improve type safety: Rule[] → ReadonlyArray<Rule> in RuleRunner
- Update preset-basic typecheck to use tsc -b for project references
- Add @types/node to preset-basic devDependencies
- Update pnpm-lock.yaml

Completes the TypeScript project references setup started in commit 3.

Related thread: T-dadffd74-9b38-4d2d-bb50-2f7dfcebd980

Amp-Thread-ID: https://ampcode.com/threads/T-725adb55-57d9-49d1-a637-3a756efeb447
Co-authored-by: Amp <amp@ampcode.com>
@aridyckovsky aridyckovsky changed the title feat(core,cli): normalized audit schema + core business logic feat(core,cli): normalized audit schema and core business logic Nov 7, 2025
@aridyckovsky aridyckovsky self-assigned this Nov 7, 2025
@aridyckovsky aridyckovsky added pkg:core Issues related to @effect-migrate/core package pkg:cli Issues related to @effect-migrate/cli package labels Nov 7, 2025
@aridyckovsky aridyckovsky added type:feature New feature or request effect-ts Effect-TS patterns and usage schema Schema validation and types migration Migration tooling and patterns priority:high High priority amp:audit Audit context and structured violation output amp:metrics Metrics context output for Amp changeset:next-minor Changes planned for next minor version pr:size:large Large PR (> 500 lines) labels Nov 7, 2025
aridyckovsky and others added 9 commits November 7, 2025 16:51
- Add module-level docstrings to PresetLoader and PresetLoaderWorkspace
- Add @category and @SInCE tags to all exports
- Document resolution strategy and usage patterns
- Include examples for preset loading in both contexts
- Update PR draft with concise description
- Add packages/core/src/amp/package-meta.ts with getPackageMeta()
- Export getPackageMeta from packages/core/src/amp/index.ts
- Consolidates duplicate package.json reading logic from context-writer and metrics-writer
- Supports both production (build/) and development (tsx) environments
- Provides consistent toolVersion and schemaVersion across all Amp output files

Amp-Thread-ID: https://ampcode.com/threads/T-25083024-e5cb-4ee3-a5b5-74a9e65ddd8d
Co-authored-by: Amp <amp@ampcode.com>
Schema changes in packages/core/src/schema/amp.ts:
- Add auditRevision field to ThreadReference (links thread to specific audit)
- Add auditRevision field to ThreadEntry with default value of 1
- Replace version with schemaVersion/toolVersion in ThreadsFile
- Add info counter to MetricsSummary (separate from warnings)
- Replace version with schemaVersion/revision in AmpMetricsContext
- Update JSDoc to document auto-detection via AMP_CURRENT_THREAD_ID

Breaking changes:
- ThreadsFile.version → ThreadsFile.schemaVersion + toolVersion
- AmpMetricsContext.version → AmpMetricsContext.schemaVersion + revision
- FindingsSummary now includes separate info counter (not counted as warnings)

Amp-Thread-ID: https://ampcode.com/threads/T-25083024-e5cb-4ee3-a5b5-74a9e65ddd8d
Co-authored-by: Amp <amp@ampcode.com>
…output

context-writer.ts:
- Auto-detect AMP_CURRENT_THREAD_ID environment variable during audit
- Generate smart tags (errors:N, warnings:N, top-3 rules) for auto-detected threads
- Link threads to audit revision via auditRevision field
- Filter threads in audit.json to only include current revision's thread
- Enhanced badges.md with info counter, table format, top 5 issues
- Add severity-consistent badge colors (red/orange/blue)
- Include metrics.json in index.json files reference
- Use getPackageMeta from package-meta module

metrics-writer.ts:
- Accept revision parameter to link metrics to audit.json
- Calculate progress percentage relative to previous revision's baseline
- Support info severity counter in summary
- Use getPackageMeta instead of duplicate logic
- Remove index.json update (now handled by context-writer)

thread-manager.ts:
- Replace version with schemaVersion/toolVersion throughout
- Track auditRevision when adding threads
- Preserve original auditRevision when merging thread metadata
- Use getPackageMeta for consistent toolVersion
- Migrate to Effect.gen for readThreads (no sync decode)

Amp-Thread-ID: https://ampcode.com/threads/T-25083024-e5cb-4ee3-a5b5-74a9e65ddd8d
Co-authored-by: Amp <amp@ampcode.com>
…chema

Formatters:
- console.ts: Display info counter alongside errors/warnings
- json.ts: Add Schema.Class validation, include info field in summary
- metrics.ts: Add info counter to metrics display

Commands:
- audit.ts: Pass revision to formatters for consistency
- metrics.ts: Format metrics using new AmpMetricsContext schema structure

Loaders:
- rules.ts: Minor cleanup and formatting improvements

All formatters now support the new info severity level separate from warnings,
aligning with the normalized schema changes in @effect-migrate/core.

Amp-Thread-ID: https://ampcode.com/threads/T-25083024-e5cb-4ee3-a5b5-74a9e65ddd8d
Co-authored-by: Amp <amp@ampcode.com>
Core tests:
- context-writer.test.ts: Update expectations for new schema fields (schemaVersion, revision, info counter)
- thread-manager.test.ts: Update for ThreadsFile schema changes (schemaVersion/toolVersion)

CLI tests:
- thread.test.ts: Align with new ThreadEntry schema structure

Supporting files:
- schema/loader.ts: Minor updates for schema compatibility
- services/RuleRunner.ts: Test-related adjustments

All tests now validate the enhanced schema with revision tracking,
auto-thread detection, and info severity support.

Amp-Thread-ID: https://ampcode.com/threads/T-25083024-e5cb-4ee3-a5b5-74a9e65ddd8d
Co-authored-by: Amp <amp@ampcode.com>
…d usage

- Update root README with accurate CLI commands and output schemas
- Add complete CLI README with all options and troubleshooting
- Add comprehensive core README documenting full exported API
- Reflect dogfooding status and unstable APIs across all READMEs
- Document complementary relationship with @effect/language-service
- Include real rule examples from preset-basic implementation
- Add proper roadmap with planned features (SQLite, Polars, MCP, etc.)

Resolves #24

Amp-Thread-ID: https://ampcode.com/threads/T-8ded36f2-0a85-43f1-af29-92d1d5c1d831
Co-authored-by: Amp <amp@ampcode.com>
@aridyckovsky aridyckovsky merged commit d4ffea4 into main Nov 8, 2025
1 check passed
@github-actions github-actions bot mentioned this pull request Nov 8, 2025
@aridyckovsky aridyckovsky deleted the feat/normalized-audit-schema branch November 8, 2025 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

amp:audit Audit context and structured violation output amp:metrics Metrics context output for Amp changeset:next-minor Changes planned for next minor version effect-ts Effect-TS patterns and usage migration Migration tooling and patterns pkg:cli Issues related to @effect-migrate/cli package pkg:core Issues related to @effect-migrate/core package pr:size:large Large PR (> 500 lines) priority:high High priority schema Schema validation and types type:feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants