fix: invalid ids/names fail at authoring instead of mid-deploy; conformance suite repaired#149
Conversation
Three things broke or were missing: - conformance/local.vitest.ts still imported ../src/testing.ts after PR #130 moved public entrypoints to src/exports/, so the suite failed to load. - Dependabot PR #126 bumped @durable-streams/server-conformance-tests from the exact pin 0.2.3 to 0.3.5, whose new tests exercise features @prisma/streams-server 0.1.11 does not ship (60 failures). Restore the pin and tell Dependabot to leave it alone; it moves by hand with streams-server. - The repo root had no test:conformance:local script; add one that delegates to @internal/streams. CI never runs the conformance suite (no workflow references it), which is why these regressions went unnoticed. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
A compute service named "origin-proof", provisioned under its inferred id,
derived config env key COMPOSER_ORIGIN-PROOF_PORT — the Management API
rejects it minutes into a deploy ("key: must match POSIX env-var key shape:
[A-Z_][A-Z0-9_]*"). The same applies to any provision id (service, module,
resource, bucket, postgres, ...) because the id becomes an address segment,
and to input/param/secret names, since configKey uppercases all of these
segments and joins them with "_".
Tighten the two existing checks instead of adding a target-side one:
- core/src/load-module.ts: the provision-id check (previously banning only
"_" and ".") now requires ids to be ASCII letters and digits, with an
error naming the id, the module, and the derived key segment.
- core/src/node.ts: the input/param/secret name check (previously banning
only "_") now requires the same charset at the factory.
Placement: both checks already lived in core and already justified
themselves by the config-key derivation, so extending them is the smallest
change consistent with that recorded placement; a Load-time integrity error
is the framework's documented failure point (Wiring precedes execution,
docs/design/01-principles). No sanitizing during key derivation — the
serializer stays deterministic (ADR-0005/ADR-0019); invalid names are
rejected loudly instead. Node NAMES stay unconstrained beyond non-empty
(ADR-0006: names are diagnostic; a hyphenated root/app name or a fake
served directly never enters a key) — only a name used as a provision id
is checked, at the moment it becomes an address segment.
Test fixtures that provisioned services under hyphenated ids (cli run
fixture, integration extension-config fixture) now use a key-safe id while
keeping their hyphenated app names.
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…the target's Review nits on the previous commit: - The rejection messages cited the POSIX env-var key shape [A-Z_][A-Z0-9_]* — a target medium leaking into core (ADR-0019). Both messages now state core's own rule: names/ids must be alphanumeric because addresses and declared names derive deterministic config keys. The POSIX motivation moved to a comment on isConfigKeySegment: the grammar is conservative by design so any target medium, POSIX env keys included, can uppercase and "_"-join segments without escaping. - The integration extension-config fixture keeps its hyphenated compute NAME again — only the provision id needed to become key-safe. - Boundary acceptance coverage: digits-only and single-char segments are accepted, for both provision ids and input/param names. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (11)
Knowledge base: Disabled due to Summary by CodeRabbit
WalkthroughThe core framework now validates service, dependency, and provision identifiers as ASCII letters-and-digits-only config key segments. Error expectations and acceptance coverage were updated, while CLI and integration fixtures use the ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Checkov (3.3.8).github/dependabot.ymlTraceback (most recent call last): package.jsonTraceback (most recent call last): packages/1-prisma-cloud/2-shared-modules/streams/package.jsonTraceback (most recent call last): 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
Two unrelated fixes on one branch. The first changes when you find out a name is bad:
Before: this authors fine, builds fine, and starts deploying — then, minutes in, with resources already created, the Management API rejects it:
After: it fails the instant the module loads, in your editor or test run, with the framework's own explanation:
The decision
Core's address-segment grammar is conservatively alphanumeric. Provision ids and declared input/param/secret names must match
[A-Za-z0-9]+, enforced where they're written down — the node factory for declared names, module loading for provision ids — so a bad one can never reach a deploy.Why these strings have a grammar at all
The framework hands each service its config through generated environment variables. The variable names are built from what you authored: segments (provision ids on the path to the service, then the declared name) are uppercased and joined with
_— idauth+ paramport→COMPOSER_AUTH_PORT. That derivation is deliberately dumb: no escaping, no sanitizing, so you can always predict the key from the code.A dumb derivation is only safe if the segments are tame, and core already knew this:
_in an id was banned because it collides with the join separator (idauth_db+ paramurland idauth+ inputdb+ paramurlboth deriveAUTH_DB_URL), and.because it's the address path separator. What was missing is everything else — a-sails through and produces a key no env-var medium accepts. This PR closes the rule from "not_, not." to "letters and digits only," which is the whole family of problems at once, not another special case.Deliberately unchanged:
names stay free (only non-empty). Names are diagnostic labels and never enter keys (ADR-0006) — hyphenated app names likestreams-examplekeep working.isConfigKeySegment; what core enforces is its own address grammar.Second fix:
pnpm test:conformance:localruns againRunning the streams conformance suite locally failed with
Cannot find module '../src/testing.ts'— and behind that first error were three stacked problems, invisible because no CI workflow runs this suite (verified — it's local-only):src/testing.tsafter the public-entrypoints move tosrc/exports/.@durable-streams/server-conformance-testswas pinned to exactly0.2.3because 0.3.x tests features@prisma/streams-server0.1.11 doesn't ship. The bump to 0.3.5 made 60 of 332 tests fail. The pin is restored, and the package is on dependabot'signorelist so it only moves by hand, together with streams-server.pnpm test:conformance:localnow exists at the repo root, delegating to@internal/streams.Result: 239/239 conformance tests pass. Adding the suite to CI is a real option but a separate decision (it needs the local server harness in CI) — not taken here.
Verification
Whole repo from root: build 29/29, typecheck 60/60, test 49/49, lint clean, cast delta 0, conformance 239/239. New tests: rejection of the live-failure case (hyphenated provision id, explicit and name-inferred) and a hyphenated param name; acceptance of camelCase, embedded digits, digits-only, and single-char segments. An independent review pass confirmed the segment coverage is complete: provision ids and input/param/secret names are exactly the user-controlled strings that reach key derivation — node names and expose names never do.
Alternatives considered
-→_): rejected outright — it makes keys unpredictable from source, reintroduces the collision family the_ban exists for, and violates the recorded no-laundering principle.@prisma/streams-serverto match 0.3.x instead of re-pinning: the right long-term move, but a feature-work decision for the streams package, not a repair — the pin restores the suite's documented, intended state.🤖 Generated with Claude Code