~bigbes/sr-ht-spec · events

h50lp0nmdsvvcp3hgrvl679ci61ie4h2 · 31 rows

idissue_idevent_typeactorold_valuenew_valuecommentcreated_at
019f8d29-5397-7e0d-b817-f81fc1ea0840spec-ejqcreatedEugene BlikhNULL2026-07-23T07:08:43Z
019f8d29-8cc1-7d90-b19d-8c7c5c36b37cspec-zqbcreatedEugene BlikhNULL2026-07-23T07:08:58Z
019f8d29-f61c-7c87-aa9f-c2d08aa053despec-3vzcreatedEugene BlikhNULL2026-07-23T07:09:25Z
019f8d29-fb60-73a1-be7f-c0199fcc676aspec-by6createdEugene BlikhNULL2026-07-23T07:09:26Z
019f8d2a-5ea5-7e9e-aab2-44c0ca2eb3c7spec-wcrcreatedEugene BlikhNULL2026-07-23T07:09:52Z
019f8d2a-626d-73e4-9e8d-d0df4ddd8437spec-ar4createdEugene BlikhNULL2026-07-23T07:09:53Z
019f8d2a-66d9-73c8-b102-455f9cb41611spec-43wcreatedEugene BlikhNULL2026-07-23T07:09:54Z
019f8d51-a40a-7cec-9ccc-53dcd00c9666spec-43wclosedEugene BlikhStale apk pins already bumped in the stack versions.env (paste 0.19.4-r0, hub 0.31.1-r0); fixed out of band.NULL2026-07-23T07:52:45Z
019f8d51-d807-7465-87f6-e94b035bd584spec-zqbclaimedEugene Blikh{"id":"spec-zqb","title":"Phase 3: write plane — agents propose","description":"The agent half of the loop, and the service's whole premise: an agent proposes a document change, gets back a link, a human approves in a browser. Until this ships, agents can only read.","design":"Scope: proposals (branch proposals/\u003cid\u003e + Postgres row, state open-\u003emerged|rejected); the If-Match tree-splice merge with the four staleness cases and the ancestry check gitx flagged; the single agent token + mandatory provenance trailers; spec_propose / spec_comment over REST + MCP; every write response returns {proposal, url} so the agent can hand over a link. Prereqs found during Phases 1-2: (1) service.ListProposals(space, state) — graph proposal listing is stubbed and db only has ListProposalsByState; (2) IsAncestor(proposalHead, H) check before Merge so an already-merged proposal reports 'already merged' not a confusing 409; (3) auto-merge policy evaluation (.spec.yml AutoMerges) which the reconciler's 'approval=policy' inference also wants. Dispatch like Phases 1-2: proposal orchestration in service/ first and committed, then surface tools fan out. This is where the merge model and reconciler first run under real proposals rather than on paper.","status":"open","priority":1,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-23T04:08:58Z","created_by":"Eugene Blikh","updated_at":"2026-07-23T04:08:58Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-07-23T07:52:59Z
019f8d73-0a9b-7e86-8f51-1851559c98a1spec-jjocreatedEugene BlikhNULL2026-07-23T08:29:14Z
019f8d73-443d-74e2-b383-b1fe9cac3f89spec-zqbclosedEugene BlikhWrite plane shipped: service.Propose/Merge/Reject/ListProposals with provenance trailers, auto-merge policy, If-Match staleness + already-merged ancestry check; surfaces graph (Proposals port), mcpsrv spec_propose, and new api/ REST PUT — every write returns {proposal, url}. Validated end-to-end against Postgres. spec_comment deliberately deferred to Phase 5 (spec-by6), which gates the comment schema on the Phase 4 review UI; the approve/reject browser UI is Phase 4 (spec-3vz).NULL2026-07-23T08:29:29Z
019f8dac-62b4-7586-b6ed-d1fd10a209a3spec-3vzclaimedEugene Blikh{"id":"spec-3vz","title":"Phase 4: review plane — approve/reject in a browser","description":"Proposal pages at stable URLs (returned by every write), the inbox, prose diff, approve (merges immediately) / reject, status lifecycle, and the digest of policy-merged firehose content.","design":"Productionise prosediff (the Phase 0 spike) into the review UI. CRITICAL requirement from the Phase 0 verdict: 13% of real prose modifications shred into interleaved fragments (similarity \u003c= 0.73), so the UI MUST switch to a two-column old/new view below ~0.75 and inline word diffs above it — building only the inline renderer makes one review in eight unreadable. The prosediff package already emits the (Hash, HeadingPath, Ordinal) comment-anchor tuple. Reads a proposal branch via service.ReadDocumentAtRef (the deliberately-awkward bypass), never the normal read path.","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-23T04:09:25Z","created_by":"Eugene Blikh","updated_at":"2026-07-23T04:09:25Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-07-23T09:31:52Z
019f8dbf-9f12-71ad-be1a-25ad050b8655spec-mfmcreatedEugene BlikhNULL2026-07-23T09:52:53Z
019f8dbf-a581-7353-ac71-aac7403f5466spec-3vzclosedEugene BlikhReview plane shipped: proposal page at /~owner/space/p/<id> with the prose diff (inline word-diff above 0.75 similarity, two-column old/new below — the Phase 0 verdict's hard requirement, in web/diff.go), approve(merge)/reject as owner-only CSRF-guarded POSTs, status badges, and the /inbox review queue + policy-merged digest. service.ProposalDiff/InboxProposals/DigestProposals/MergeHuman back it; web.Reader extended. Diff reads the proposal branch by resolving its tip to a sha (pinned read) rather than the ReadDocumentAtRef bypass — cleaner and immutable. Validated: diff renderer unit tests (inline/two-column/escaping), proposal-page + approve/reject handler tests (CSRF, owner-only, stale->409, wrong-space->404), inbox tests, and PG-backed service tests. Follow-up: digest_mark 'since last seen' tracking.NULL2026-07-23T09:52:55Z
019f8dc8-d95b-7daf-90cd-eaf2e7575e02spec-3m9createdEugene BlikhNULL2026-07-23T10:02:58Z
019f8dc8-ded8-7301-8f4b-b77fa045ed8bspec-3m9claimedEugene Blikh{"id":"spec-3m9","title":"Phase 5a: webhooks + notifications on proposal lifecycle","description":"Emit webhooks on proposal open/merge/reject so external systems and email learn about review events. core-go/webhooks is GraphQL-native; the Phase 2 read schema at /query is the foundation. First slice of Phase 5 (spec-by6).","status":"open","priority":3,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-23T07:02:58Z","created_by":"Eugene Blikh","updated_at":"2026-07-23T07:02:58Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-07-23T10:02:59Z
019f91de-d454-75cc-97d7-7252b2993b83spec-3m9updatedEugene Blikh{"id":"spec-3m9","title":"Phase 5a: webhooks + notifications on proposal lifecycle","description":"Emit webhooks on proposal open/merge/reject so external systems and email learn about review events. core-go/webhooks is GraphQL-native; the Phase 2 read schema at /query is the foundation. First slice of Phase 5 (spec-by6).","status":"in_progress","priority":3,"issue_type":"feature","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-07-23T07:02:58Z","created_by":"Eugene Blikh","updated_at":"2026-07-23T07:03:00Z","started_at":"2026-07-23T07:03:00Z"}{"description":"Phase 5a: webhooks via FULL core-go convention adoption (user chose to match pages.sr.ht/lists.sr.ht byte-for-byte). Prerequisite: retrofit graph/ onto core-go conventions (database.Model, @access/@private directives, cursor pagination, auth.Middleware + a user model with OAuth2 scopes). Then add gql_proposal_wh_sub/_delivery + webhook SDL/resolvers/delivery on top. Reference: ~/data/home/tmp/pages.sr.ht (same fork). Large graph rewrite, not additive."}NULL2026-07-24T05:05:27Z
019f91de-d881-7cf8-818f-bf93678361f1spec-8y4createdEugene BlikhNULL2026-07-24T05:05:28Z
019f91de-da86-7dac-9775-7ea6c0d049bdspec-45jcreatedEugene BlikhNULL2026-07-24T05:05:29Z
019f9388-60c0-7c63-af2a-72a4204c086fspec-45jclosedEugene BlikhWebhook tables/SDL/resolvers/delivery all shipped and verified end-to-end.NULL2026-07-24T12:50:16Z
019f9388-6565-776a-9981-597c97d03836spec-8y4closedEugene BlikhAdopted core-go server stack for /query (faithful path); the convention pieces webhooks needed (auth/database/server context, database.Model for webhook models, gqlgen) are in.NULL2026-07-24T12:50:17Z
019f9388-67e2-7ae1-a922-4d6512ee0c21spec-3m9closedEugene BlikhPhase 5a webhooks complete: DB + authn→AuthContext bridge + GraphQL surface + core-go server wiring + firing. Verified live: agent REST propose delivers an Ed25519-signed POST whose body is the subscription query executed against the ProposalEvent payload; delivery recorded.NULL2026-07-24T12:50:18Z
019f9501-8f28-7cb9-adf5-63cf96358bd3spec-jjoclaimedEugene Blikh{"id":"spec-jjo","title":"MCP read tools (/mcp) have no auth gate — reads are open behind the Host check","description":"Phase 3 added the resolver middleware to /mcp so spec_propose can resolve the agent, but the read tools (spec_search/spec_read/spec_list) still have no ACL: anyone passing the Host allowlist can read approved content. graph's /query gates to owner+agents (graph.gate); /mcp does not. The design's read plane is fail-closed (owner+agents only). Add the same gate to the MCP surface. Pre-existing since Phase 2; not caused by Phase 3, but now that /mcp resolves a principal the gate is a one-liner. Deliberately left out of Phase 3 to avoid changing Phase 2 read behavior mid-feature.","status":"open","priority":3,"issue_type":"bug","owner":"bigbes@gmail.com","created_at":"2026-07-23T05:29:15Z","created_by":"Eugene Blikh","updated_at":"2026-07-23T05:29:15Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-07-24T19:42:15Z
019f9504-4ff9-71f0-99e6-f4ecb18a35b1spec-ejq.1createdEugene BlikhNULL2026-07-24T19:45:15Z
019f9504-8f0b-769f-ae58-fa2d2f33e332spec-jjoclosedEugene BlikhMCP surface gated to owner+agents (mcpsrv.Gate), mounted inside resolver middleware; tests cover anon 401 / owner+agent pass / fail-closed without middleware. Commit 7cc652d.NULL2026-07-24T19:45:31Z
019f9508-0fe2-7cec-b14d-74d325836985spec-mfmclaimedEugene Blikh{"id":"spec-mfm","title":"Digest should track 'since you last looked' via digest_mark, not just show recent policy-merges","description":"Phase 4 ships the policy-merged digest as 'recent policy-merged proposals' (service.DigestProposals). The design intends it as 'what auto-merged since you last saw the digest', backed by the digest_mark table (db.GetDigestMark/SetDigestMark, already present). Advancing the mark is a write, and the inbox GET is deliberately kept pure, so this needs either a POST 'mark as seen' action or an accepted side-effecting GET. Low priority: the digest already surfaces auto-merged content, which is its core purpose.","status":"open","priority":3,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-23T06:52:53Z","created_by":"Eugene Blikh","updated_at":"2026-07-23T06:52:53Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-07-24T19:49:21Z
019f950c-69d6-7547-95f1-4bca5bc75604spec-mfmclosedEugene BlikhInbox GET reads digest_mark to flag/count new-since-last-looked auto-merges + divider (pure read); explicit POST /inbox/seen advances the mark behind owner-only + same-origin guard. service.DigestMark/MarkDigestSeen added. Commit 865a21f.NULL2026-07-24T19:54:06Z
019f950f-ceba-7c44-a1be-2d446fb75666spec-ejq.1claimedEugene Blikh{"id":"spec-ejq.1","title":"Consolidate owner+agents read predicate into one Principal.CanRead()","description":"graph/server.go:161, web/handlers.go:61 and now mcpsrv.Gate each hand-spell 'IsOwner() || IsAgent()'. graph.gate's own comment warns two read surfaces with two policies is how a corpus leaks — there are now three copies. Add authn.Principal.CanRead() and route all three through it so the policy is defined once. Low-risk mechanical refactor; deferred out of spec-jjo to keep that bug fix surgical.","status":"open","priority":4,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-07-24T16:45:16Z","created_by":"Eugene Blikh","updated_at":"2026-07-24T16:45:16Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-07-24T19:57:48Z
019f9511-6765-7a54-b5ac-1c081434f0cfspec-ejq.1closedEugene Blikhauthn.Principal.CanRead() defined once; graph.gate, web.mayRead, mcpsrv.Gate routed through it. coreauth left independent (different semantic). Unit test covers owner/agent true, anon/zero/unknown false. Commit pending push.NULL2026-07-24T19:59:33Z
019f9515-34a5-7a5c-8fe0-0e1298c0b6dcspec-wcrupdatedEugene Blikh{"id":"spec-wcr","title":"Loose ends from Phases 1-2 (latent bugs, no user impact yet)","description":"Real issues agents flagged and deliberately left alone during the parallel build. None blocks anything today; each is a trap for a later phase.","design":"1. ProposalBranch derived THREE ways: core.ProposalBranch (canonical), and a third copy in SQL — db.OpenProposal concatenates prefix||serial in its INSERT to allocate id+branch atomically. Shares the prefix constant but not the function; reconcile if they can ever diverge. 2. doc.linkHierarchy passes path.Dir(p.Path) i.e. '.' as fromDir where every other call site uses DirOf ('') — section-proximity lookup misses for root-level parent: targets. Latent; fixing changes resolution behaviour. 3. doc.SplitLog collides entry IDs within a space (two type:log docs -\u003e identical IDs -\u003e second silently overwrites first in one index). Defended in search/ but should be fixed at source in doc/. 4. doc.Scan/DocumentSource are production-dead after service.Archive landed — they're the documented seam but also the API that made web's layering violation writable; delete is a judgement call. 5. mcpsrv ships a beforeCAS test hook in production code (gitx too). 6. No GraphQL complexity limit — service authenticates on its own router, not core-go's WithSchema, so nothing bounds query cost; low risk on a single-user authed surface. 7. Attachments: gitx walks .md only, so image embeds render as visibly-missing; needs WalkBlobs + asset index, or prefer Mermaid by convention.","status":"open","priority":3,"issue_type":"chore","owner":"bigbes@gmail.com","created_at":"2026-07-23T04:09:52Z","created_by":"Eugene Blikh","updated_at":"2026-07-23T04:09:52Z"}{"notes":"Triage 2026-07-24 (post Phase 5a). Investigated all 7 items:\n\n#1 ProposalBranch 3rd copy in OpenProposal SQL — DONE (commit e97532c): pure-Go guard test TestOpenProposalBranchMatchesCanonical asserts BranchPrefix||id == core.ProposalBranch(id). No behavior change.\n\n#2 linkHierarchy path.Dir vs DirOf — JUDGEMENT CALL, deferred. Fixing changes link-resolution behavior for root-level parent: targets; needs a design decision + fixture confirming intended resolution before touching.\n\n#3 SplitLog id collision — NOT A BUG as feared. Already correctly defended in search/extract.go (logEntries substitutes p.ID for the log# prefix → space-unique). \"Fix at source in doc/\" would push search-index-keyspace uniqueness into doc/, which shouldn't know it's indexed into a shared space index. Current layering (doc/ = within-doc identity, search/ = index-key uniqueness) is arguably correct. Recommend WONTFIX unless a second SplitLog consumer appears.\n\n#4 delete doc.Scan/DocumentSource — JUDGEMENT CALL (deletion), deferred. Production-dead after service.Archive; also the seam that made web's layering violation writable. Lean delete, but confirm no external/test reliance first.\n\n#5 beforeCAS \"test hook in production\" — NOT A BUG. gitx.beforeCAS is an unexported field set only by same-package tests (write_test/merge_test); zero prod cost, cannot be set externally. Standard test-seam pattern. mcpsrv has no such hook (item wording conflated). Recommend WONTFIX.\n\n#6 no GraphQL complexity limit — FEATURE, deferred. Low risk on single-user authed surface; wire only if /query is ever widened.\n\n#7 attachments (gitx walks .md only) — FEATURE, deferred. Real work: WalkBlobs + asset index, or adopt Mermaid-by-convention. Phase 5+ scope.\n\nActionable-now clear win (#1) done. Remainder are judgement calls (#2,#4), non-issues (#3,#5), or features (#6,#7) — each needs a decision, not mechanical fixing."}NULL2026-07-24T20:03:42Z
019f954f-6055-774f-a234-abcf74285abaspec-wcrclaimedEugene Blikh{"id":"spec-wcr","title":"Loose ends from Phases 1-2 (latent bugs, no user impact yet)","description":"Real issues agents flagged and deliberately left alone during the parallel build. None blocks anything today; each is a trap for a later phase.","design":"1. ProposalBranch derived THREE ways: core.ProposalBranch (canonical), and a third copy in SQL — db.OpenProposal concatenates prefix||serial in its INSERT to allocate id+branch atomically. Shares the prefix constant but not the function; reconcile if they can ever diverge. 2. doc.linkHierarchy passes path.Dir(p.Path) i.e. '.' as fromDir where every other call site uses DirOf ('') — section-proximity lookup misses for root-level parent: targets. Latent; fixing changes resolution behaviour. 3. doc.SplitLog collides entry IDs within a space (two type:log docs -\u003e identical IDs -\u003e second silently overwrites first in one index). Defended in search/ but should be fixed at source in doc/. 4. doc.Scan/DocumentSource are production-dead after service.Archive landed — they're the documented seam but also the API that made web's layering violation writable; delete is a judgement call. 5. mcpsrv ships a beforeCAS test hook in production code (gitx too). 6. No GraphQL complexity limit — service authenticates on its own router, not core-go's WithSchema, so nothing bounds query cost; low risk on a single-user authed surface. 7. Attachments: gitx walks .md only, so image embeds render as visibly-missing; needs WalkBlobs + asset index, or prefer Mermaid by convention.","notes":"Triage 2026-07-24 (post Phase 5a). Investigated all 7 items:\n\n#1 ProposalBranch 3rd copy in OpenProposal SQL — DONE (commit e97532c): pure-Go guard test TestOpenProposalBranchMatchesCanonical asserts BranchPrefix||id == core.ProposalBranch(id). No behavior change.\n\n#2 linkHierarchy path.Dir vs DirOf — JUDGEMENT CALL, deferred. Fixing changes link-resolution behavior for root-level parent: targets; needs a design decision + fixture confirming intended resolution before touching.\n\n#3 SplitLog id collision — NOT A BUG as feared. Already correctly defended in search/extract.go (logEntries substitutes p.ID for the log# prefix → space-unique). \"Fix at source in doc/\" would push search-index-keyspace uniqueness into doc/, which shouldn't know it's indexed into a shared space index. Current layering (doc/ = within-doc identity, search/ = index-key uniqueness) is arguably correct. Recommend WONTFIX unless a second SplitLog consumer appears.\n\n#4 delete doc.Scan/DocumentSource — JUDGEMENT CALL (deletion), deferred. Production-dead after service.Archive; also the seam that made web's layering violation writable. Lean delete, but confirm no external/test reliance first.\n\n#5 beforeCAS \"test hook in production\" — NOT A BUG. gitx.beforeCAS is an unexported field set only by same-package tests (write_test/merge_test); zero prod cost, cannot be set externally. Standard test-seam pattern. mcpsrv has no such hook (item wording conflated). Recommend WONTFIX.\n\n#6 no GraphQL complexity limit — FEATURE, deferred. Low risk on single-user authed surface; wire only if /query is ever widened.\n\n#7 attachments (gitx walks .md only) — FEATURE, deferred. Real work: WalkBlobs + asset index, or adopt Mermaid-by-convention. Phase 5+ scope.\n\nActionable-now clear win (#1) done. Remainder are judgement calls (#2,#4), non-issues (#3,#5), or features (#6,#7) — each needs a decision, not mechanical fixing.","status":"open","priority":3,"issue_type":"chore","owner":"bigbes@gmail.com","created_at":"2026-07-23T04:09:52Z","created_by":"Eugene Blikh","updated_at":"2026-07-24T17:03:43Z"}{"assignee":"Eugene Blikh","status":"in_progress"}NULL2026-07-24T21:07:15Z