Fix #253: create tag from UI #262

Merged
crueber merged 2 commits from fix/issue-253 into main 2026-09-10 01:06:26 +00:00
Owner

Fixes #253: create a lightweight tag at a given commit from the commit-view UI, server-side via the WAL ref-update path.

What: new internal/tags package + POST /{o}/{r}/api/tags (both lanes, Seam 1) publishing one EntryKindRefUpdate CAS-create — no new WAL kind. Commit.jsx gains a write-gated Create-tag affordance; SDK gains repo.tagsApi.create; create tag → create release now works end to end.

Design call (documented in docs/go/14_extensibility.md Decisions): lightweight-only v1 (recommended option (a)/(c)) — annotated (non-empty message) → 422, never a silent downgrade; object-write path under frozen proto rules is the follow-up. P6 = RoleWrite (push-equivalent) + explicit policy EvaluateProtect create-check (pull-merge precedent). Validation: git refname rules (400), sha must resolve (404), existing tag → 409 via publish verify (race-safe). Events ride the existing WAL bridge identically to pushed tags.

Tests: internal/tags 98.4% statements (go test -race clean); table-driven httptest (201/400/404/409/422/401/403/405); real-git CommitExists tests; end-to-end through a real WAL registry (cmd/walhub: create → sync-visible → 409 → restart-replay from wiped cache); SDK surface tests (node --test); releases/events/policy suites green; gofmt/vet clean.

Deviations/notes: no browser drive (per task note — shared daemon blocks loopback); full node --test shows 7 pre-existing failures from missing node_modules (solid-js/marked) in this env, unrelated files; make e2e/sim not run (no wal/git-path changes — new package reuses the existing publish funnel); .gitignore re-includes internal/tags/ against blanket ctags tags ignores.

Fixes #253: create a lightweight tag at a given commit from the commit-view UI, server-side via the WAL ref-update path. **What:** new `internal/tags` package + `POST /{o}/{r}/api/tags` (both lanes, Seam 1) publishing one `EntryKindRefUpdate` CAS-create — no new WAL kind. Commit.jsx gains a write-gated Create-tag affordance; SDK gains `repo.tagsApi.create`; create tag → create release now works end to end. **Design call (documented in docs/go/14_extensibility.md Decisions):** lightweight-only v1 (recommended option (a)/(c)) — annotated (non-empty message) → 422, never a silent downgrade; object-write path under frozen proto rules is the follow-up. P6 = RoleWrite (push-equivalent) + explicit policy EvaluateProtect create-check (pull-merge precedent). Validation: git refname rules (400), sha must resolve (404), existing tag → 409 via publish verify (race-safe). Events ride the existing WAL bridge identically to pushed tags. **Tests:** `internal/tags` 98.4% statements (`go test -race` clean); table-driven httptest (201/400/404/409/422/401/403/405); real-git CommitExists tests; end-to-end through a real WAL registry (`cmd/walhub`: create → sync-visible → 409 → restart-replay from wiped cache); SDK surface tests (`node --test`); releases/events/policy suites green; gofmt/vet clean. **Deviations/notes:** no browser drive (per task note — shared daemon blocks loopback); full `node --test` shows 7 pre-existing failures from missing `node_modules` (solid-js/marked) in this env, unrelated files; `make e2e/sim` not run (no wal/git-path changes — new package reuses the existing publish funnel); `.gitignore` re-includes `internal/tags/` against blanket ctags `tags` ignores.
New internal/tags package (docs/go/14_extensibility.md Decisions):
POST /{o}/{r}/api/tags (+ api-browser twin, Seam 1) publishes one
EntryKindRefUpdate CAS-create; no new WAL kind. Lightweight-only v1:
non-empty message -> 422 (annotated needs a tag object the frozen
proto cannot carry; follow-up). P6 RoleWrite + policy EvaluateProtect
(principal, refs/tags/<name>, create); git refname validation (400),
sha must resolve (404), existing tag 409 via publish verify. Events
ride the existing WAL bridge unchanged. UI: Create-tag affordance on
Commit.jsx (write-gated) + SDK repo.tagsApi.create. Also re-includes
internal/tags/ against blanket ctags ignores.
The CreateTag submit handler calls reportError(err, "create-tag") on
failure but the data.js import lacked the name — a ReferenceError that
masked the real server error. Same import shape as Access/Issue pages.
Sign in to join this conversation.
No description provided.