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.0 KiB
P6 task 04: sift_batch_* series in internal/metrics
Branch: p6 (git switch p6; git status --short must be empty, otherwise stop)
Commit subject: metrics: sift_batch_* series (jobs, targets, depth, in-flight, durations, bytes)
Add the batch series to internal/metrics so the caps (32 targets, 1 job/caller, 8 jobs total)
and the byte budget can be re-sized from observed data. This task touches only
internal/metrics: task 06 wires these methods to the runner's batch.Hooks.
Series (names and label values exact — the given test asserts these)
| Metric | Type | Labels / meaning |
|---|---|---|
sift_batch_jobs_total |
counter | outcome ∈ created, reused, done, partial, failed, cancelled, restart |
sift_batch_targets_total |
counter | outcome ∈ ok, blocked, timeout, busy, upstream_4xx, upstream_5xx, unsupported, too_long, cancel |
sift_batch_queue_depth |
gauge | live jobs (queued+running) |
sift_batch_targets_inflight |
gauge | targets currently being fetched |
sift_batch_job_seconds |
histogram | wall time from submit to terminal status |
sift_batch_target_seconds |
histogram | wall time per target |
sift_batch_result_bytes |
histogram | stored bytes per target result |
Classifying an error into a target outcome is task 06's job (it has the *fetch.Error); this
package only records the label it is given.
Public surface (exact names — the given test compiles against them)
// fields added to metrics.Set (registered in New)
BatchJobsTotal *prometheus.CounterVec // label "outcome"
BatchTargetsTotal *prometheus.CounterVec // label "outcome"
BatchQueueDepth prometheus.Gauge
BatchTargetsInflight prometheus.Gauge
BatchJobSeconds prometheus.Histogram
BatchTargetSeconds prometheus.Histogram
BatchResultBytes prometheus.Histogram
// methods (nil-guarded, like ObservePDF)
func (s *Set) ObserveBatchJob(outcome string)
func (s *Set) ObserveBatchTarget(outcome string)
func (s *Set) SetBatchQueueDepth(n int)
func (s *Set) SetBatchTargetsInflight(n int)
func (s *Set) ObserveBatchJobSeconds(d time.Duration)
func (s *Set) ObserveBatchTargetSeconds(d time.Duration)
func (s *Set) ObserveBatchResultBytes(n int)
Both outcome counters fold any value outside their known set to other — the same "a raw string
never becomes a label" guard as ObservePDF. Job outcomes: created, reused, done, partial, failed, cancelled, restart. Target outcomes: ok, blocked, timeout, busy, upstream_4xx, upstream_5xx, unsupported, too_long, cancel.
Rules
- A new file
internal/metrics/batch.goadds the series tometrics.Set(registered inNew), withObserve…/Set…methods mirroringObservePDF/ObserveDigest, nil-receiver safe. - Both
outcomecounters fold any value outside their known set toother: a raw string never becomes a label. - The series are exposed through the existing
/metricsand/metrics.jsonpaths: no new endpoint.Snapshot/writeMetricsJSONdo not need to list them. - Histogram buckets: seconds as the existing request histograms; bytes
1K, 4K, 16K, 64K, 256K, 1M.
Given
Copy docs/plans/p6/_files/metrics/batch_test.go → internal/metrics/batch_test.go. It drives the Observe…
methods, serves the /metrics handler (as pdf_test.go does), and asserts the exact series names,
label values, gauge values, histogram counts, and that a raw outcome string is folded to other.
Steps
- 1.
git switch p6; copy the given test. 2. See it fail. - 3.
internal/metrics/batch.goand the registration inNew. - 4.
gofmt -w;go test -race -count=3 ./internal/metrics/→ok. 5.make gate. - 6. Row
p6/04-metrics; commit.
git add internal/metrics docs/implementer-log.md
git commit -F .state/commit-msg.txt
Done when
- The given and existing metrics tests pass under
-race -count=3;make gateok; the given file is byte-identical.