Files
ThothII/task-10-report.md
T

94 lines
4.4 KiB
Markdown

# Task 10 — Workspace Registry Manager Publish UX
## Delivered
- Added a typed `WorkspacePublishDialog` with an explicit two-stage flow: validate the
canonical draft, then confirm publication. The dialog displays the action and pinned base
revision before a request can be sent.
- Connected the workspace editor's Publish action and staged deletion action to that dialog;
local browser drafts remain local until the explicit confirmation.
- Added registry pull, workspace bundle import, and Blob-URL export controls. Imports are saved
as browser-only drafts and never publish automatically; export URLs are revoked after download.
- Added field-level 409 conflict presentation with base, local, and registry values. The only
recovery actions are Pull latest registry and Reload workspace; no automatic merge, overwrite,
or re-publication occurs.
- Kept diagnostics user-initiated and restricted UI/API draft data to canonical workspace fields.
Conflict payloads now pass through the canonical draft sanitizer and reject unknown/secret
fields before rendering.
## Review round 1
- Replaced the pull/reload-only conflict recovery with an explicit choice of the local draft or
registry value for every changed field. A revised draft can be saved only after every field has
a choice; it is rebased to the conflict's `actual.commit` and `actual.blob` and is never
published automatically.
- Kept normal validation and the explicit publish confirmation as mandatory steps after saving a
resolution. Nothing silently discards the local draft or merges it into the registry.
- Added typed expected/actual conflict revisions, displayed the active registry `status.head`
commit, and whitelisted every canonical `diagnostics.*` leaf path structurally.
## TDD evidence
- Wrote the publish-dialog and manager import/export tests before the implementation and observed
the expected RED failures (missing dialog/import control).
- Added a regression test for conflict payloads containing a secret field and observed it fail
before wiring the conflict parser through the canonical sanitizer.
- Added a regression test for a failed pull during conflict recovery and observed the original
unhandled rejection before adding the redacted in-dialog error state.
- Added review-round tests first for per-field local/registry selection, rebased draft saving
without a second publish, active-commit rendering, and every canonical diagnostics conflict
path; these initially failed against the pull/reload-only UI and narrow path parser.
## Review round 2
- Fixed recursive registry diffs so add/remove changes to optional nested diagnostics branches
report their actual canonical paths instead of the fallback `workspace.id`. The regression cases
cover both add and remove for `diagnostics.dwh_rest` and
`diagnostics.vector_rest.reversible_probe`.
- Extended the conflict-path allowlist to accept the optional `diagnostics` root and every
optional diagnostics branch. The existing structural rebase now saves an explicitly selected
branch (including an added or removed branch) in the revised browser draft, still pinned to the
registry's actual revision and requiring normal validation and confirmation before publishing.
- Wrote the backend/frontend cases first and observed the expected RED failures: backend conflict
fields were `workspace.id`, while the frontend rejected the safe conflict payload before the
resolution UI could render.
## Verification
Run in `frontend/` after the final changes:
```text
npx vitest run src/shell/WorkspacePublishDialog.test.tsx src/api/workspaces.test.ts src/shell/WorkspaceManager.test.tsx src/workspaces/drafts.test.ts
# 4 files passed, 47 tests passed
npx tsc -b
# exit 0
```
```text
npx vitest run
# 51 files passed, 398 tests passed
```
Round-2 focused verification:
```text
backend: npx vitest run test/workspace-registry.test.ts
# 1 file passed, 23 tests passed
backend: npx tsc --noEmit -p .
# exit 0
frontend: npx vitest run
# 51 files passed, 398 tests passed
frontend: npx tsc -b
# exit 0
```
The full backend `npx vitest run` was also attempted after allowing its local SSE test socket.
The Task 10 registry tests passed, but seven unchanged SSE/session tests fail because their
default, unbootstrapped registry makes session authorization return the intentional
`session storage is unavailable` response. This failure is outside the Task 10 diff; it persists
without any changed Task 10 route or test-harness code.