Changeset 0.28.7 (#193)

This commit is contained in:
2026-03-15 15:45:00 +00:00
parent bffda043db
commit 3237d55e0c
82 changed files with 2481 additions and 2771 deletions

View File

@@ -33,10 +33,15 @@ v0.9.xv0.27.5 Foundation → Extensions → Surfaces → Auth ✅
├─ v0.28.6 Infrastructure ✅
│ (virtual scroll, Helm, system tasks,
│ broadcast, git keygen, model prefs)
└─ v0.28.7 Unified Packaging + Task RBAC
└─ v0.28.7 Unified Packaging + Task RBAC
(.pkg archive, manifest.type,
task permission gate pre-Starlark)
v0.28.8 ICD Green Board
(provider timeout resilience, CORS
lockdown, SDK base path fix, WS
ticket exchange)
v0.29.0 Starlark Sandbox
(eval loop, permissions, admin UI
— adds starlark capability to .pkg)
@@ -337,73 +342,61 @@ pre-positions for `starlark` tasks in v0.29.0.
Depends on: v0.28.5 (SDK — pipe/filter registration is part of manifest contract).
**Archive format:**
- [ ] `.pkg` archive: zip containing `manifest.json` + assets (JS, CSS,
- [x] `.pkg` archive: zip containing `manifest.json` + assets (JS, CSS,
templates, icons). Same structure as `.surface` archives, extended
manifest schema
- [ ] `manifest.type` field: `surface` (routes + templates + data loader),
- [x] `manifest.type` field: `surface` (routes + templates + data loader),
`extension` (hooks + tools + pipes, no own route), `full` (both).
Absent `type` defaults to `surface` for backward compat
- [ ] `manifest.pipes` key: declarative pipe filter registration (pre-send,
- [x] `manifest.pipes` key: declarative pipe filter registration (pre-send,
post-receive, post-render) with priority and entry function reference.
Wired by SDK on extension load
- [ ] `manifest.tools` key: LLM-callable tool declarations (existing schema,
- [x] `manifest.tools` key: LLM-callable tool declarations (existing schema,
now part of unified manifest)
- [ ] `manifest.hooks` key: EventBus subscriptions (existing schema from
- [x] `manifest.hooks` key: EventBus subscriptions (existing schema from
EXTENSIONS.md, carried forward)
**Install infrastructure:**
- [ ] `POST /admin/packages/install` — unified install endpoint. Reads
- [x] `POST /admin/packages/install` — unified install endpoint. Reads
`manifest.type`, validates type-specific requirements, wires subsystems.
Replaces `POST /admin/surfaces/install` (old route kept as alias)
- [ ] Validation branches by type: `surface` requires `routes`/`template`,
- [x] Validation branches by type: `surface` requires `routes`/`template`,
`extension` requires at least one of `hooks`/`tools`/`pipes`, `full`
requires both sets
- [ ] Admin UI: merge Surfaces + Extensions into single "Packages" section.
Type badge on each entry. Filter by type. Enable/disable granular
for `full` packages (disable hooks independently of routes)
- [ ] `packages` table (or rename `surfaces``packages` with migration):
adds `type` column, retains all existing surface columns
- [x] Admin UI: merge Surfaces + Extensions into single "Packages" section.
Type badge on each entry. Filter by type.
- [x] `packages` table: replaces both `surface_registry` and `extensions`.
Text slug PKs, type/version/tier/scope/is_system columns.
**Migration:**
- [ ] Existing `.surface` archives install unchanged (type defaults to
`surface`). No re-install required
- [ ] Existing `extensions` table rows (loose-JS browser extensions) get
synthetic package wrappers: migration generates `manifest.json` from
existing DB fields, archives JS entry file into `.pkg` format
- [ ] `build.sh` in `surfaces/` updated to produce `.pkg` files. Directory
optionally renamed to `packages/`
- [ ] ICD runner surface install tests updated to use new endpoint (or alias)
- [x] Existing `.surface` archives install unchanged (type defaults to
`surface`). Re-install required after DB rebuild.
- [x] `extensions` table removed. Builtin extensions re-seed into `packages`
table at startup via `SeedBuiltinPackages()`.
- [x] `build.sh` in `packages/` produces `.pkg` files. Directory
renamed from `surfaces/`.
- [x] ICD runner surface install tests updated to use new endpoint (or alias)
**Task RBAC:**
Permission gate on task creation by `task_type` and `scope`. Must ship
before Starlark (v0.29.0) — cannot allow server-side code execution
without a permission model. Also retroactively locks down `action` tasks.
Permission gate on task creation by `task_type`. Uses existing group
permission model — no new `task_permissions` table. `task_type` is
immutable on PATCH (not in `TaskPatch` struct).
- [ ] `task_permissions` table (or extend `extension_permissions` pattern):
maps `(user_id | team_id | role) → task_type → allowed`. Default
permissions seeded on migration:
- Admin: all types, all scopes
- Team admin: `prompt`, `workflow` (team scope). `action` denied by default
- User: `prompt`, `workflow` (personal scope). `action` denied by default
- `system` always admin-only (hardcoded, not in permissions table)
- [ ] Create/update task handlers check permission before accepting
`task_type`. Existing `action` tasks grandfathered (can run, cannot
be cloned or created without permission). Migration adds warning
notification to owners of existing `action` tasks
- [x] `task.starlark` permission constant pre-positioned in
`AllPermissions`. Handler rejects with 400 referencing v0.29.0.
- [x] `task.action` permission gate on create (existing, v0.28.0).
`system` type hardcoded admin-only (existing, v0.28.6).
- [x] Go tests: starlark rejected, system non-admin denied, action
without permission denied
- [ ] Admin UI: task permission management — per-user and per-team overrides.
"Allow action tasks for Team X" toggle. Pre-positions `starlark`
permission type (hidden until v0.29.0 enables it)
- [ ] `POST /api/v1/tasks` and `PATCH /api/v1/tasks/:id` validate
`task_type` against caller's permissions. 403 on denied type
- [ ] ICD tests: permission-denied task creation, team admin boundaries,
admin override
**ICD + docs:**
- [ ] `packages.md` ICD: install, list, enable/disable, delete, type filtering
- [ ] `EXTENSIONS.md` updated: packaging section references `.pkg` format,
loose-JS model documented as legacy
- [ ] `tasks.md` ICD updated: permission model, per-type RBAC
- [x] `packages.md` ICD: install, list, enable/disable, delete, type filtering
- [x] `extensions.md` + `surfaces.md` redirected to `packages.md`
- [x] `tasks.md` ICD updated: permission matrix, `task_type` immutability
- [ ] ICD runner gains `packaging` test tier: install surface-type, install
extension-type, install full-type, type validation, backward compat
@@ -417,13 +410,71 @@ without a permission model. Also retroactively locks down `action` tasks.
---
## v0.28.8 — ICD Green Board
Close out pre-existing ICD test failures. Gate: 543/543 (100%) on the
ICD runner before starting v0.29.0 feature work.
Depends on: v0.28.7 (unified packaging).
**Provider tier — upstream timeout resilience (6 failures):**
The provider test tier calls `POST /admin/models/fetch` to sync the
model catalog from the upstream provider (Venice). When Venice is slow
(>30s), the Gin handler times out, the reverse proxy returns 502, and
every subsequent provider test fails (bulk enable, model list, team
creation for provider scoping, BYOK creation).
- [ ] Request timeout on outbound provider HTTP calls: `http.Client`
with configurable timeout (default 30s). Currently uses
`http.DefaultClient` with no timeout in `providers/sync.go`.
- [ ] `POST /admin/models/fetch` returns 504 (not 502) on upstream
timeout, with `{"error": "upstream timeout: <provider>"}`.
Currently the reverse proxy manufactures the 502 from a broken
connection.
- [ ] ICD runner provider tier: retry `models/fetch` once on 502/504
before failing. Slow providers are a fact of life; the test
should tolerate one retry.
**SDK tier — base path in sw.api calls (4 failures):**
`sw.api.get('/api/v1/health')` calls `API._get('/api/v1/health')`
which prepends `window.__BASE__`. In the ICD runner context on a
`/dev` base path deployment, `__BASE__` is `/dev`, so the request
goes to `/dev/api/v1/health` — correct. The 502s here are cascading
from the same upstream provider timeout that poisons the proxy
connection pool. These will resolve when the provider timeout fix
lands. No SDK code change needed.
- [ ] Confirm SDK 502s are gone after provider timeout fix (no
independent fix required)
**Security transport — CORS + WebSocket (2 failures):**
Both are informational findings from the v0.28.4 security tier.
They're real issues but low severity (P2).
- [ ] `CORS_ALLOWED_ORIGINS` enforcement: currently `*` in all
environments. Production should restrict to the actual domain.
Add validation: if `CORS_ALLOWED_ORIGINS` is unset or `*`, log
a warning at startup. Document in ARCHITECTURE.md.
- [ ] WebSocket ticket exchange: replace `?token=` query parameter
(JWT visible in server logs, proxy logs, browser history) with a
short-lived opaque ticket. `POST /api/v1/ws/ticket` returns a
single-use token (UUID, 30s TTL, stored in memory/Redis).
WebSocket connects with `?ticket=` instead. Server validates
and deletes on use. This is a protocol change — coordinate with
frontend `events.js` WebSocket connection logic.
---
## v0.29.0 — Starlark Sandbox + Permission Model
Server-side extension runtime. Prove the eval loop, permission pipeline,
and admin UI before adding capabilities.
Depends on: v0.28.0 (platform polish — specifically v0.28.7 unified packaging),
extension infrastructure (v0.11.0).
Depends on: v0.28.8 (ICD green board — clean test baseline before feature work),
v0.28.7 (unified packaging), extension infrastructure (v0.11.0).
- [ ] `go.starlark.net` integration (eval loop, timeout, memory ceiling)
- [ ] Permission model: manifest declarations, admin grant/revoke, DB schema