fix: require a compiled artifact for entrypoints.jobs
Module discovery gated the compiled-ESM rule on an allowlist, `["schema", "server", "ui"]`, so `entrypoints.jobs` accepted `./src/jobs/index.ts`. Every other executable entrypoint required a built `.js` or `.mjs`; `jobs` did not, purely because it was never added to that list. It is the second entrypoint to slip through the same way — `ui` did too, until Phase 6A added it explicitly — which is the argument against the allowlist rather than against `jobs`. The rule is now expressed as "every entrypoint except a directory entrypoint", with `migrations` the only member of that set. A new manifest entrypoint therefore defaults to the stricter validation instead of silently escaping it. The same constant replaces the two existing `=== "migrations"` special cases for the file/directory kind check and its message, so the one thing that distinguishes `migrations` is stated once. The directory message is now templated and produces byte-identical text. Every other entrypoint guarantee is untouched: package-relative paths, no traversal, inside-package before and after symlink resolution, the artifact must exist, and it must be a file. No runtime was added. `entrypoints.jobs` still has no consumer — it is declared, validated, and never executed — exactly as it has been since ADR 0006, and as `ui` was before its host loader existed. The manifest schema is unchanged and this stays within v4: the field, its type, and its optionality are all the same, and only discovery's validation of the declared path tightened. Compatibility impact is nil in first-party code: no module, template, or fixture declares a `jobs` entrypoint at all. A third-party module declaring a source-TypeScript path would now fail discovery, which is the intended correction. Tests cover accepted `.js` and `.mjs`, rejected `.ts`/`.tsx`/`.cjs`, a missing artifact, a directory, a symlink escaping the package, and that discovery still never evaluates the artifact. The three rejection cases were confirmed to fail against the previous implementation. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ff159a04dc
commit
3f9b5e3cb0
@@ -272,3 +272,9 @@ every real feature module. `entrypoints.jobs` still accepts source TypeScript wh
|
||||
entrypoints require compiled output — that inconsistency is unchanged and remains open, because this
|
||||
pass did not centralize executable-entrypoint validation and fixing it here would have been unrelated
|
||||
scope.
|
||||
|
||||
> **Correction — this deferred item is closed.** `entrypoints.jobs` now requires a compiled `.js` or
|
||||
> `.mjs` artifact, exactly like `server`, `schema`, and `ui`. Module discovery expresses the rule as
|
||||
> "every entrypoint except the directory entrypoint (`migrations`)", so the omission that let `jobs`
|
||||
> escape it cannot recur. No jobs runtime was added: the entrypoint is still declared, validated, and
|
||||
> never executed. Every other item in this list remains deferred.
|
||||
|
||||
@@ -198,3 +198,9 @@ loading; and every real feature module. `entrypoints.jobs` still accepts source
|
||||
other executable entrypoints require compiled output; this pass reused the *path* grammar from
|
||||
`@ekklesia/contracts` but did not centralize the *extension* rule, so that inconsistency is
|
||||
unchanged and still open.
|
||||
|
||||
> **Correction — this deferred item is closed.** `entrypoints.jobs` now requires a compiled `.js` or
|
||||
> `.mjs` artifact, exactly like `server`, `schema`, and `ui`. Module discovery expresses the rule as
|
||||
> "every entrypoint except the directory entrypoint (`migrations`)", so the omission that let `jobs`
|
||||
> escape it cannot recur. No jobs runtime was added: the entrypoint is still declared, validated, and
|
||||
> never executed. Every other item in this list remains deferred.
|
||||
|
||||
@@ -197,3 +197,9 @@ is unchanged and still open. The permission-id typing gap (`permissions.has` tak
|
||||
a typo silently hides a control) is likewise unchanged: the browser-safe split did not produce a
|
||||
clean answer for it, and inventing one would have meant shipping generated constants this phase does
|
||||
not need.
|
||||
|
||||
> **Correction — this deferred item is closed.** `entrypoints.jobs` now requires a compiled `.js` or
|
||||
> `.mjs` artifact, exactly like `server`, `schema`, and `ui`. Module discovery expresses the rule as
|
||||
> "every entrypoint except the directory entrypoint (`migrations`)", so the omission that let `jobs`
|
||||
> escape it cannot recur. No jobs runtime was added: the entrypoint is still declared, validated, and
|
||||
> never executed. Every other item in this list remains deferred.
|
||||
|
||||
@@ -153,11 +153,11 @@ module's own HTTP routes, and creating relationship-derived grants automatically
|
||||
own business logic, are both still later work; this only makes a declared permission *usable*
|
||||
through Core's existing, generic surface.
|
||||
|
||||
Server and optional schema and UI entrypoints must be compiled ESM `.js` or `.mjs` files. The
|
||||
optional migration entrypoint is a directory. All entrypoints begin with `./`, remain inside the
|
||||
package, and exist. Production never imports source TypeScript directly. Modules with no tables omit
|
||||
`entrypoints.schema`; modules with no migration history omit `entrypoints.migrations`; modules with
|
||||
no UI omit `entrypoints.ui`.
|
||||
Every entrypoint except `migrations` must be a compiled ESM `.js` or `.mjs` file — `server`,
|
||||
`schema`, `jobs`, and `ui` alike. `migrations` is the one directory entrypoint. All entrypoints begin
|
||||
with `./`, remain inside the package, and exist. Production never imports source TypeScript directly.
|
||||
Modules with no tables omit `entrypoints.schema`; modules with no migration history omit
|
||||
`entrypoints.migrations`; modules with no UI omit `entrypoints.ui`.
|
||||
|
||||
Unknown manifest properties are still rejected. `ui` is the only entrypoint version 4 adds — a
|
||||
`dashboard`, `surface`, `client`, `web`, or `renderers` key fails validation — and the manifest
|
||||
|
||||
Reference in New Issue
Block a user