diff options
Diffstat (limited to 'docs/roadmap.md')
| -rw-r--r-- | docs/roadmap.md | 103 |
1 files changed, 66 insertions, 37 deletions
diff --git a/docs/roadmap.md b/docs/roadmap.md index 59eb6c9..fd2e698 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,50 +1,79 @@ -# v0.1.0 Roadmap +# MiniRoute Roadmap -Initial release of the routing/middleware kernel. +Status: **v0.1.0 released** (2026-08-29) · next: **v0.2.0 hardening** +Issue tracking: beads — the epics below are live in the database (`bd ready`, +`bd show <id>`). Full issue IDs carry a `miniroute-` prefix (e.g. `miniroute-uhs`). -## Proposed beads +## Version policy -### [EPIC] miniroute v0.1.0 — attribute routing + middleware kernel +- **0.x era** — the contract is still settling. Breaking changes are allowed + at minor bumps (`0.2`, `0.3`); patches (`0.1.1`) are for fixes within a + minor. Every behavior change lands in `CHANGELOG.md`. +- **1.0** — API freeze. From `v1.0.0` on: strict SemVer (major = breaking, + minor = feature, patch = fix). The freeze review is `miniroute-18h.1`. -- Type: epic -- Priority: P2 +## v0.1.0 — Initial kernel [released] -Children (create with `--parent`): +Attribute routes, deterministic matching (literal beats `{param}` regardless +of registration order), onion middleware pipeline, resolver seam, thin HTTP +contracts. Closed via epic `miniroute-c5e` (children 1–6; 7–8 completed the +release ceremony: tag + cgit publish). -1. **Core: attribute route declaration and reflection loader** - - Type: task, Priority: P2 - - Description: Implement `Get`/`Post`/`Put`/`Patch`/`Delete`/`Middleware` - attributes and `RouteLoader` reflection scanning. - - Acceptance: `RouteLoaderTest` passes. +## v0.2.0 — Hardening (epic `miniroute-uhs`) -2. **Core: deterministic route matching** - - Type: task, Priority: P2 - - Description: `RouteMatcher` with `{param}` support and - literal-before-parameter precedence. - - Acceptance: `RouteMatcherTest` passes. +Fix the failure modes confirmed by the stress test; each fix flips a baseline +in `tests/Regression/KnownIssuesTest.php` from "v0.1.0 behavior" to desired: -3. **Core: middleware pipeline and groups** - - Type: task, Priority: P2 - - Description: `MiddlewarePipeline` onion composition and router-level - `group()` prefix middleware. - - Acceptance: `MiddlewarePipelineTest` and router group coverage pass. +| Bead | Fix | Current (v0.1.0) behavior | +|---|---|---| +| `uhs.1` | Validate param names (unique, `[A-Za-z_][A-Za-z0-9_]*`) at registration → `RouteRegistrationException` | Duplicate params = dead route + preg warning; malformed `{a-b}` degrades to literal | +| `uhs.2` | 405 detection: path-only fallback → `MethodNotAllowedException` with `allowed()`; app renders 405 + `Allow` | Wrong method = plain 404 | +| `uhs.3` | HEAD → GET mapping (matcher); app's response layer suppresses body | HEAD = 404 | +| `uhs.4` | Fail loud: route attribute on non-public method → `RouteRegistrationException` | Non-public methods silently skipped | +| `uhs.5` | Lazy single sort in `Router` (dirty flag, sort at first dispatch) | `usort` per add: 600 routes ≈ 770ms registration | +| `uhs.6` | Memoize compiled patterns in `RouteMatcher` | Regex recompiled per route per match | -4. **Core: controller resolution and dispatch** - - Type: task, Priority: P2 - - Description: `ControllerResolverInterface` seam and `Router::dispatch`. - - Acceptance: `RouterTest` passes. +Gate: `composer check` green with baselines flipped; bench shows registration +cost collapse at 600 routes. Middleware singleton-state rule is a *usage +contract*, documented in v0.3.0 ADRs (`k4i.3`), not a kernel change. -5. **Tests: unit coverage for loader/matcher/pipeline/router** - - Type: task, Priority: P2 - - Acceptance: `vendor/bin/phpunit` green. +## v0.3.0 — API completeness (epic `miniroute-k4i`) -6. **Docs: ADRs, README, usage** - - Type: task, Priority: P2 +- `k4i.1` — `RequestInterface::input()` / `query()` so real middleware (CSRF) + reads form/query data through the contract instead of `$_GET` or narrowing. +- `k4i.2` — `match(): ?ResponseInterface` (or richer result) so fall-through + composition doesn't need try/catch. +- `k4i.3` — ADRs: middleware ordering contract (group/class/method onion), + singleton-middleware state rule, exception hygiene (sessions closed in + `finally`), and the rejected decision on `{id:\d+}` param constraints + (controllers already validate; don't add scope). -7. **Release: Composer metadata and git tags** - - Type: task, Priority: P2 - - Description: `composer.json` PSR-4 autoload, MIT license, tag `v0.1.0`. +## v0.4.0 — parsonwebsite integration (epic `miniroute-g3j`) -8. **Repo: publish to src.brett-parson.com** - - Type: task, Priority: P2 - - Description: Add cgit remote, push, set `git-daemon-export-ok` marker. +- `g3j.1` — Port `RequireAdmin` / `RequireCSRF` / `AdminSession` onto + `MiddlewareInterface` (the per-route closures become `/admin` groups). +- `g3j.2` — App `Request`/`Response` implement the interfaces directly + (drop `ToyRequest`/`ToyResponse`; add `Response::status()`). +- `g3j.3` — Full route table behind the existing flag; old router as fallback + until green, then cut over. + +Gate: the realistic stress section passes against the real controllers. + +## v1.0.0 — Release (epic `miniroute-18h`) + +- `18h.1` — API freeze review of the public surface (attributes, interfaces, + exceptions, `Router` methods). +- `18h.2` — Dogfood via Composer: parsonwebsite consumes the package from the + published VCS remote. +- `18h.3` — CI benchmark gates: full-table registration < 5ms, dispatch + < 0.1ms, full suite green. +- `18h.4` — Tag `v1.0.0`, publish, strict-SemVer policy from here. + +## Cross-cutting infrastructure + +- Test suite epic `miniroute-4dh` — regression/integration coverage: + realistic route table (`4dh.1`), known-issue baselines (`4dh.2`), router + boundary cases (`4dh.3`), benchmark script (`4dh.4`). +- `miniroute-ouq` — changelog + roadmap + agent docs (this file, + `CHANGELOG.md`, `AGENTS.md`/`CLAUDE.md`). +- `miniroute-br6` — configure a beads Dolt remote for issue sync/backup. |
