Skip to content

chore(layering): derive the contracts export inventory from package.json - #2297

Merged
thymikee merged 2 commits into
mainfrom
claude/layering-contracts-exports-single-copy
Sep 5, 2026
Merged

chore(layering): derive the contracts export inventory from package.json#2297
thymikee merged 2 commits into
mainfrom
claude/layering-contracts-exports-single-copy

Conversation

@thymikee

@thymikee thymikee commented Sep 5, 2026

Copy link
Copy Markdown
Member

Summary

scripts/layering/package-boundaries.test.ts pinned every packages/contracts export
subpath by hand (~115 entries, deepEqual), so every packages/contracts/package.json
change also required a matching test edit. The pin was replaced with a structural check:
every exports target must resolve to an existing, tracked source file. Review (#2297)
found that check alone did not catch the export SURFACE widening or shrinking, since both
sides were read from the same manifest object. A follow-up commit adds
contracts-exports.snapshot.json, an independently committed baseline regenerated by
generate-contracts-exports-snapshot.ts, and diffs the live export list against it. A
subpath added or removed now fails until the contributor reruns the generator and reviews
the snapshot diff — restoring the widen/shrink guarantee the old inline pin gave, while
still removing the ~120-line hand-typed array.

Validation

Tested at 53c925f.

  • node --test --experimental-strip-types scripts/layering/package-boundaries.test.ts (14/14 pass)
  • pnpm check:layering (198/198 pass)
  • pnpm check:quick (oxlint + typecheck, clean)
  • pnpm format (no changes needed)
  • Planted red (gates commit): widened packages/contracts/package.json#exports with a
    throwaway subpath, then separately deleted ./wait — both failed the new deepEqual with
    the regenerate-and-review message; reverted before pushing.
  • Planted red (original commit): a bogus subpath resolving to a missing file, and a
    subpath resolving to a must-not-resolve file — both failed as expected; reverted.

Full affected gate: green at 53c925f (pnpm check:affected --run; 32 local gates passed: format, lint, typecheck, layering, di-seams, fallow, mcp-metadata, build, package, integration-node, macos-coverage, vitest-related, integration-progress, replay-compat, daemon-wire-compat, affected-selector, gate-manifest, depgraph, tmpdir-leaks, coverage-model, wire-compat-model, production-exports, bundle-owner-files, fixture-cache, fixture-fallback, command-docs, agent-guidance, xctest-selection, maestro-conformance, mutation-model)

R11's package-boundaries test pinned every packages/contracts export
subpath by hand (~115 entries, compared with deepEqual), so every merge
that touched packages/contracts/package.json also had to hand-edit the
pin. Replace it with a structural check derived from the manifest
itself: every exports target must resolve to an existing, tracked
source file, and the number of resolved targets must equal
Object.keys(manifest.exports).length. The must-not-resolve negative
list (Node resolution enforces the exports map at runtime) is
untouched.
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 2.61 MB 2.61 MB 0 B
JS gzip 878.9 kB 878.9 kB 0 B
npm bundled raw 2.61 MB 2.61 MB 0 B
npm bundled gzip 878.9 kB 878.9 kB 0 B
npm tarball 1.04 MB 1.04 MB -6 B
npm unpacked 3.52 MB 3.52 MB 0 B
npm clean-installed 3.52 MB 3.52 MB 0 B

npm unpacked components

Component Base Current Diff
JS / dist source 2.77 MB 2.77 MB 0 B
Apple runner source/project 544.4 kB 544.4 kB 0 B
Apple snapshot presentation source 33.8 kB 33.8 kB 0 B
Apple Simulator snapshot bridge source 30.5 kB 30.5 kB 0 B
macOS helper source 54.8 kB 54.8 kB 0 B
Android helper artifacts 43.3 kB 43.3 kB 0 B
Other package files 46.7 kB 46.7 kB 0 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 31.0 ms 30.7 ms -0.3 ms
CLI --help 81.1 ms 80.3 ms -0.9 ms

Top changed chunks: no changes in the largest emitted chunks.

Top changed packed files

No changed packed files.

assertExportTargetsMatchManifest's two checks (targets resolve to
tracked files, count equals manifest.exports keys) both read from the
same manifest.exports object, so a subpath added or removed moves both
sides together and the equality holds regardless -- the widen/shrink
guarantee the deleted ~120-line CONTRACT_EXPORTS pin gave was silently
gone (#2297 review).

Add scripts/layering/contracts-exports.snapshot.json, an independently
committed baseline regenerated by the new
generate-contracts-exports-snapshot.ts, and deepEqual the live export
specifiers against it. A subpath change now fails until the
contributor reruns the generator and reviews the snapshot diff --
"run a script and commit its output" instead of hand-retyping an
alphabetized array, so the original maintenance-burden goal holds too.

Planted red: widened packages/contracts/package.json#exports with a
throwaway "./planted-red-widen" subpath, then separately deleted the
"./wait" subpath; `node --test --experimental-strip-types
scripts/layering/package-boundaries.test.ts` failed both times on the
new deepEqual with the regenerate-and-review message. Reverted before
committing.
@thymikee

thymikee commented Sep 5, 2026

Copy link
Copy Markdown
Member Author

Sentinel review at 53c925fa4912879665b82e9dd18fe6263c312c3e.

No actionable findings. The committed snapshot retains explicit export-surface review while manifest/tracked-target checks avoid the old hand-maintained inline inventory. Add/remove/missing-target planted-red evidence is recorded; CI is green. Pure tooling; no device proof needed.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Sep 5, 2026
@thymikee
thymikee merged commit a04b587 into main Sep 5, 2026
18 of 19 checks passed
@thymikee
thymikee deleted the claude/layering-contracts-exports-single-copy branch September 5, 2026 18:47
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-05 18:47 UTC

thymikee added a commit that referenced this pull request Sep 5, 2026
* origin/main:
  perf: bundle runtime dependencies and report full install size (#2310)
  ci: avoid unrelated Apple runner cache invalidation (#2303)
  fix(web): preserve the backend ref so snapshot refs match actionable refs (#2283)
  test(daemon): session-open-url-prewarm through the request seam (#2304)
  test(daemon): session-devices-batch-runtime through the request seam (#2305)
  chore(gates): layering baselines ratchet against merge-base (#2299)
  test(daemon): one typed conformance helper for the daemon runtime suites (#2298)
  chore(layering): derive the contracts export inventory from package.json (#2297)
  perf: bundle tar-stream to reduce install footprint (#2286)
  docs: simplify agent context and resolve conflicting guidance (#2287)
  refactor(cli): let help resolve command aliases itself and retire R12 (#2293)
thymikee added a commit that referenced this pull request Sep 5, 2026
* origin/main:
  perf: bundle runtime dependencies and report full install size (#2310)
  ci: avoid unrelated Apple runner cache invalidation (#2303)
  fix(web): preserve the backend ref so snapshot refs match actionable refs (#2283)
  test(daemon): session-open-url-prewarm through the request seam (#2304)
  test(daemon): session-devices-batch-runtime through the request seam (#2305)
  chore(gates): layering baselines ratchet against merge-base (#2299)
  test(daemon): one typed conformance helper for the daemon runtime suites (#2298)
  chore(layering): derive the contracts export inventory from package.json (#2297)
  perf: bundle tar-stream to reduce install footprint (#2286)
  docs: simplify agent context and resolve conflicting guidance (#2287)
  refactor(cli): let help resolve command aliases itself and retire R12 (#2293)
  refactor(commands): retire the navigation-only type projection (#2294)
  feat(runtime): route managed leases through contained transports (#2285)
  refactor(contracts): build unavailable runtime facts once (#2291)
  refactor(cli): derive the common flag readers from the common-field table (#2292)
  feat(daemon): add managed allocation operation journal (#2284)
thymikee added a commit that referenced this pull request Sep 5, 2026
* origin/main:
  perf: bundle runtime dependencies and report full install size (#2310)
  ci: avoid unrelated Apple runner cache invalidation (#2303)
  fix(web): preserve the backend ref so snapshot refs match actionable refs (#2283)
  test(daemon): session-open-url-prewarm through the request seam (#2304)
  test(daemon): session-devices-batch-runtime through the request seam (#2305)
  chore(gates): layering baselines ratchet against merge-base (#2299)
  test(daemon): one typed conformance helper for the daemon runtime suites (#2298)
  chore(layering): derive the contracts export inventory from package.json (#2297)
  perf: bundle tar-stream to reduce install footprint (#2286)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant