Some checks failed
CI/CD / detect-changes (pull_request) Successful in 3s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-runners (pull_request) Failing after 1m20s
CI/CD / e2e-smoke (pull_request) Failing after 1m20s
CI/CD / test-go-pg (pull_request) Successful in 2m45s
CI/CD / test-sqlite (pull_request) Successful in 2m51s
CI/CD / build-and-deploy (pull_request) Has been skipped
9 code smells from chat gut (dead channels references, stale routes), migration numbering gaps, and store/workflow/middleware test coverage gaps identified in April 2026 codebase analysis. Gate for v0.8.x. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
468 lines
27 KiB
Markdown
468 lines
27 KiB
Markdown
# Armature — Roadmap
|
||
|
||
## Current: v0.7.5 — Headless E2E + CI Gate
|
||
|
||
Self-hosted extensible platform kernel. 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 · Cluster registry + HA
|
||
|
||
**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 `<Topbar>`, use `setTitle('Chat')` + `setSlot()` for thread title/people button. |
|
||
| Notes → shell topbar | done | Delete `<Topbar>`, use `setTitle('Notes')` + `setSlot()` for action buttons. |
|
||
| Schedules → shell topbar | done | Delete `<Topbar>`, 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 |
|
||
|------|--------|-------------|
|
||
| Docs category grouping | done | Backend `Category` field on doc entries. Frontend groups sidebar by category with headings. Four categories: Getting Started, Platform, Extension Development, Operations. |
|
||
| Permissions & Groups guide | done | RBAC model, 7 permission slugs, system/custom groups, settings cascade, extension permissions. |
|
||
| Workflows user guide | done | Entry modes, stages, team roles, signoff gates, SLA, public forms, branch rules, Starlark hooks. |
|
||
| Starlark Reference | done | Sandbox constraints, 10 modules with function signatures, permission gates, example hook script. |
|
||
| Frontend JS Guide | done | Preact+htm runtime, 16 SDK modules with API reference, shell topbar patterns, CSS contract. |
|
||
| Extension config_section docs | done | Manifest schema, backend discovery, frontend contract, example component. Added to Extension Guide. |
|
||
| Docs content refresh | done | All 10 user-facing docs reviewed for v0.7.x accuracy: rebrand volume names, stale CSS vars, TLS_MODE env, self-hosted font notes, Architecture frontend section. |
|
||
| Team Admin Workflows split | done | 722-line `workflows.js` split into 3 modules: `workflows.js` (router+CRUD), `workflow-editor.js` (editor+stages), `workflow-monitor.js` (assignments+monitor+signoff). |
|
||
| Stale CSS variable fix | done | `--bg-2` references in `sw-shell.css` and `sw-primitives.css` replaced with `--bg-secondary`. |
|
||
|
||
### v0.7.5 — Headless E2E + CI Gate
|
||
|
||
| Step | Status | Description |
|
||
|------|--------|-------------|
|
||
| CI gating redesign | done | Fix path rules: `VERSION`/`scripts/*` deploy-only, `docs/*` no longer skips deploy, test-runners trigger on any code change. |
|
||
| E2E smoke test harness | done | `ci/e2e-smoke-test.sh` + `ci/e2e-smoke-driver.js` — Playwright visits every surface, asserts topbar, no JS errors, home link. |
|
||
| Screenshot-on-failure | done | Full-page screenshot + console log saved as CI artifacts. |
|
||
| CI pipeline integration | done | Re-enable `test-runners` stage, add `e2e-smoke` stage. Failure blocks merge. |
|
||
| Design docs landed | done | `docs/DESIGN-storage-primitives.md`, `docs/DESIGN-extension-composability.md`. Roadmap expanded through v1.0. |
|
||
|
||
### v0.7.6 — Code Hygiene + Test Coverage
|
||
|
||
Codebase analysis (April 2026) found 9 code smells from the chat gut and
|
||
a test coverage gap in the store layer. Fix before v0.8.x kernel expansion.
|
||
|
||
**Critical Fixes**
|
||
|
||
| Step | Status | Description |
|
||
|------|--------|-------------|
|
||
| Remove channels from allowedViews | | `db_module.go` — `ext_view_channels` does not exist. `db.view("channels")` crashes. |
|
||
| Fix workflow.html dead routes | | Template calls `/api/v1/channels/{id}/workflow/*` — routes moved to `/api/v1/public/workflows/`. Update template to match. |
|
||
|
||
**Dead Code Removal**
|
||
|
||
| Step | Status | Description |
|
||
|------|--------|-------------|
|
||
| Delete SeedTestChannel() | | `database/testhelper.go` — inserts into nonexistent channels table. |
|
||
| Remove RunContext.ChannelID | | `sandbox/runner.go` — vestigial field, unused by any module. |
|
||
| Remove webhook.ChannelID | | `webhook/webhook.go` — vestigial struct field from chat era. |
|
||
| Fix stale comments | | `storage.go` key format, `prometheus.go` route pattern — reference dead `/channels` paths. |
|
||
|
||
**Migration Hygiene**
|
||
|
||
| Step | Status | Description |
|
||
|------|--------|-------------|
|
||
| Align SQLite migration numbering | | SQLite 013 = test_runner_type, PG 014 = same. Add placeholder `013_cluster_registry.sql` to SQLite (comment-only, explains PG-only). |
|
||
| Document missing 008 | | Add comment in both 009 files explaining the gap (merged/removed). |
|
||
|
||
**Test Gap Closure**
|
||
|
||
| Step | Status | Description |
|
||
|------|--------|-------------|
|
||
| store/ unit tests | | Direct tests for PG + SQLite store implementations. Priority: packages, ext_data, workflows. Target: ≥30% SLOC ratio (from 2%). |
|
||
| workflow/ engine unit tests | | Direct tests for `engine.go`, `routing.go`, `automated.go`. Currently 0% — tested only through handler integration. |
|
||
| middleware/ unit tests | | Auth middleware, rate limit, permissions. Currently 8.9%. |
|
||
| InstallPackage decomposition | | 224 cognitive complexity. Split into: validate → create → DDL → permissions → triggers. Each independently testable. |
|
||
|
||
---
|
||
|
||
## Planned
|
||
|
||
### v0.8.x — Storage Primitives
|
||
|
||
Design doc: `docs/DESIGN-storage-primitives.md`
|
||
|
||
The last major kernel expansion. Completes the primitive set that the
|
||
entire extension ecosystem builds on. After v0.8.x, the kernel is
|
||
feature-complete for 1.0 — all new capabilities are extensions.
|
||
|
||
**v0.8.0 — `files` Module**
|
||
|
||
Bridge `ObjectStore` (PVC/S3) into the Starlark sandbox. Extension-scoped
|
||
key namespacing (`ext/{packageID}/`). Permissions: `files.read`,
|
||
`files.write`. Metadata companions stored as sibling objects.
|
||
|
||
New: `sandbox/files_module.go`. Modified: runner wiring, permission
|
||
constants.
|
||
|
||
**v0.8.1 — `workspace` Module**
|
||
|
||
Managed disk directories for tools that need a real filesystem (git,
|
||
compilers, media tools). `workspace.create(name)` → scoped path.
|
||
Permission: `workspace.manage`. Quota enforcement via `WORKSPACE_QUOTA_MB`.
|
||
|
||
New: `sandbox/workspace_module.go`. Modified: runner wiring, permission
|
||
constants.
|
||
|
||
**v0.8.2 — Capability Negotiation**
|
||
|
||
Extensions declare environment requirements in manifest (`capabilities.required`,
|
||
`capabilities.optional`). Kernel validates at install time. Runtime query
|
||
via `settings.has_capability()`. Admin endpoint: `GET /admin/capabilities`.
|
||
|
||
Detected capabilities: `pgvector`, `workspace`, `object_storage`, `s3`,
|
||
`postgres`.
|
||
|
||
New: `handlers/capabilities.go`. Modified: install handler, settings module.
|
||
|
||
**v0.8.3 — Vector Column Type**
|
||
|
||
`"vector(N)"` in `db_tables` manifest. Maps to native `vector(N)` on
|
||
PG+pgvector, `JSONB` on PG without, `TEXT` on SQLite. New `db.query_similar()`
|
||
with dual-path dispatch (native operator vs Go-side brute force).
|
||
|
||
Modified: `ext_db_schema.go`, `db_module.go`.
|
||
|
||
**v0.8.4 — Extension Composability**
|
||
|
||
Design doc: `docs/DESIGN-extension-composability.md`
|
||
|
||
Manifest declarations for `slots` (host surfaces declare injection points)
|
||
and `contributes` (extensions declare UI contributions to other packages'
|
||
slots). `lib.require()` relaxed from library-only to any package with
|
||
`exports` — enables full packages (with surfaces, settings, UI) to also
|
||
expose callable backend functions. `sw.slots.renderAll()` SDK helper.
|
||
Admin slot aggregation endpoint.
|
||
|
||
The composability primitive that enables: LLM tool registration, UI
|
||
contribution (toolbar buttons, image actions), and cross-extension
|
||
function calls. No new tables, migrations, or permissions.
|
||
|
||
Modified: `sandbox/lib_module.go` (~1 line), `handlers/extensions.go`,
|
||
`src/js/sw/sdk/slots.js`. New: `handlers/admin_slots.go`.
|
||
|
||
---
|
||
|
||
### v0.9.x — Reference Extensions
|
||
|
||
The kernel is complete. This series proves the platform by shipping
|
||
first-party extensions that exercise every primitive. These are
|
||
**extensions, not kernel code** — they ship as `.pkg` files and can be
|
||
uninstalled.
|
||
|
||
**v0.9.0 — `vector-store` Library**
|
||
|
||
Library extension: document ingestion, chunk storage, embedding persistence,
|
||
semantic similarity search. Three-tier vector strategy (pgvector → JSONB
|
||
fallback → TEXT fallback). Consumes: `db.write`, `files.read`.
|
||
|
||
**v0.9.1 — `llm-bridge` Library**
|
||
|
||
Library extension: model abstraction, tool-use routing, provider BYOK via
|
||
connections. Exposes `complete()`, `embed()`, `classify()`, `register_tool()`
|
||
to consumer extensions. Tool extensions (image-gen, code-exec, web-search)
|
||
register at load time — LLM discovers available tools automatically.
|
||
Consumes: `connections.read`, `api.http`, `db.write`.
|
||
|
||
**v0.9.2 — `file-share` Extension**
|
||
|
||
File upload via `api_routes`, storage via `files` module, download links,
|
||
optional team/group ACLs via resource grants. First extension to exercise
|
||
the full `files` primitive end-to-end.
|
||
|
||
**v0.9.3 — `code-workspace` Extension**
|
||
|
||
Managed code repositories via `workspace` module. Git clone/pull via
|
||
`api.http` to Gitea/GitHub API. File browser surface. Structural indexing
|
||
(AST-aware) for code navigation. Consumes: `workspace.manage`, `files.write`,
|
||
`api.http`.
|
||
|
||
**v0.9.4 — `image-gen` + `image-edit` Extensions**
|
||
|
||
Image generation via external APIs (DALL-E, Stable Diffusion). Registers
|
||
as LLM tool with `llm-bridge`. Contributes regen/edit buttons to
|
||
`chat:image-actions` slot. Image-edit extends with inpaint, outpaint,
|
||
upscale, and style transfer — each contributing action buttons to the
|
||
same slot independently. First full demonstration of the composability
|
||
pattern: three extensions contributing UI to a fourth's surface.
|
||
|
||
**v0.9.5 — Chat System**
|
||
|
||
Generic 1-to-N human messaging. `chat-core` library (conversation/message
|
||
CRUD) + `chat` surface. Declares `chat:message-actions`, `chat:image-actions`,
|
||
`chat:composer-tools` slots for extension contribution. LLM participation
|
||
as a follow-on consuming `llm-bridge`. Consumes: `db.write`,
|
||
`realtime.publish`, `files.write` (attachments).
|
||
|
||
---
|
||
|
||
### v0.10.x — Sidecar Tier + Polish
|
||
|
||
**v0.10.0 — Sidecar Tier**
|
||
|
||
Autonomous out-of-process extensions for workloads that can't run in
|
||
Starlark: ML inference, media transcoding, language servers, local git
|
||
operations. The kernel does NOT manage container lifecycle — sidecars
|
||
are independent processes (Docker, systemd, bare binary) that connect
|
||
inward to the kernel, following the cluster registry pattern:
|
||
|
||
- Sidecar boots with cluster config (instance URLs, credentials).
|
||
- Connects and self-registers, declaring capabilities ("sklearn",
|
||
"gpu", "ffmpeg", "sentence-transformers").
|
||
- Goes inert until an admin authorizes (same flow as extension permissions).
|
||
- Kernel dispatches work; sidecar returns results.
|
||
- Heartbeat keeps registration alive; missed heartbeat = eviction.
|
||
|
||
Communication channel TBD (WebSocket over existing event bus, gRPC, or
|
||
HTTP callback model — design doc required). Authentication via mTLS
|
||
certs or registration tokens.
|
||
|
||
This model eliminates k8s RBAC dependency for local deployments. The
|
||
kernel stays thin — it accepts registrations and dispatches work. The
|
||
sidecar brings its own compute and manages its own lifecycle.
|
||
|
||
**v0.10.1 — Native Dialog Audit**
|
||
|
||
Replace `prompt()`/`confirm()`/`alert()` with `sw.dialog` SDK primitives.
|
||
Accessible, themed, promise-based. Small kernel SDK change that improves
|
||
every surface.
|
||
|
||
**v0.10.2 — Stability + Migration Tooling**
|
||
|
||
Proper versioned migrations (post-MVP discipline). `armature migrate`
|
||
CLI command. Backup/restore validation against reference dataset.
|
||
Pre-1.0 schema freeze.
|
||
|
||
---
|
||
|
||
### v1.0.0 — Stable Release
|
||
|
||
The kernel API surface is frozen. Extensions are the product.
|
||
|
||
Gate criteria:
|
||
|
||
- All kernel Starlark modules documented with examples
|
||
- All `api_routes` covered by OpenAPI spec
|
||
- Upgrade path tested from v0.8.0 → v1.0.0
|
||
- At least 3 reference extensions shipped and tested (vector-store, llm-bridge, chat)
|
||
- At least 1 cross-extension composability demo (image-gen → chat:image-actions)
|
||
- Headless E2E green on PG + SQLite
|
||
- `armature-ca.sh` + mTLS deployment guide
|
||
- Single-binary + Docker + K8s deployment paths documented
|
||
|
||
---
|
||
|
||
## Post-1.0 Horizon
|
||
|
||
These are candidates, not commitments. Each requires a design doc.
|
||
|
||
- **Federation** — cross-instance package sharing, identity federation
|
||
- **Package marketplace** — signing, review, discovery registry
|
||
- **Desktop app** — Tauri wrapper for local-first deployment
|
||
- **Offline/sync** — SQLite-first with PG sync for field deployments
|
||
- **Multi-tenant SaaS mode** — tenant isolation at the team boundary
|
||
|
||
---
|
||
|
||
## Design Principles
|
||
|
||
| Principle | Implication |
|
||
|-----------|-------------|
|
||
| Extensions are the product | Chat, tasks, LLM, vector search, file sharing — all extensions. Zero kernel awareness of domain logic. |
|
||
| Kernel stays thin | New kernel primitives require justification. If it can be an extension, it must be. |
|
||
| Progressive enhancement | Every feature works on SQLite. PG adds performance. pgvector adds native vectors. S3 adds scalable storage. |
|
||
| KISS-first | No unnecessary dependencies. Preact+htm (3KB), single binary, dual-DB from one codebase. |
|
||
| Changeset discipline | Each CS independently CI-green. Design docs as implementation contracts. |
|
||
| Pre-1.0 migration freedom | Schema changes fold into existing migrations. Post-1.0: proper versioned migrations. |
|
||
|
||
---
|
||
|
||
## 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. |
|
||
| `db` module is the structured store | No separate KV primitive. Extensions declare tables — infrastructure exists. |
|
||
| `files` module rides ObjectStore | No new kernel tables. Metadata as companion objects. Works on PVC and S3 identically. |
|
||
| `workspace` for real filesystem | Flat blob store can't serve git/compilers/ffmpeg. Managed disk paths are the explicit escape hatch. |
|
||
| Capability negotiation at install | Fail loud with actionable message, not silently at runtime. |
|
||
| Vector column with three-tier fallback | Works everywhere, works fast with pgvector. Documentation > hard gates. |
|
||
| Sidecar deferred to v0.10.x | HTTP module covers external APIs. Local compute is a v0.10.x concern. Sidecars connect inward (like cluster nodes), not spawned outward (no k8s RBAC needed). |
|
||
| No second scripting runtime | Starlark for glue, HTTP for external compute, sidecars for local compute. Three tiers with clear boundaries. Lua/WASM middle tier rejected — Turing-complete enough to be dangerous, not isolated enough to be trustworthy. |
|
||
| Reference extensions prove the platform | First-party `.pkg` files, not kernel code. Uninstallable. Dogfooding. |
|
||
| Composability via slots + exports, not kernel | `sw.slots` + `sw.actions` + `lib.require()` are the composition primitives. Manifest declarations add admin visibility. No inter-extension message bus — too complex, too fragile. |
|