docs(openspec): specify VIRTUAL_PATH routing - #114
Merged
Conversation
Adds an OpenSpec change describing a VIRTUAL_PATH variable that mounts a container under a path of a hostname another container already serves, so a browser-served frontend and its API can share one origin locally. Introduces OpenSpec in this repository, since the change is large enough that the decisions behind it are worth recording somewhere other than a commit message. Refs: #113 Assisted-by: claude-code/claude-opus-5
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨No code suggestions found for the PR. |
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.
User description
Specification only. No behaviour changes in this pull request.
Refs #113.
What this is
An OpenSpec change describing
VIRTUAL_PATH, a variable that mounts a container under a path of a hostname another container already serves, so a browser-served frontend and its API can share one origin locally.It also introduces OpenSpec in this repository. The feature touches routing precedence, path matching semantics and three test surfaces, and the reasoning behind those choices is worth recording somewhere more durable than a commit message. If you would rather not carry
openspec/here, say so and the same content can go indocs/instead.The shape
Three decisions worth reviewing
The matcher is segment-aware. Traefik's
PathPrefixis a raw string prefix, soPathPrefix(/api)also matches/api-docs. A Kubernetes IngresspathType: Prefixsplits on separators and does not. Since the point is that one relative call behaves the same locally and once deployed, the rule pairs them:Priority is set on the new routes only. Traefik orders routers by rule length when priority is unset, in one table per entrypoint, across providers. Setting a priority on the hostname routers this layer already emits would re-rank them against routers built from users' own
traefik.*labels, and would replace today's stable exact-versus-wildcard ordering with an undefined tie. So those are left exactly as they are, and only the routes a path produces are ranked explicitly. The field also needs a non-zero floor, because a zero value withomitemptywould be dropped and silently restore inherited ordering.Nothing is stripped, matching both an Ingress and nginx-proxy's default.
VIRTUAL_DESTis out of scope and recorded as unsupported.Two existing problems this surfaces
Neither is caused by the feature, both are made easier to hit by it:
traefik.label is skipped whole, so itsVIRTUAL_HOSTnever routes. Example 7 inexamples/applications.ymlis dead today for exactly this reason. The spec requires reporting it and fixing the example.AGENTS.mdsays the repository has no unit tests and thatmake testis the verification step. There are five_test.gofiles, andmake testruns only the integration suite. Corrected as part of the work.Test surfaces
Three, deliberately: unit cases for parsing and rule generation, the integration suite for the routing and its failure modes, and
spark-http-proxy self-test, so a machine where paths are broken does not report itself healthy. The diagnostic has to compare response content rather than status codes, because a missing path route falls through to the hostname's container and still answers200.Review notes
The spec went through an adversarial review that changed the priority decision, added the two silent-failure cases above, and caught that duplicate detection has to work for containers arriving as live events rather than only at startup, since developers start the proxy before their stack.
Happy to split this differently or drop the OpenSpec framing entirely if that suits the project better.
PR Type
Documentation
Description
Introduce OpenSpec documentation for
VIRTUAL_PATHroutingDefine segment-aware matching and explicit route precedence
Specify validation, collision reporting, certificates, and tests
Add repository-wide OpenSpec configuration and conventions
Diagram Walkthrough
File Walkthrough
.openspec.yaml
Register virtual path routing OpenSpec changeopenspec/changes/virtual-path-routing/.openspec.yaml
virtual-path-routingchange as spec-drivendesign.md
Document VIRTUAL_PATH routing design decisionsopenspec/changes/virtual-path-routing/design.md
VIRTUAL_PATHmatching, normalization, and validationdecisions
testing
proposal.md
Propose shared-hostname virtual path routingopenspec/changes/virtual-path-routing/proposal.md
VIRTUAL_PATHfor shared-hostname container routingVIRTUAL_HOSTandVIRTUAL_PORTbehaviorspec.md
Specify VIRTUAL_PATH routing behavior and safeguardsopenspec/changes/virtual-path-routing/specs/virtual-path-routing/spec.md
VIRTUAL_PATHroutingpaths
handling
expectations
tasks.md
Plan VIRTUAL_PATH implementation and verification tasksopenspec/changes/virtual-path-routing/tasks.md
tasks
work
config.yaml
Configure OpenSpec repository context and rulesopenspec/config.yaml
routing