Skip to content

feat(registry): add repo registry — machine-readable module/file/owner/criticality map - #737

Closed
diberry wants to merge 4 commits into
devfrom
squad/736-repo-registry
Closed

diberry wants to merge 4 commits into
devfrom
squad/736-repo-registry

Conversation

@diberry

@diberry diberry commented Apr 2, 2026 •

Copy link
Copy Markdown
Contributor
  • Explore codebase and understand current state
  • Fix parsePackages() to sort directory entries (determinism)
  • Fix resolveModuleToPackage() to handle package-qualified paths (packages/squad-sdk/src/, packages/squad-cli/src/)
  • Fix resolveFileToModule() to derive package from stripped file-path prefix (returns correct squad-sdk vs squad-cli for SDK files)
  • Add --out <path> flag to generator script (enables test isolation)
  • Fix registry-sync.test.ts to write to temp file instead of overwriting committed file
  • Fix registry-sync.test.ts to compare parsed JSON objects (avoids EOL false positives on Windows)
  • Fix misleading test description ("scaffolding" → "medium or unknown tier")
  • Regenerate .squad/repo-registry.json with all fixes applied
  • All 40 registry tests pass

Copilot AI review requested due to automatic review settings April 2, 2026 05:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a machine-readable repository registry (.squad/repo-registry.json) that maps file paths to modules/owners/criticality, plus generator + query utilities and CI tests to keep the registry in sync with its sources.

Changes:

  • Added scripts/generate-repo-registry.mjs to generate .squad/repo-registry.json from .squad/routing.md, templates.ts, and package.json workspaces.
  • Added scripts/registry-utils.mjs with query helpers for resolving file → module/owner/criticality/package.
  • Added Vitest coverage: unit tests for utilities + a sync/freshness guard test; added npm run registry script and changelog entry.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
scripts/generate-repo-registry.mjs Implements registry generation by parsing ownership table, template manifest, and workspaces.
scripts/registry-utils.mjs Provides consumer-facing query helpers over the generated registry.
test/registry-sync.test.ts CI freshness guard that regenerates and diffs registry output.
test/registry-utils.test.ts Unit tests for registry query utilities.
.squad/repo-registry.json Committed generated registry output.
.squad/routing.md Adds parsing constraints / pointer to generated registry.
package.json Adds npm run registry script.
CHANGELOG.md Documents the new repo registry feature.

Comment thread test/registry-sync.test.ts Resolved
Comment thread scripts/generate-repo-registry.mjs Resolved
Comment thread scripts/generate-repo-registry.mjs Resolved
Comment thread scripts/registry-utils.mjs Resolved
Comment thread test/registry-utils.test.ts Resolved
Comment thread test/registry-sync.test.ts Resolved
@diberry

diberry commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please review this PR. Focus on: Is the routing.md parser robust? Are the utility functions correct? Is the generated JSON schema complete? Any edge cases in resolveFileToModule()?

@diberry

diberry commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

