Skip to content

refactor(core)!: a runtime resolves ports, it does not need them - #88

Merged
btravers merged 2 commits into
mainfrom
refactor/runtime-needs-rename
Aug 21, 2026
Merged

refactor(core)!: a runtime resolves ports, it does not need them#88
btravers merged 2 commits into
mainfrom
refactor/runtime-needs-rename

Conversation

@btravers

Copy link
Copy Markdown
Contributor

Two different needs in one framework was one too many.

di's Module has a needs — what a composition root supplies it — and the
kernel's Runtime had one too, meaning something else entirely: the ports the
runtime reads back out of the built application context. They never appear in
the same object, which is exactly what made the collision easy to misread
rather than harmless.

const runtime: Runtime<typeof Clock> = {
  name: "ticker",
  resolves: [Clock],
  start: (host) => OkAsync(serving),
};

The type parameter follows the field — Runtime<Resolves, Info>,
RuntimeHost<Resolves>, RunUnit<Resolves>, RuntimeResolvesOf — and so does
start's gate sentence:

"UNSATISFIED RUNTIME PORTS — the runtime resolves a port the module does not export"

Blast radius

Small, because every shipped runtime declares resolves: []. An
application that composes http() / temporal() / amqp() and never writes a
runtime by hand is unaffected; a hand-rolled one renames a field.

RuntimeResolvesOf was never exported from packages/core/src/index.ts, so
the public surface change is the Runtime field and the gate sentence, nothing
else.

While renaming

The field's own comment now says the thing that was true and unwritten: the
array is never read at run time. It exists so Resolves is inferable from
the value, and start's gate checks it against the module's exports.

Gate

All six green from the root: format --check, lint, typecheck (31/31),
knip, test (30/30), build (10/10). Changeset included — minor, all nine.

Two different `needs` in one framework was one too many. di's Module has one —
what a composition root supplies it — and the kernel's Runtime had another,
meaning the ports it reads back out of the built application context. They never
appear in the same object, which is what made the collision easy to misread
rather than harmless.

The type parameter follows the field: Runtime<Resolves, Info>,
RuntimeHost<Resolves>, RunUnit<Resolves>, RuntimeResolvesOf. So does start's
gate sentence, now "UNSATISFIED RUNTIME PORTS — the runtime resolves a port the
module does not export".

Every shipped runtime declares resolves: [], so an application that composes a
starter is unaffected; a hand-rolled runtime renames one field. The array is
still never read at run time — it exists so Resolves is inferable from the
value, which is now said where the field is declared.
Copilot AI lite review requested due to automatic review settings August 21, 2026 21:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Refactors @btravstack/core’s Runtime contract to rename needsresolves, clarifying that a runtime reads ports from the built application context (distinct from di Module.needs) and aligning the type parameter names and gate messaging accordingly.

Changes:

  • Rename Runtime<Needs, Info>Runtime<Resolves, Info> (and RuntimeHost, RunUnit, and helper types) and update start’s gate sentence to UNSATISFIED RUNTIME PORTS.
  • Update shipped starters and test utilities to declare resolves: [] (and update type tests/specs accordingly).
  • Update documentation (package CLAUDE.md, READMEs, and docs site pages) plus add a changeset for the minor bump.

Reviewed changes

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

