feat(entrypoints): file-convention and manifest matchers; level invariance with every tier firing - #163
Merged
Merged
Conversation
…l-called free functions)
…er firing; regenerate README help
…t missing pages/api defaults, bad manifests; validate file globs at load
rahlk
force-pushed
the
feat/issue-161-entrypoint-files
branch
from
September 6, 2026 12:58
6e125f6 to
9a060ad
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #161. Unit 5 of the entrypoint spec (#150); plan
docs/design/plans/2026-09-03-entrypoints-units-2-5.md, Tasks 7–9. Stacked on #160 (unit 4) — this PR targets that branch, notmain. The last unit: with it, #72 is complete.Two declaration forms python never faced, and the proof that the whole pass is level-free.
What this adds
files:rules match a glob over the module file key (**/,*,{a,b}, anchored). Each named export resolves to the exported callable;defaultis detected from the declaration's source text, becauseTSModule.exportsrecords onlyexport { }and re-exports. Shipped: Next.js app router (app/**/route.ts→GET/POST/…,routefrom the path), Next.js pages API (default), SvelteKit+server.ts. Gated: withoutnextin the manifest, the same files register nothing.package.jsonmainandbin(string or name→path object) resolve to a module (withdist/→src/and extension fallbacks); the free functions that module calls at top level getconfidence: declaredrecords withvia= the module id. A path that resolves to nothing, or a module with no such call, is counted, never fabricated. This decides the spec's open question about module-level entrypoints without adding a field to the shared vocabulary.calls:heuristic tier andmanifest.main— L1 cold, then L2–L4 warm against the cache, byte-identical. The unit-1 contract test only proved the empty case; this closes that gap.--helpblock regenerated for--entrypoint-rules.Verification
bun test— 286 pass, 0 fail; container tests run (final unit)pipeline.tsandmatching.tsin full for cross-unit seams): stage order and never-doubles across all six tiers verified; level/cache invariance verified as genuinely cache-warm; gate holds. Two Important findings — both silent misses — fixed in one wave and re-reviewed:--no-artifact-textstoressource: ""and??did not fall through, so the manifest tier vanished without a count; andpages/apidefaults spelledexport default handler;orexport default async (req, res) => {}went unfound and uncounted. Both now resolve or are counted. Three one-line minors landed with them: malformedpackage.jsonis counted, file-rule globs are validated at load, a consistency nit. Re-review: all five addressed, no new breakage.Decisions worth your eye
routeFromFileKeyis a convention pinned by tests, not a contract:app/users/route.ts→/users,app/route.ts→/,pages/api/hello.ts→/api/hello,src/routes/x/+server.ts→/src/routes/x.main-called root, so the manifest stage runs last and pushes unconditionally.noRepoSectionslives on the unmerged feat(cli): --program shard selector, --no-repo-sections, and shard IR #149, not this branch; the manifest matcher's disk fallback is tested by a direct unit call with an empty artifact map.Deferred (triaged by the final review — nothing blocks)
Follow-up issue #162 collects the coverage gaps and raw-text seams: calls never-doubles against a live
files:claim;transitive: false/ emptydispatchtests; a stronger file-gate test; the callless-module manifest branch; theliteralOf/routeOf/isSignaturetrio;resolveHandlerbinding a bare identifier to a same-named class method; thepages/api/index.tsroute convention. Marked never: theneo4j-schema.test.tsoptions literal,resolveByTypekeyed per type, splittingmatching.ts.