🏗️ Architecture Review: Repo Registry (PR #737)

STATUS: ✅ APPROVE

Summary

PR #737 implements a robust, machine-readable repository registry that correctly captures module ownership, criticality tiers, and file mappings. The design is sound, extensible, and ready to support downstream consumers (#670, #733).

Strengths

  • Schema correctness: Registry structure properly normalized with clear top-level keys (modules, criticalFiles, packages, templateFiles, metadata)
  • Source integrity: SHA256 hashes for routing.md, templates.ts, and package.json enable change detection in CI
  • Complete module coverage: All 19 modules from routing.md correctly parsed and stored with primary + optional secondary owners
  • Utility API solid: Six well-documented query functions (loadRegistry, resolveFileToModule, getModuleOwner, getFileCriticality, getPackageForFile, getModulesByOwner) provide clean downstream interfaces
  • Fallback logic clear: Unknown files → Flight ownership; unknown criticality → impact:0; lazy caching prevents repeated I/O
  • Test guards effective: Freshness sync test catches source drift; normalize-timestamp prevents false positives; full JSON validation included
  • Forward-compatible: Package prefix normalization and longest-prefix matching support both PRD: Versioned file layout manifest - single source of truth for directory structure #670 (file layout manifest) and feat: PR architectural impact analysis — blast radius, module boundaries, reviewer routing #733 (PR impact analysis) without breaking changes

Notes

  • Registry generation script robustly handles malformed routing.md with explicit error messages—excellent for catch-and-fix workflow
  • Template extraction correctly identifies 29 entries across 4 tiers (critical, high, medium); CI workflows and squad.agent.md properly marked as critical
  • All module entries include package mapping or null for root-level tests

Recommendation

Ready to merge. Meets all architectural criteria for module registry. Ready for #670 and #733 to import and consume.

@diberry

diberry commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

Test Coverage Review - PR #737 (Registry Sync)

Test Execution Summary

  • All tests passing: 40 tests across 2 test files
  • Test files: registry-sync.test.ts (4 tests), registry-utils.test.ts (36 tests)
  • Execution time: 1.63s
  • Exit code: 0

Timestamp Normalization - SOLID

  • normalizeTimestamp() helper correctly replaces generated timestamps with placeholder
  • Regex pattern /"generated"\s*:\s*"[^"]*"/ matches with flexible whitespace handling
  • Both committed and freshly generated registries normalized before comparison
  • Prevents false failures from timestamp drift

Edge Cases Covered

Unknown paths:

  • README.md resolves to unknown module with Flight primary
  • .github/workflows/squad-ci.yml resolves to unknown (outside module table)
  • Unrecognized module keys default to Flight primary

Module resolution robustness:

  • Longest-prefix matching for nested paths (e.g., src/cli/shell/components/)
  • Trailing slash consistency across path variants
  • File-level entries (e.g., src/index.ts) vs. directory paths
  • Windows vs. Unix path normalization

Malformed routing.md:

  • Script throws explicit error if "## Module Ownership" section missing
  • Validates minimum row format (modulePath + primary owner required)
  • Normalizes emoji characters before parsing

Package discovery:

  • squad-sdk and squad-cli correctly identified
  • Root-level files return null for package lookup
  • .github files return null for package

Freshness Test is Robust

  • Pattern: Regenerate -> read committed -> normalize both -> deep-compare
  • Sync guard: Fails if source files (routing.md, templates.ts, package.json) edited without running npm run registry
  • CI integration: Detects drift before merge
  • Script exit check: Validates generator returns code 0
  • JSON validation: Confirms committed registry is parseable
  • Required keys check: Verifies all top-level properties exist

Query API Coverage

  • resolveFileToModule(): 8 scenarios (known modules, nested specificity, unknown paths, trailing slashes, file-level entries)
  • getModuleOwner(): 5 scenarios (known/unknown modules, primary/secondary fallbacks, null secondary handling)
  • getFileCriticality(): 6 scenarios (critical files, high tier, default fallbacks)
  • getPackageForFile(): 5 scenarios (workspace packages, root/.github files returning null)
  • getModulesByOwner(): 5 scenarios (multi-module owners, single-module owners, empty results)
  • loadRegistry(): 7 scenarios (top-level structure, module integrity, hash metadata)

Minor Observations (Not blockers)

  1. Criticality fallback: getFileCriticality() returns 'medium' for any file in known modules; consider if this should distinguish between unknown modules ('unknown') vs. unmapped files in known modules ('medium')
  2. Hash verification not in tests: Registry metadata hashes are generated but not validated in tests - consider adding a test to verify hashes regenerate consistently
  3. Secondary owner can be null: Tests verify this, but might warrant defensive checks in downstream consumers

VERDICT: APPROVE

Rationale:

  • All 40 tests passing with 100% execution success
  • Timestamp normalization prevents flaky CI checks
  • Comprehensive edge case coverage for unknown/malformed input
  • Query API well-tested against real registry data
  • Freshness guard properly detects source file drift
  • Clear error messages guide developers to fix violations

Ready to merge. Test suite is production-ready and provides strong guardrails for registry freshness and drift detection.

@diberry

diberry commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

CI/Process Review — PR #737 (Repo Registry)

Status: ✅ APPROVE

All process and CI requirements met. Branch is clean and ready to merge.

Verification Checklist

✅ Commit Structure

  • Count: Exactly 1 commit on branch (dev..squad/736-repo-registry)
  • Message: Clear semantic commit: \ eat(registry): add repo registry — machine-readable module/file/owner/criticality map\
  • Co-authored: Includes Copilot trailer ✓

✅ CHANGELOG Entry

✅ Package.json Updates

  • New script added: "registry": "node scripts/generate-repo-registry.mjs"\ (line 21)
  • Location: Correct alphabetical order among dev scripts
  • No version bump: version remains \

Copilot AI commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

@copilot Please review this PR. Focus on: Is the routing.md parser robust? Are the utility functions correct? Is the generated JSON schema complete? Any edge cases in resolveFileToModule()?

Reviewed and addressed. Here's what was found and fixed in commit 4426cc8:

routing.md parser — Robust. It guards against malformed rows with a clear error, stops at the next ## heading, and skips header/separator rows reliably.

utility functions — Two correctness issues fixed:

  • resolveFileToModule() was returning package: "squad-cli" for squad-sdk files. It now tracks which workspace prefix was stripped from the path and returns that as the authoritative package, so packages/squad-sdk/src/config/init.ts correctly resolves to { ..., package: "squad-sdk" }.
  • resolveModuleToPackage() now handles packages/squad-sdk/src/ and packages/squad-cli/src/ qualified paths in addition to bare src/ paths, making it forward-compatible with per-package module keys.

generated JSON schema — Complete and well-structured. All required fields (modules, criticalFiles, packages, templateFiles, metadata, criticalityTiers) are present.

resolveFileToModule() edge cases — Longest-prefix matching is correct (sorted descending by length). The unknown fallback now preserves the matched package (e.g. a file in packages/squad-sdk/ with no module match returns package: "squad-sdk", not null).

Additional fixes applied from automated review:

  • parsePackages() now sorts workspace entries alphabetically for deterministic JSON output across filesystems.
  • Sync test writes to a temp file (os.tmpdir()) instead of overwriting the committed registry — working tree stays clean after test runs.
  • Sync test compares parsed JSON objects instead of raw strings — eliminates CRLF/LF false failures on Windows.
  • Test description corrected from "scaffolding" to "medium or unknown tier" to match the actual tier vocabulary.

@diberry
diberry force-pushed the squad/736-repo-registry branch from 4426cc8 to bc87f79 Compare April 2, 2026 12:15
@diberry
diberry force-pushed the squad/736-repo-registry branch from d9cf324 to 5658765 Compare April 2, 2026 12:35
diberry added a commit that referenced this pull request Apr 2, 2026
…733 (#748)

Implements the registry query layer PRD (docs/proposals/registry-query-layer.md).
Shared foundation that both #670 (layout manifest) and #733 (impact analysis) consume.

- scripts/registry-query.mjs: 5 exported functions (loadRegistry, resolveFile,
  analyzeFiles, computeRiskTier, getInvolvedOwners)
- test/registry-query.test.ts: 33 test cases covering all acceptance criteria
- Includes PR #737 dependency files (registry-utils.mjs, repo-registry.json)

Depends on: PR #737 (repo registry data)
Feeds into: #670, #733

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
diberry and others added 3 commits April 2, 2026 14:49
- Archive: 71 decisions (>30d), 10 (7-30d)
- Merge: 13 inbox decisions into canonical log
- Summarize: Flight, EECOM, FIDO histories (kept recent entries)
- Log: Bug-fix-pipeline session recorded
- Deduplicate: 73 unique decisions
- decisions.md: 385.8 KB -> 103.7 KB

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@diberry
diberry force-pushed the squad/736-repo-registry branch 2 times, most recently from a5bb47b to 539a2de Compare April 2, 2026 22:32
Reset .squad/ files to match origin/dev — these changes were not part of the PR content.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@diberry diberry closed this Apr 3, 2026
@bradygaster
bradygaster deleted the squad/736-repo-registry branch August 8, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants