Task 02 (the whole runner) ended at 21:08 with no file and no commit: Ornith wrote the
implementation out in its reply (~700 lines), OpenCode compacted the session, and the model
then emitted a malformed tool call. It had also looked for the given test at a wrong path
("_files/…" relative to the plan: my ambiguity).
- 02-runner → 02-runner-core (types, Submit, Status, Touch, Cancel; no goroutines) and
03-runner-workers; the given test split to match (runner_core_test.go gains three tests:
queued storage, cancel while queued, Status never moves the lease); later tasks renumbered
04-09 and every cross-reference checked.
- Copy paths spelled from the repo root.
- guard.PreCheck (+ its test) is committed here by the owner: the old task 05 told the
implementer to edit internal/guard/, which AGENTS.md forbids. My contradiction.
- AGENTS.md rule 6: write code into files early, in small steps.
Both runner test files compile against a panic-only skeleton (the core file also alone) and
fail there on panic: todo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.1 KiB
P6 task 05: extract v1fetch's pipeline into fetchTarget
Branch: p6 (git switch p6; git status --short must be empty, otherwise stop)
Commit subject: api: v1fetch's per-target pipeline becomes fetchTarget (no behaviour change)
This is the one task in P6 that edits working code. It is a move, not a rewrite: the reviewer will diff the old
v1fetchbody againstfetchTargetline by line.
Goal
v1fetch today inlines the whole per-target pipeline: fetch → recover → PDF render or clean →
question limit → digest → context → log line → envelope. The batch worker (task 06) needs the
same pipeline for one target. Move it into one method that both call:
// internal/api/target.go
func (s *Server) fetchTarget(ctx context.Context, c *auth.Caller, t batch.Target) (batch.Result, error)
v1fetch keeps its exact responses. Every existing api test must pass unchanged.
Files
- Copy:
docs/plans/p6/_files/api/fetchtarget_test.go→internal/api/fetchtarget_test.go - Create:
internal/api/target.go(fetchTarget) - Modify:
internal/api/api.go(v1fetchshrinks;doFetchtakes acontext.Contextin place of the*http.Request, and its call sites passr.Context()),docs/implementer-log.md
What already exists
// internal/batch (task 02)
type Options struct{ Mode, Question, Pages, Grep, JQ string; Context *bool; Recover bool }
type Target struct{ URL string; Options Options }
type Result struct{ Content string; Meta map[string]any }
fetch.Error{Status int; Msg, Hint string; RetryAfter int} is the error type writeFetchErr
already turns into a response.
Rules
- What stays in
v1fetch:s.reqN.Add(1), the caller check, decodingv1Req, and the400 invalid urlfor a bad body or an empty URL. Then it builds abatch.Targetfrom the request (URL, andMode,Question,Pages,Grep,JQ,Context,RecoverintoOptions), callss.fetchTarget(r.Context(), c, t), and:- on an error,
s.writeFetchErr(w, c, req.URL, err); - on success,
writeJSON(w, 200, env)whereenvisres.Metaplus"content": res.Content.
- on an error,
- What moves into
fetchTarget, in the same order and unchanged: the question truncation to 500 runes, the mode default and check,wantCtx,doFetch, the recover path (recover.Try(ctx, …)), the PDF branch (render,pages/greperrors, the question-chunk limit), the clean/raw branch, the digest, the context search, thefetchlog line, and the envelope. - Errors that
v1fetchwrote directly withwriteErrbecome*fetch.Errorvalues with the same status, message and hint:400 invalid urlfor a bad mode,400 raw mode does not apply to PDFs.writeFetchErrthen writes them exactly as before. The only visible difference is itsfetch failedlog line, which is fine. - The envelope:
fetchTargetreturnsResult{Content: content, Meta: m}wheremholds every other key of today'soutmap (mode,untrusted,source,warnings,sizes,timings, andpdf,digest,contextwhen present). Never putcontentinMeta. doFetch(ctx, c, rawURL, jq, onlyMain):r.Context()becomesctx. That is the only change indoFetch.scrape(the other caller) passesr.Context().- No new behaviour, no new log fields, no renamed JSON keys. If something cannot move without changing behaviour, stop and report it.
Steps
- 1.
git switch p6; copy the given test. 2. See it fail (fetchTargetundefined). - 3.
doFetch(ctx, …)and its call sites. 4.target.go. 5. Shrinkv1fetch. - 6.
gofmt -w;go test -race -count=3 ./internal/api/→ok, every existing test included. 7.make gate. - 8. Row
p6/05-fetchtarget; commit.
git add internal/api docs/implementer-log.md
git commit -F .state/commit-msg.txt
Done when
- The two given tests and every existing api test pass under
-race -count=3, with no existing test file modified;make gateok; the given file is byte-identical.
Stop and report if
- An existing api test fails and fixing it would need a change to that test.