capture #49c: Gitea IssueTracker client (new outbound dependency) #52
Closed
opened 2026-06-22 20:27:10 +00:00 by mathias
·
1 comment
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#52
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Parent: #49 · Spec:
specs/capture-bdd-spec.md§1 · Depends on: #51 (theIssueTrackerport) · Blocks: #49dScope
Implement the
IssueTrackerport (#51) as a real Gitea client. This is the new outbound dependency the brain server does not have today — per the #49 ground-truth, the brain server does brain-local file ops only and knows nothing about Gitea. Isolated and testable against a Gitea test instance.What to build
IssueTrackerimpl:CreateIssue(repo, title, body),CloseIssue(repo, number, comment),CommentIssue(repo, number, body). Owner is alwaysmathias(hard-coded; never caller-supplied).IssueTrackerinterface (swappable/testable — the use-case never sees the concrete type).Ticketreceipt fields ({repo, number, action, url, ok}).Acceptance criteria
IssueTrackerimplementing #51's port: create / close / commentmathias; never read from caller inputok:false+ message (best-effort; one failed ticket doesn't abort the call)task checkgreenNotes
Decision from #49: the Gitea client lives in the brain server, injected behind the interface — not a separate composing service. This keeps capture as one use-case while keeping the dependency swappable. The interface boundary is what lets #51's use-case tests stay hermetic (fake tracker) while this issue tests the real wire.
Implemented — PR #58 (open, stacked on #57)
PR: #58 · base
feat/capture-service(#52-only diff). Merge order: #56 → #57 → #58.ingestion/internal/gitea/—Clientimplementingcapture.IssueTracker:"mathias"— never a param; a caller can't redirect to another owner's repo.BRAIN_GITEA_TOKEN, only ever in theAuthorizationheader — never logged/argv.TestErrorPathDoesNotLeakTokenproves the token never appears in an error string.gitea.New→ nil when unconfigured.mcp.Server.WithIssueTracker(constructor injection) +IssueTracker()accessor;mainwires fromBRAIN_GITEA_URL(defaulthttps://git.d-ma.be) +BRAIN_GITEA_TOKEN. Consumed by the use-case in #53.Port refinement:
CloseIssuegained acommentparam to match this issue's spec; service passes the ticket body as the closing comment.Deploy note: 1Password
DMABE_GITEA_API_TOKEN→ maps toBRAIN_GITEA_TOKENin the k3s manifest (#55/infra). Secret never in repo/argv/logs.All ACs met (
httptest-backed: create/comment/close±comment/error/auth-header/owner-forcing);task checkgreen.Critical path next: #53 —
POST /captureREST adapter + OAuth2 + the I1 sovereignty gate (server-derived origin). All three converging deps (#50 classification, #51 service, #52 tracker) are now in flight; #53 wires them together and adds the origin gate. After #53 = "capture works" for direct-REST harnesses.