docs(spec): entrypoint detection for typescript, matching python - #150
Conversation
|
Amended in
That makes the import-table resolver the primary resolution mechanism in TS (python's is a fallback behind Jedi), and adds a unit 0: fix Rules-format decision (made with the user): one |
|
Unit 0 is up as its own PR, per the amended decomposition: |
|
Unit 1 is up: the contract — schema, Neo4j projection (report on |
…keleton (#154) Unit 1 of the entrypoint spec (#150): the CONTRACT, before any detector exists. The fields were de-advertised in #60 because nothing populated them; this lands their shape so they exist at every -a and a consumer can already tell "no entrypoints" from "no pass ran". `TSEntrypoint` and `TSEntrypointReport` mirror python's `PyEntrypoint` / `PyEntrypointReport` field for field. `entrypoints: []` and `is_entrypoint: false` are stamped on every callable and every CLASS by a per-run pass -- like heritage, so the cached tree stays free of them and the wire always carries them. Interfaces, enums, aliases and namespaces never carry them: python stamps PyClass, and nothing else can be an entrypoint. `entrypoint_report` sits on the application root, empty. Neo4j mirrors python's projection exactly: `is_entrypoint` / `entrypoint_frameworks` on :TSClass and :TSCallable, and on :TSApplication the report as `entrypoint_frameworks` plus `entrypoint_report_json` (sorted-key JSON, since Neo4j has no map type and python encodes it the same way). Best-effort by contract: the pass records into `report.errors` rather than throwing, so a failure here loses flags, never the analysis. Additive; SCHEMA_VERSION unmoved (#144). The root-envelope key list in schema-v2.test.ts gains the one new key.
4656824 to
76d8042
Compare
|
Units 2–5 are implemented (#156 → #158 → #160 → #161, stacked). Appended a "Decisions taken during implementation" section to the spec recording how each open question was settled — file-convention entrypoints attach to callables (no module-level field); manifest entrypoints attach to the entry module's top-level-called free functions; module call sites captured INTERNAL and kept in the cache; |
Spec for TypeScript entrypoint detection at parity with codeanalyzer-python's #27. Committed as provenance; no code.
Starting point
TypeScript has none.
grep -rniE "entry_?point" src/returns one hit, and it is a bundler comment indataflow/pool.ts.codeanalyzer/entrypoints/, 5 filesPyEntrypoint,PyEntrypointReportis_entrypoint,entrypoint_frameworks--entrypoint-rulesWithout this, the analyzer emits a call graph with no distinguished roots — so a consumer cannot ask what is reachable from outside the application, which is the first question any taint or attack-surface query asks.
What the spec commits to
Mirror python's contract exactly:
TSEntrypoint/TSEntrypointReport,entrypoints+is_entrypointonTSCallableandTSType, the same Neo4j properties, a declarative rules file with a stage-0 framework gate,--entrypoint-rulesfor user rules, gradeddeclared|certain|heuristicconfidence,via:dispatch modelling, and a coverage report. Level-free L1 post-pass; rule loading is a hard error, detection is best-effort and never aborts the analysis.The part that cannot be ported
Python's engine has two matchers — decorators and base classes — and they cover its ecosystem. They do not cover TypeScript's:
app.get('/p', h)— a callapp/**/route.ts,+server.tshandlerbin/mainin package.jsonSo the rules format has to be designed for three matcher kinds python never needed, rather than copied and extended later. Two decisions are called out explicitly: whether a file-convention entrypoint can hang off a module (python's schema has no module-level entrypoints, so this would diverge from the shared vocabulary), and how call-site matching stays level-free — recommendation is a syntactic L1 match at
confidence: heuristicrather than gating Express to-a >= 2and breaking "identical at every -a".What TS has going for it
Better positioned than python was: decorators are structured and checker-resolved as of #143 —
qualified_nameis the direct analog of the Jedi definition path python matches on, andpositional_arguments/keyword_argumentsare exactly whatroute: {from: positional, index: 0}needs. Heritage is resolved tocan://ids, so transitive base matching is a graph walk rather than a name match. And the stage-0 gate has two ready sources inTSImportand the artifact layer'sTSDependency, where python had to regex manifests.Recommendation on #72
#72 ("entrypoint finders (Express/Angular routes)") is scoped too narrowly — two frameworks and no engine. Built as written it would produce hardcoded detectors with no rules file, no confidence grading, no coverage report and no extensibility, then need rewriting for parity. Retitle it or close it in favour of the engine-shaped unit.
Caveats it states plainly
Controllerin a non-NestJS project must not register, which is why the stage-0 gate is not an optimisationheuristic; Express handlers registered via a variable or helper will be missed, and that belongs in the report'sunresolvedcounts