diff --git a/ROADMAP.md b/ROADMAP.md index d937573..f6832a5 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -268,15 +268,66 @@ sidecar auth (v0.10.x). | `gate_permission` manifest field | done | Optional. If set, `ext_api.go` checks this permission before calling `on_request`. Extension doesn't execute for unauthorized users. | | `req["permissions"]` in request dict | done | `ext_api.go` resolves user permissions and includes them in the request dict. Extensions can check inline without the module. | -### v0.7.8 — Deferred Test Coverage - -Remaining test gap items deferred from v0.7.6. +### v0.7.8 — Bug Fixes & Admin Gaps | Step | Status | Description | |------|--------|-------------| -| store/ unit tests | | Direct tests for PG + SQLite store implementations. Priority: packages, ext_data, workflows. Target: ≥30% SLOC ratio. | -| InstallPackage decomposition | | 224 cognitive complexity. Split into: validate → create → DDL → permissions → triggers. Each independently testable. | -| workflow/ engine integration tests | | Engine lifecycle tests with mock stores (Start, Advance, Cancel, signoff gate). | +| Workflow landing page Start | done | Added `StartBySlug` handler + `/api/v1/workflow-entry/:scope/:slug` route. Landing page Start button now resolves scope/slug → workflow ID and creates instance. | +| Workflow delete guard | done | Admin `DELETE /api/v1/workflows/:id` rejects team-scoped workflows (403). Team workflows must use team endpoint. Prevents accidental global template deletion. | +| Package button cleanup | done | Delete button hidden for `bundled` packages via `IMMUTABLE_SOURCES` guard, matching Export/Update. | +| Package export fetch | done | Export uses `fetch()` with auth token instead of `window.open()`. Handles errors, shows toast on missing assets. | +| Settings CSS fix | done | Bottom padding increased to `--sp-12` on `.admin-settings-form`. Save button no longer cut off. | +| Admin stage builder + links | done | Shared `StageForm` component between admin and team-admin. Public entry URL with copy button in admin workflow editor. | + +### v0.7.9 — Workflow Independence Audit + +Workflows must work end-to-end without chat or any 3rd-party package +dependency. Chat, notifications, and other packages should *enhance* +workflows but never be required for core operation. + +| Step | Status | Description | +|------|--------|-------------| +| Public entry flow | | Verify workflow start → instance creation → stage progression works without chat package installed. Landing page → form → completion. | +| Stage mode degradation | | All stage modes (`form_only`, `form_chat`, `review`) degrade gracefully when optional packages missing. `form_chat` without chat falls back to form-only. | +| Instance lifecycle | | Create, advance, complete, cancel — full lifecycle without chat dependency. Engine doesn't error when chat unavailable. | +| Admin/team-admin UI | | All CRUD, monitoring, and stage builder work without optional packages. No broken references. | +| E2E without chat | | Landing page → instance → stage progression → completion tested with chat package disabled. | +| Deferred test coverage | | store/ unit tests (PG + SQLite), InstallPackage decomposition, workflow/ engine integration tests. Carried from v0.7.6. | + +### v0.7.10 — Query & HTTP Ergonomics + +Four additions to existing sandbox modules. No new files beyond tests, +no schema changes. Motivated by real-world extension porting feedback: +complex SQL decomposition and synchronous HTTP fan-out are the two +remaining friction points for extensions migrating from native Go/Python. + +| Step | Status | Description | +|------|--------|-------------| +| `db.count()` | | `db.count(table, filters={})` → int. `SELECT count(*) FROM ext_{pkg}_{table} WHERE ...`. Uses existing `starlarkFiltersToSQL` builder. Permission: `db.read`. ~40 lines in `db_module.go`. | +| `db.aggregate()` | | `db.aggregate(table, column, op, filters={})` → single value. `op` ∈ {`count`, `sum`, `avg`, `min`, `max`}. Column name validated same as filter keys. Returns int/float/None. Permission: `db.read`. ~60 lines in `db_module.go`. | +| `db.query_batch()` | | `db.query_batch(queries)` → list of result sets. Each query spec is a dict with `table` (required), `filters`, `order`, `limit`, `before`, `after`, `search_like` (all optional, same as `db.query`). Loops existing query builder internally — one Starlark↔Go boundary crossing instead of N. Permission: `db.read`. ~30 lines in `db_module.go`. | +| `http.batch()` | | `http.batch(requests)` → list of response dicts (ordered). Each request dict: `method`, `url`, `body`, `headers`. Concurrent dispatch via goroutines capped at 10, `sync.WaitGroup` collection. Reuses existing `httpDo` plumbing (SSRF checks, domain allowlist, body cap, timeout). Individual failures return error response dicts, don't abort batch. Permission: `api.http`. ~80 lines in `http_module.go`. | +| Tests | | Unit tests for all four builtins. `db.count`/`db.aggregate` test empty table, filtered, type coercion. `db.query_batch` test mixed specs, empty list. `http.batch` test concurrent execution, partial failure, ordering. PG + SQLite for db tests. | + +### v0.7.11 — Concurrent Execution Primitive + +New `batch` sandbox module. Enables extensions to parallelize arbitrary +Starlark callables — including library function calls via `lib.require()`. +The kernel manages concurrency (multiple `starlark.Thread` instances in +goroutines); extensions stay single-threaded and synchronous from the +author's perspective. + +Key insight: library exports loaded via `lib.require()` are frozen structs +(immutable, safe to share across threads). Each concurrent branch gets +fresh module instances (`db`, `http`, etc.) — same pattern as +`buildRestrictedModules` in `triggers/schedule.go`. + +| Step | Status | Description | +|------|--------|-------------| +| Design doc | | `docs/DESIGN-batch-exec.md`. Thread isolation model, module construction, error semantics (partial results on failure), permission model, concurrency cap. | +| `batch.exec()` | | `batch.exec(callables)` → `(results, errors)` tuple. List of Starlark callables (lambdas, function refs). Each runs in its own `starlark.Thread` with fresh modules. Concurrent goroutines capped at 8. Ordered results. Errors are per-callable (None on success, string on failure). Permission: `batch.exec` (new). New file: `sandbox/batch_module.go`. | +| Runner wiring | | `buildModulesWithLibCtx` creates `batch` module when `batch.exec` permission granted. Module receives runner reference for per-branch module construction. | +| Tests | | Unit tests: parallel execution ordering, partial failure, cap enforcement, frozen library sharing, permission gating. | ---