Show a summary per file
File Description
packages/testing/src/test-runtime.ts Update test runtime object to resolves: [].
packages/temporal/src/temporal-runtime.ts Update Temporal runtime object to resolves: [].
packages/temporal/CLAUDE.md Docs wording update to match resolves/gate rename.
packages/observability/src/test-fixtures.ts Update hand-rolled runtime example to resolves: [Logger].
packages/http/src/http-runtime.ts Update HTTP runtime object to resolves: [].
packages/http/CLAUDE.md Docs wording update to match resolves/gate rename.
packages/core/src/start.ts Rename gate/type plumbing from RuntimeNeedsOfRuntimeResolvesOf and update gate sentence.
packages/core/src/start.test-d.ts Update type-level gate tests to use resolves and new sentence.
packages/core/src/start.spec.ts Update spec runtime object to resolves: [].
packages/core/src/runtime.ts Rename Runtime field/type parameter and helper type to resolves/RuntimeResolvesOf.
packages/core/src/docs-examples.test-d.ts Update compiled doc examples to resolves.
packages/core/README.md Update README example runtime to resolves.
packages/core/CLAUDE.md Update core package docs to use resolves terminology.
packages/amqp/src/amqp-runtime.ts Update AMQP runtime object to resolves: [].
packages/amqp/CLAUDE.md Docs wording update to match resolves/gate rename.
docs/typedoc.core.json Update intentionallyNotExported for renamed helper type.
docs/reference/testing.md Update testing reference docs to resolves.
docs/reference/http.md Update HTTP reference wording to “resolves nothing”.
docs/reference/glossary.md Update glossary entries for gate/runtime shape.
docs/reference/di/entry-points.md Update entry-points doc to renamed gate arm.
docs/reference/core/start.md Update StartGate docs and arm table to RuntimeResolvesOf/UNSATISFIED RUNTIME PORTS.
docs/reference/core/runtime.md Update runtime reference page to resolves.
docs/reference/core/exit-codes.md Update exit-codes page to renamed gate arm.
docs/reference/amqp.md Update AMQP reference wording to “resolves nothing”.
docs/index.md Update landing-page feature text to match rename.
docs/how-to/write-a-runtime.md Update how-to guide’s runtime definitions/examples to resolves.
docs/how-to/open-a-per-request-scope.md Update per-request scope page to renamed gate arm/field.
docs/explanation/why-start.md Update explanation wording (“ports … not exported”).
docs/explanation/the-kernel-maps-nothing.md Update explanation link text to resolves.
docs/explanation/starters.md Update starters explanation to resolves terminology.
docs/explanation/one-process-one-runtime.md Update explanation link text to match rename.
docs/explanation/design-decisions.md Update gate wording to renamed arm.
docs/explanation/compile-time-wiring.md Update compile-time wiring explanation tables/rows to UNSATISFIED RUNTIME PORTS.
docs/examples/order-api.md Update example doc wording to renamed arm/field.
CLAUDE.md Update repo-wide guidance text to resolves terminology.
.changeset/runtime-resolves.md Add minor changeset documenting the rename and gate sentence update.
Suppressed comments (2)

packages/core/src/start.test-d.ts:64

  • @ts-expect-error directive still references the old gate arm and field name (UNSATISFIED RUNTIME NEEDS / "needs"). After the rename, this comment should match the new diagnostic wording (UNSATISFIED RUNTIME PORTS / "resolves") so future readers don't chase the wrong concept.
expectTypeOf<
  StartGate<Greeting | NeedsClock>
>().toEqualTypeOf<"UNSATISFIED RUNTIME PORTS — the runtime resolves a port the module does not export">();

packages/core/src/start.test-d.ts:64

  • These nearby comments still say "needs-free runtime" / "runtime's needs" even though the type parameter and field were renamed to Resolves/resolves. Updating the wording will keep the type-test file consistent with the new API and gate terminology.
expectTypeOf<
  StartGate<Greeting | NeedsClock>
>().toEqualTypeOf<"UNSATISFIED RUNTIME PORTS — the runtime resolves a port the module does not export">();

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/core/src/start.test-d.ts
Comment thread docs/reference/core/runtime.md Outdated
Comment thread packages/core/src/start.test-d.ts
Comment thread packages/observability/src/test-fixtures.ts
Comment thread docs/explanation/starters.md Outdated
Comment thread packages/core/CLAUDE.md Outdated
The sweep renamed the identifiers and the gate sentences and stopped there, so
a dozen comments and headings still said `needs` about the runtime — including
two `@ts-expect-error` directives naming an arm that no longer exists, which is
the worst kind of stale: a negative that still passes while documenting the
wrong gate.

Every runtime-sense `needs` is now `resolves`: start.test-d's directives and
runtime names, runtime.ts's own remaining `Needs` mentions, observability's
fixture docstring, the three examples' gate files and README, starters.md's
heading, and the reference tables. di's `Needs` channel keeps its name
everywhere it appears, which is the distinction the rename existed to draw.

Audited mechanically afterwards rather than by eye: every surviving `needs`
near the word "runtime" is either di's channel, a unit module's, or the English
verb.
@btravers
btravers merged commit 39adbc0 into main Aug 21, 2026
13 checks passed
@btravers
btravers deleted the refactor/runtime-needs-rename branch August 21, 2026 22:19
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.

2 participants