# Armature — Roadmap ## Current: v0.7.3 — Extension Shell Migration Self-hosted extensible platform. Auth, identity, packages, Starlark sandbox, storage, realtime, and ops are kernel primitives. Everything else is an extension. **Kernel capabilities:** Auth (builtin/mTLS/OIDC) · Users/teams/groups/RBAC · Surfaces/extensions/libraries/workflows · Starlark sandbox (capability-gated) · Object storage (PVC/S3) + ext_data tables · WebSocket hub + realtime pub/sub · Audit log · Notifications · Scheduled tasks **Completed history:** v0.2.x–v0.5.x fully documented in `CHANGELOG.md`. Highlights: RBAC + settings cascade, event bus + triggers, SDK stabilization, workflow engine (multi-stage, team roles, signoff gate, public entry, SLA), package distribution, Notes surface (CM6, folders, tags, backlinks, graph), realtime primitive, Chat surface (chat-core library + surface + polish), upgrade test harness, cluster registry + HA. --- ## v0.6.x — Completed (MVP + Hardening) All v0.6.x work is shipped and documented in `CHANGELOG.md`. Summary: | Version | Title | Key Deliverables | |---------|-------|-----------------| | v0.6.0 | Cluster Registry + HA | PG-backed node registry, heartbeat sweep, LISTEN/NOTIFY routing, self-eviction | | v0.6.1 | Backup/Restore + Docs | `.swb` archive format, server-side backups, docs surface + 5 guides | | v0.6.2 | Docs Polish + OpenAPI | Dark mode fix, topbar nav, `api_schema` manifest field, dynamic spec builder | | v0.6.3 | Dead Code Sweep | Registry install fix, dead Go/JS/HTML deletion, narrowed default bundle | | v0.6.4 | Admin Health/Metrics | Cluster dashboard merged into Admin tab, block renderer `requires` removed | | v0.6.5 | Renderer Pipeline | `sw.renderers.register()` kernel primitive, unified markdown, docs rewrite | | v0.6.6 | Final Hardening | Dependency auto-activation, `ValidateManifest()`, OIDC nonce, ICD/SDK update | | v0.6.7 | Native mTLS | `TLS_MODE` config, `MTLSNativeProvider`, node-to-node mTLS, `armature-ca.sh` | | v0.6.8 | Cookie Fix + UI Roadmap | Cookie SameSite fix, UI hardening roadmap published | | v0.6.9 | Session Lifetime Config | Admin-configurable TTLs, idle timeout, "keep me logged in" | | v0.6.10 | Viewport Foundation | Single layout model, CSS zoom, 100dvh, dead shell deprecated | | v0.6.11 | CSS Deduplication | Old primitive system retired, one class per concept | | v0.6.12 | Extension CSS Isolation | Prefix enforcement via linter, all 12 in-tree packages migrated | | v0.6.13 | Responsive & Spacing | Spacing token scale (4px grid), tablet breakpoint | | v0.6.14 | Visual Polish | Stale fallback colors purged, fonts self-hosted, radius tokens | | v0.6.15 | User Display Audit | Batch user resolve API, `sw.users` SDK module | | v0.6.16 | Usability Survey Gate | Four audit scripts, contrast/touch-target fixes | | v0.6.17 | Bug Fixes & Welcome | Notes folder fix, team member add fix, welcome auto-disable, zero default bundle | | v0.6.18 | CI Bundle Wiring | `BUNDLED_PACKAGES` env var wired into Gitea CI pipeline | --- ## v0.7.x — Test Infrastructure + Quality Gate The v0.6.x series built the kernel. v0.7.x makes it provably correct. A full surface audit (docs/AUDIT-surfaces.md) found 7 cross-surface issues and 18 surface-specific issues across Settings, Admin, Team Admin, and Docs. Only Docs is properly built. The fix is three phases: (1) establish a shell contract and bring all four primary surfaces to parity, (2) build a runner framework for end-to-end browser tests, (3) automate those runners headlessly in CI. Design docs: - `docs/DESIGN-shell-contract.md` — two-slot topbar, three navigation patterns, surface migrations - `docs/DESIGN-surface-runners.md` — runner framework, requires declarations, headless E2E - `docs/AUDIT-surfaces.md` — full audit findings ### v0.7.0 — Shell Contract + Surface Audit + Rebrand Cleanup Design doc: `docs/DESIGN-shell-contract.md` **Shell Infrastructure** | Step | Status | Description | |------|--------|-------------| | Shell topbar (two-slot model) | done | Kernel injects topbar into `surface-extension` template. Two named slots: **left** (defaults to manifest title) and **center** (`flex: 1`, for tabs/pickers/search). Home link, notification bell, and user menu always present. | | Topbar customization API | done | `sw.shell.topbar.setLeft(vnode)` overrides left slot. `sw.shell.topbar.setSlot(vnode)` sets center slot. `sw.shell.topbar.setTitle(str)` shorthand for text-only left. `sw.shell.topbar.hide()` / `.show()` for full-bleed surfaces. | | Kernel tab CSS | done | `.sw-topbar__tabs` and `.sw-topbar__tab` classes for consistent tab styling in the center slot. Surfaces use these for free or style their own slot content. | | Notification read broadcast | done | Backend emits `notification.read` and `notification.all_read` WS events. Bell listens for `.created`, `.read`, `.all_read`. Cross-surface sync without refetch. | | User menu reactivity | done | Emit `package.changed` (install/uninstall/enable/disable) and `auth.changed` (role/membership) WS events. UserMenu listens and re-fetches surface list. Most impactful single fix. | | Shell announcement global dismiss | done | Dismissed state persisted to localStorage keyed by content hash. Dismiss once, dismissed everywhere. | **Surface Migrations** | Step | Status | Description | |------|--------|-------------| | Settings → Pattern B (flat tabs) | done | Delete custom topbar + sidebar nav. 6 sections become flat tabs in topbar center slot. Content full-width. Fix Teams section: add team admin link, role display, leave action. Remove sessionStorage return URL logic. | | Admin → Pattern C (category tabs + sidebar) | done | Delete custom `admin-topbar`. `setLeft()` for favicon + "Administration". `setSlot()` for category tabs (People / Workflows / System / Monitoring). Admin sidebar (sub-navigation) unchanged — surface-owned, below the topbar. Bell + user menu come free from shell. Delete bespoke CatIcon renderer if using standard SVGs. | | Team Admin → Pattern B (flat tabs) | done | Delete custom topbar + sidebar nav. 5 sections (Members / Connections / Workflows / Settings / Activity — Groups removed) become flat tabs. Content full-width. `setTitle()` for team-specific name. Remove sessionStorage return URL. Fix signoff user display (`user_id` → `sw.users.displayName()`). | | Team Admin: remove Groups tab | done | 37-line dead-end. Read-only "No groups" with no create/docs/link. Remove until team-scoped group management is properly designed. | | Docs → Pattern A (default) | done | Delete explicit Topbar import. Shell topbar auto-renders with manifest title. Docs sidebar (document list) is in content area, unaffected. | **Error Handling + UX Pass** | Step | Status | Description | |------|--------|-------------| | Inline error states | done | Replace `catch { toast }` with inline error + retry on all list endpoints. New `.sw-inline-error` CSS primitive. Systematic pass across Settings, Admin, Team Admin. | | Empty state guidance | done | Every "No X" message gets one-line explanation + primary action (create button or doc link). Admin Groups, Workflows, Teams; Team Admin Workflows; Settings Notifications. | **Bug Fixes** | Step | Status | Description | |------|--------|-------------| | evil-chat cleanup | done | ICD security tier: `finally` cleanup block + tighten `409` assertion. | | Workflow demo error surfacing | done | Replace silent `catch` with inline error + retry. | | Hello dashboard removal | done | Delete `packages/hello-dashboard/`. | **Rebrand** | Step | Status | Description | |------|--------|-------------| | Light-mode icon SVG | done | New `favicon-light.svg` — square icon, transparent bg, dark node fills. Rename current `favicon-light.svg` (wordmark) to `wordmark.svg`. | | Dark-mode wordmark SVG | done | New `wordmark-dark.svg` — light text for dark backgrounds. | | Light-mode raster assets | done | `favicon-light-32.png`, `favicon-light-256.png`. | | PWA manifest description | done | "Self-hosted extension platform — build, compose, and run extensions." | | REBRAND-SPEC.md | | Land into `docs/`. Find/replace patterns, validation checklist, asset inventory. | | base.html favicon swap | done | Verify theme swap works with new square light icon. | **Tests** | Step | Status | Description | |------|--------|-------------| | Shell topbar renders for extensions | done | Home, left slot, center slot, bell, user menu present. | | Topbar API (setLeft, setSlot, hide) | done | Custom content renders. Hide removes topbar. | | All 4 surfaces use shell topbar | done | No double topbars. Each pattern (A/B/C) renders correctly. | | User menu reactive to package install | | Install → menu updates without reload. | | Notification bell cross-surface sync | | Dismiss on Notes → clears on Chat. | | Inline error on API failure | | Error + retry shown, not empty list. | ### v0.7.1 — Surface Runner Framework Design doc: `docs/DESIGN-surface-runners.md` | Step | Status | Description | |------|--------|-------------| | Runner framework (`sw.testing`) | done | SDK module: suite/test/assert, lifecycle hooks, structured JSON results. | | `requires` declarations | done | Runner manifests declare dependencies. Missing packages → clean skip. | | Cleanup enforcement | done | `s.track(type, id)` auto-deletes in `afterAll`. No leaked state. | | Warning tier | done | pass / fail / warning. No silent catch swallowing. | | ICD runner migration | done | Refactor to `sw.testing`. Test logic preserved. | | SDK runner migration | done | Refactor to `sw.testing`. Domain suites preserved. | | Runner registry surface | done | `/s/test-runners` — list runners, run-all, results dashboard. | ### v0.7.2 — Package Runners + CI Gate | Step | Status | Description | |------|--------|-------------| | Notes runner | done | `requires: ["notes"]`. 3 suites (crud, folders, tags-search), 12 tests. | | Chat runner | done | `requires: ["chat", "chat-core"]`. 2 suites (conversations, messaging), 9 tests. | | Schedules runner | done | `requires: ["schedules"]`. 1 suite (crud), 5 tests. | | Workflow runner | done | `requires: ["content-approval"]`. 1 suite (lifecycle), 5 tests. | | Renderer runner | done | `requires: ["mermaid-renderer"]`. 1 suite (contract), 4 tests. | | Runner result API | done | `POST/GET /api/v1/admin/test-runners/results`. In-memory store, 4 Go tests. | | CI integration | done | `test-runners` stage in Gitea CI. Playwright driver, `wait-for-healthy.sh`. | | CI DinD networking fix | done | Resolve container IP via `docker inspect` — DinD port mapping doesn't expose to runner localhost. | ### v0.7.3 — Extension Shell Migration Chat, Notes, and Schedules still use the old `sw.shell.Topbar` component, producing a double topbar (shell-injected + surface-owned). Migrate all three to the v0.7.0 shell contract (`sw.shell.topbar.setTitle/setSlot`), same pattern as the kernel surface migrations. | Step | Status | Description | |------|--------|-------------| | Chat → shell topbar | done | Delete ``, use `setTitle('Chat')` + `setSlot()` for thread title/people button. | | Notes → shell topbar | done | Delete ``, use `setTitle('Notes')` + `setSlot()` for action buttons. | | Schedules → shell topbar | done | Delete ``, use `setTitle('Schedules')` + `setSlot()` for count/new button. | | Update package runner tests | done | Shell-topbar test suite in each runner — assert no legacy Topbar, uses shell API. | ### v0.7.4 — Documentation + Deferred Surface Work | Step | Status | Description | |------|--------|-------------| | Permissions & Groups guide | | RBAC model, permission slugs with descriptions, group scoping, settings cascade. | | Workflows user guide | | Entry modes, stages, team roles, signoff gates, SLA, public forms. | | Docs content refresh | | Review all 5 existing docs for accuracy at v0.7.x. | | Extension config section docs | | Document `config_section` manifest field for Settings/Admin extensibility. | | Team Admin Workflows evaluation | | 723-line inline designer — extract to surface or split into files. Decision doc if needed. | ### v0.7.5 — Headless E2E + CI Gate | Step | Status | Description | |------|--------|-------------| | Playwright test harness | | `ci/e2e-surface-test.sh` — docker-compose, chromium, run-all, assert. | | Screenshot-on-failure | | Full-page screenshot + console log. CI artifacts. | | Navigation smoke test | | Playwright visits every surface. Asserts topbar, no JS errors, home link works. | | Visual regression baseline | | Optional screenshot diff. Not a gate — report for review. | | CI pipeline integration | | Enable `test-runners` stage, add `e2e-smoke` stage. Failure blocks merge. | --- ## Post-v0.7.x - **LLM participation** (`llm-bridge` extension) - **Rich media extensions:** image generation, code sandbox, STT/TTS - **Desktop app** (Tauri or Electron) - **Sidecar tier:** container-based extensions - **Federation:** cross-instance package sharing - **Plugin marketplace** with signing and review --- ## Design Decisions Log | Decision | Rationale | |----------|-----------| | Tasks → extension | Three trigger primitives replace the monolithic scheduler. | | Sessions removed | Workflow instances with dedicated storage replace kernel sessions. | | `custom` stage mode | Delegates to a surface package, proving extension composability. | | Providers removed from kernel | Connections + Starlark `provider.complete` as the interface. | | Kernel permissions simplified | 6 platform permissions. Extensions define their own. | | Preact+htm retained | 3KB runtime, no build step, KISS. | | Single Docker image | Go binary + assets + migrations. | | Admin → RBAC group | Grant check replaces role check. | | Settings cascade | Scope auth + `user_overridable`. Two orthogonal axes. | | No new migrations pre-MVP | Proper versioned migrations post-MVP. | | Chat as extension, not kernel | Zero kernel awareness. Proves extensibility thesis. | | PG as consensus layer | UNLOGGED node_registry + LISTEN/NOTIFY. No etcd/Consul/Redis. | | Two trigger tiers | Extension-declared (full sandbox) vs user ad-hoc (restricted). | | Builtin package rationale | Must enhance kernel surfaces or demonstrate platform capabilities. | | Two-slot topbar model | Left slot (title/branding) + center slot (`flex: 1`, tabs/pickers). Two named slots cover every navigation pattern: simple title (Pattern A), flat tabs full-width (Pattern B), category tabs + surface-owned sidebar (Pattern C). Surfaces without sub-items get full content width; surfaces with hierarchical navigation add their own sidebar below the topbar. Shell provides the stage; surface decides the theater. | | All four primary surfaces migrate to shell topbar | Admin was "keep custom topbar" initially. The two-slot model makes it unnecessary — category tabs fit in the center slot, sidebar is surface-owned below. One topbar implementation replaces four. Bell + user menu + reactivity come free on every surface. | | Settings / Team Admin → flat tabs (Pattern B) | Both had thin sidebars (~140px) that consumed width without justification. 5–6 sections fit cleanly in topbar tabs. Full-width content is a better use of space for these surfaces. | | Team Admin Groups removed | 37-line read-only dead-end. Admin Groups has full CRUD. Restore when properly designed. | | Docs is the reference surface | Only surface with shell Topbar, bell, user menu, inline errors. Others converge. | | Surface runners over expanding ICD | Different test tier, different failure class. | | Headless E2E via Playwright | Runners produce structured JSON; Playwright navigates and reads output. |