The subject namespace is the platform's, and it says so - #131
Merged
czpython merged 1 commit intoJul 27, 2026
Merged
Conversation
czpython
deleted the
commonzenpython/eng-779-platform-owns-the-subject-namespace
branch
July 27, 2026 15:01
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.
Declaring a subject mounts a read surface the extension writes none of, and review's trigger sat next to it looking like the same noun spelled twice:
They were never the same noun.
GET /api/review/pull_requestis not a list of pull requests — it is the board of open review runs, keyed by subject. What the POST creates is a review, so that is what it is called now:Nothing changes about authoring. An extension declares routers in
routes.pyand they mount under its namespace, exactly as before — there is no way to attach an action to the platform's subject path, and there should not be: the operation is the author's own resource and belongs on its own path. ship has proved that since the subject read-side landed, serving/api/ship/work_itembeside/api/ship/work-itemswith nothing to reconcile.Two spellings run through druks and never mean the same thing: snake_case is identity — a subject type, a run's kind, an event's attributes — and kebab-case is a URL segment. Under that rule
pull_requestandpull-requestswere never in conflict. It is how the repo already behaved and it had never been written down.What did need enforcing is the one case where the two surfaces genuinely collide. Declared routers mount ahead of the platform's, so a router reaching into the subject's own segment takes the board or a detail read with it — and nothing collides at import, so the loss surfaces much later as a 404 from a route nobody deleted. That fails at load now, naming the segment and what owns it. The rule is exact: the subject's segment, whatever the method, and no resemblance check —
/widgetsis an author's own resource and says nothing about/widget.The order the guard protects is pinned by a test rather than left to a list literal.
An extension's routers are also tagged with its name at mount, where the platform already applies the prefix and the identity gate.
tags=had drifted to mean two things across four routers — the extension in two, the resource in the others — and a router now declares only what its own resource is called.