3c563e4d
feat(web): proposal review page — prose diff + approve/reject (Phase 4)
The browser review plane at /~owner/space/p/<id>, the stable URL every write already returns. The owner opens the link an agent handed them, reads a prose diff of each changed document, and approves (merges now) or rejects. - web/diff.go: the prose-diff HTML renderer, consuming prosediff's block model (the package renders text only; HTML is the web layer's job). It implements the Phase 0 verdict's hard requirement — inline word diffs above 0.75 block similarity, a two-column old/new view below it, because 13% of real edits shred and are unreadable inline. All document content is HTML-escaped; only the diff structure is markup. - service/review.go: ProposalDiff reads each changed document's base and proposed content for the page to diff (branch tip resolved to a sha, the legitimate pinned-rev read, not the ReadDocumentAtRef bypass), and MergeHuman fixes the approval kind so a browser approve is always human. - web/proposal.go: the GET page and the approve/reject POSTs. Only the owner may act (an agent is authenticated but has no more approval authority than anyone); a cross-site guard on Origin/Referer is the CSRF defense a form post needs when the session cookie is meta's. Post- redirect-get back to the page. Stale/already-merged approve → 409. - web.Reader gains the proposal reads and the two actions; the diff-view styles go in scss/main.scss (inline marks, two-column, code line diffs). Inbox and the policy-merged digest are the remaining Phase 4 surfaces.
Eugene Blikh <bigbes@gmail.com> — 2026-07-23 06:48:16 UTC
Commit 3c563e4d3eafe7ead010a894d18b0eb8ab31e6c5 —
view raw patch
Parent(s):
1476e065
| File | Status | + | − |
|---|---|---|---|
scss/main.scss
|
M | +149 | |
service/review.go
|
A | +103 | |
service/review_test.go
|
A | +77 | |
web/diff.go
|
A | +239 | |
web/diff_internal_test.go
|
A | +90 | |
web/handlers.go
|
M | +11 | |
web/proposal.go
|
A | +203 | |
web/proposal_test.go
|
A | +221 | |
web/reader.go
|
M | +45 | -3 |
web/router.go
|
M | +8 | |
web/templates.go
|
M | +1 | -1 |
web/templates/proposal.html
|
A | +64 | |
web/web_test.go
|
M | +66 | -5 |