Skip to content

docs(openspec): specify VIRTUAL_PATH routing - #114

Merged
paolomainardi merged 1 commit into
mainfrom
docs/113-virtual-path-spec
Aug 12, 2026
Merged

docs(openspec): specify VIRTUAL_PATH routing#114
paolomainardi merged 1 commit into
mainfrom
docs/113-virtual-path-spec

Conversation

@paolomainardi

@paolomainardi paolomainardi commented Aug 12, 2026

Copy link
Copy Markdown
Member

User description

🤖 This was written by an AI agent on behalf of @paolomainardi.

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 in docs/ instead.

The shape

react:  VIRTUAL_HOST=app.loc                        VIRTUAL_PORT=5173
api:    VIRTUAL_HOST=app.loc   VIRTUAL_PATH=/api    VIRTUAL_PORT=3000

Three decisions worth reviewing

The matcher is segment-aware. Traefik's PathPrefix is a raw string prefix, so PathPrefix(/api) also matches /api-docs. A Kubernetes Ingress pathType: Prefix splits on separators and does not. Since the point is that one relative call behaves the same locally and once deployed, the rule pairs them:

Host(`app.loc`) && (PathPrefix(`/api/`) || Path(`/api`))

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 with omitempty would be dropped and silently restore inherited ordering.

Nothing is stripped, matching both an Ingress and nginx-proxy's default. VIRTUAL_DEST is 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:

  • A container carrying any traefik. label is skipped whole, so its VIRTUAL_HOST never routes. Example 7 in examples/applications.yml is dead today for exactly this reason. The spec requires reporting it and fixing the example.
  • AGENTS.md says the repository has no unit tests and that make test is the verification step. There are five _test.go files, and make test runs 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 answers 200.

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_PATH routing

  • Define segment-aware matching and explicit route precedence

  • Specify validation, collision reporting, certificates, and tests

  • Add repository-wide OpenSpec configuration and conventions


Diagram Walkthrough

flowchart LR
  Container["Container with VIRTUAL_HOST and VIRTUAL_PATH"]
  Layer["dinghy_layer routing generation"]
  PathRouter["Segment-aware path router"]
  Backend["Container backend receives unchanged path"]
  Container -- "declares routing" --> Layer
  Layer -- "creates prioritized route" --> PathRouter
  PathRouter -- "forwards request" --> Backend
Loading

File Walkthrough

Relevant files
Documentation
.openspec.yaml
Register virtual path routing OpenSpec change                       

openspec/changes/virtual-path-routing/.openspec.yaml

  • Registers the virtual-path-routing change as spec-driven
  • Records the OpenSpec change creation date
+2/-0     
design.md
Document VIRTUAL_PATH routing design decisions                     

openspec/changes/virtual-path-routing/design.md

  • Documents existing routing constraints and compatibility concerns
  • Explains VIRTUAL_PATH matching, normalization, and validation
    decisions
  • Defines explicit path-router priority without altering hostname routes
  • Records trade-offs around collisions, certificates, labels, and
    testing
+89/-0   
proposal.md
Propose shared-hostname virtual path routing                         

openspec/changes/virtual-path-routing/proposal.md

  • Proposes VIRTUAL_PATH for shared-hostname container routing
  • Summarizes segment-aware matching and path route precedence
  • Identifies implementation, testing, documentation, and example impacts
  • Preserves existing VIRTUAL_HOST and VIRTUAL_PORT behavior
+44/-0   
spec.md
Specify VIRTUAL_PATH routing behavior and safeguards         

openspec/changes/virtual-path-routing/specs/virtual-path-routing/spec.md

  • Defines observable requirements for VIRTUAL_PATH routing
  • Specifies whole-segment matching, precedence, and unchanged backend
    paths
  • Covers malformed declarations, duplicate paths, and certificate
    handling
  • Defines diagnostic, documentation, example, and agent-skill
    expectations
+240/-0 
tasks.md
Plan VIRTUAL_PATH implementation and verification tasks   

openspec/changes/virtual-path-routing/tasks.md

  • Breaks implementation into parsing, routing, precedence, and reporting
    tasks
  • Lists certificate, documentation, example, and changelog follow-up
    work
  • Defines direct unit and end-to-end coverage expectations
  • Tracks separate companion agent-skill release work
+97/-0   
Configuration changes
config.yaml
Configure OpenSpec repository context and rules                   

openspec/config.yaml

  • Introduces repository-level OpenSpec configuration
  • Describes proxy architecture, routing conventions, and test locations
  • Requires observable specifications and integration coverage for
    routing
+26/-0   


Assisted-by: pr-agent/gpt-5.6-terra

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
@sparkfabrik-ai-bot

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

113 - Partially compliant

Compliant requirements:

  • Add a detailed specification for the intended VIRTUAL_PATH behavior and implementation work.

Non-compliant requirements:

  • Implement VIRTUAL_PATH routing behavior.
  • Add route validation, precedence, collision detection, certificate safeguards, documentation, examples, diagnostics, and test coverage.

Requires further human verification:

  • The proposed specification should be reviewed for product and routing-semantics agreement before implementation.
⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Contradictory management

This scenario says any container setting VIRTUAL_PATH is managed and has its network joined, but the later VIRTUAL_PATH-without-VIRTUAL_HOST scenario says that container is not exposed. Since management currently depends on VIRTUAL_HOST, an implementation following the former requirement could incorrectly join or manage path-only containers. Qualify this scenario with VIRTUAL_HOST, or explicitly define the intended behavior for path-only containers.

#### Scenario: A container using a path is still managed

- **WHEN** a container sets `VIRTUAL_PATH`
- **THEN** it is managed, and its network is joined, on the same terms as any other exposed container

Assisted-by: pr-agent/gpt-5.6-terra

@sparkfabrik-ai-bot

Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

@paolomainardi
paolomainardi merged commit 51afa20 into main Aug 12, 2026
14 checks passed
@paolomainardi
paolomainardi deleted the docs/113-virtual-path-spec branch August 12, 2026 23:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant