diff --git a/CHANGELOG.md b/CHANGELOG.md index df45468..31618dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,53 @@ All notable changes to Armature are documented here. +## v0.7.9 — Workflow Independence Audit + +Workflows proven independent of chat and all optional packages. Critical +rendering bugs fixed, dead chat UI removed, deferred test debt closed. + +**RenderWorkflow Fix (critical)** + +- `RenderWorkflow()` was a stub that never loaded instance/stage data — post-start page was broken. Now loads instance by token/ID, resolves current stage, populates all template fields. +- `WorkflowPageData` fields renamed: `ChannelID` → `EntryToken`, `ChannelTitle` → `WorkflowTitle`, `ChannelDescription` → `WorkflowDescription` (vestigial chat-era names) +- Stage modes aligned: template uses Go constants (`form`, `review`, `delegated`, `automated`) instead of legacy `form_only`/`form_chat` +- Dead chat UI removed: chat CSS, split layout, `sendMessage()`, fallback chat branch (~180 lines deleted from `workflow.html`) +- Landing page mode conditionals updated to match Go constants +- OpenAPI `stage_mode` enum corrected (4 occurrences) + +**Bug Fixes (found during verification)** + +- Entry token resolution: handler passed route param (instance ID) as entry token to JS. Fixed: resolve actual token from `inst.EntryToken` + `?token=` query param. +- Fieldset submit guard: `submitForm()` checked `FORM_TPL.fields` but not `.fieldsets` — progressive forms silently no-op'd. Fixed: accept either. +- Stage advance status check: JS checked `result.status === 'advanced'` but API returns `active`/`completed`. Fixed: on 200 OK with `active`, reload to render next stage. + +**Deferred test coverage (carried from v0.7.6)** + +- 17 new SQLite store tests: workflow CRUD, stages, instances, lifecycle (advance/complete/cancel/stale), team scope, API tokens, users, groups +- `InstallPackage` decomposed from 400-line monolith into 7 private methods: `receiveUpload`, `parseAndValidateArchive`, `extractPackageAssets`, `registerPackage`, `applySchemaAndPermissions`, `resolveDependencies`, `checkCapabilities` +- `ci/e2e-workflow-nochat.sh` — E2E test for workflow lifecycle without chat + +**Discovered issues (deferred to v0.7.10)** + +- Public→authenticated stage handoff: visitor sees auth-gated stage form instead of "submitted" screen +- Team member pickup UI: no surface for claiming workflow instances +- Assignment flow: no admin UI for manual instance assignment + +**Tests:** 17 new store tests, 1 new E2E script + +--- + +## v0.7.8 — Bug Fixes & Admin Gaps + +- `StartBySlug` handler + `/api/v1/workflow-entry/:scope/:slug` route for landing page Start button +- Workflow delete guard: admin endpoint rejects team-scoped workflows (403) +- Package button cleanup: Delete hidden for bundled packages +- Package export: `fetch()` with auth token instead of `window.open()` +- Settings CSS: bottom padding fix for save button cutoff +- Shared `StageForm` component between admin and team-admin; public entry URL with copy button + +--- + ## v0.7.7 — API Tokens + Extension Permissions Personal access tokens (PATs) for programmatic API access, plus extension-declared diff --git a/ROADMAP.md b/ROADMAP.md index a63dcda..9dd3fc4 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -305,7 +305,39 @@ workflows but never be required for core operation. | Store unit tests (SQLite) | done | 17 tests: workflow CRUD, stages, instances, lifecycle (advance/complete/cancel/stale), team scope, API tokens, users, groups. Carried from v0.7.6. | | InstallPackage decomposition | done | Split 400-line handler into 7 private methods: `receiveUpload`, `parseAndValidateArchive`, `extractPackageAssets`, `registerPackage`, `applySchemaAndPermissions`, `resolveDependencies`, `checkCapabilities`. Carried from v0.7.6. | -### v0.7.10 — Query & HTTP Ergonomics +**Bug Fixes (found during verification)** + +| Step | Status | Description | +|------|--------|-------------| +| Entry token resolution | done | `RenderWorkflow()` passed route param (instance ID) as entry token. JS then sent instance ID to the advance API which expects entry token. Fixed: resolve actual token from `inst.EntryToken` + check `?token=` query param. | +| Fieldset submit guard | done | `submitForm()` checked `FORM_TPL.fields` but not `.fieldsets` — progressive forms silently no-op'd on submit. Fixed: accept either. | +| Stage advance status check | done | Template JS checked `result.status === 'advanced'` but API returns instance status (`active`/`completed`). Fixed: on 200 OK with `active` status, reload to render next stage. | + +**Discovered issues (deferred)** + +The audit uncovered deeper workflow UX gaps that are out of scope for v0.7.9: + +1. **Public→authenticated stage handoff** — After a public visitor completes their stages, the workflow advances to an authenticated stage (e.g. "classify"). The visitor sees the next stage's form + an auth error instead of a "thank you, we'll take it from here" message. The page should detect audience mismatch and show a completion/waiting screen. +2. **Team member pickup UI** — No surface exists for team members to see workflow instances assigned to their team and claim/work on them. Currently only visible in team-admin monitoring. +3. **Assignment flow** — No mechanism for team admins to assign a specific instance to a specific team member. The `workflow_assignments` table exists but has no admin UI for manual assignment. + +These will be addressed in a future version (see v0.7.10 below). + +### v0.7.10 — Workflow Handoff + Assignment UI + +Addresses the three UX gaps found during the v0.7.9 independence audit. +The workflow engine and data model already support these flows — the +missing pieces are page-level audience detection and team-facing UI. + +| Step | Status | Description | +|------|--------|-------------| +| Public stage completion screen | | When `RenderWorkflow()` detects the current stage's audience is `team`/`system` but the visitor is unauthenticated, render a "Submitted — your request is being reviewed" screen instead of the stage form. | +| Team workflow inbox | | New section in team-admin (or dedicated surface): list active instances assigned to this team, with claim/unclaim actions. Uses existing `ListAssignmentsByTeam` store method. | +| Manual assignment UI | | Team admin can assign an unclaimed instance to a specific team member. Uses existing `CreateAssignment` store method. | +| Assignment notifications | | When an instance is assigned (auto or manual), notify the assignee via the notification system. | +| E2E multi-stage test | | Full lifecycle: public form → team pickup → review → complete. Verified with both authenticated and unauthenticated users. | + +### v0.7.11 — Query & HTTP Ergonomics (was v0.7.10) Four additions to existing sandbox modules. No new files beyond tests, no schema changes. Motivated by real-world extension porting feedback: @@ -320,7 +352,7 @@ remaining friction points for extensions migrating from native Go/Python. | `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 +### v0.7.12 — Concurrent Execution Primitive (was v0.7.11) New `batch` sandbox module. Enables extensions to parallelize arbitrary Starlark callables — including library function calls via `lib.require()`.