Watch
3
Measure where the 32.9s turn actually goes: a 116 KB prefix paid roughly six times per reply #1002
Closed
opened 2026-08-19 00:56:01 +00:00 by coilyco-ops
·
3 comments
No Branch/Tag specified
main
aos/claude/sj87-entity-attribute
aos/claude/sj87-challenge
aos/claude/turn-duration-buckets
aos/claude/turn-stages-over-cap
aos/claude/turn-stages-hold-doc
aos/claude/turn-iteration-cap
book-leads-the-glyphs
science-and-web-culture-packs
record-lane-role-voice-pairings
catalogue-stage-phrase
progress-rows-one-knob
skill-read-worklog-detail
librarian-lookup-first
librarian-person-package
feat/dowel-no-boundaries
aos/claude/gh1035-no-blank-posts
aos/claude/gh1036-harness-thread-name
fix/thread-names
feat/trajectory-completes
fix/prompt-budgets
aos/claude/docs-cut-2
aos/claude/ka54-thread-ownership
aos/claude/admission-bound
aos/claude/gh1025-roster-reexport
aos/claude/docs-strip-archaeology
feat/temporal-mcp
aos/claude/dowel-board-moxn-write-boundaries
aos/claude/ue65-moxn-write-framing
aos/claude/progress-backoff
aos/claude/bound-scratch-search-2
aos/claude/unblock-main
aos/claude/tool-breaker
fix/roster-core-eager
aos/claude/finish-dowel-rename
fix/971-skill-contract
aos/claude/model-answered-not-unavailable
aos/claude/mcp-singular-command
task/moxn-and-temporal-skills
aos/claude/ue65-temporal-brand
task/dowel-site-work-tier
aos/claude/ue65-roster-drift
fix/dropped-turn-always-speaks
aos/claude/folded-ask-coverage
aos/claude/dowel-board
aos/claude/dowel-pronouns
feat/trajectory-keyed-on-the-message
aos/claude/coalesce-discord-lane
task/derive-shipped-profiles
fix/ship-the-dowel-skill-root
aos/claude/eval-context
fix/bundle-references-reachable
aos/claude/eval-docs-one-page
aos/claude/dowel-engineer-suite
fix/catalogue-clone-cache
feat/engineer-role-graph
task/free-the-config-numbers
aos/claude/dowel-site-work
aos/claude/dowel-prose
aos/claude/mx76-derive-knobs
issue-859-on-demand-skill-reads
issue-651-ship-well-formed-replies
issue-852-filing-validity
issue-916-calculator-tool
issue-854-feature-flag-table
issue-866-role-mention-summons
issue-858-grounding-bound-per-server
issue-899-progress-keeps-updating
issue-900-rollup-mirrors-worklog
issue-901-raise-progress-cadence
issue-904-thread-title-length
issue-905-http-reachability
issue-855-turn-clock
issue-895-silent-turn
issue-873-mcp-tool-span-error
issue-878-settle-dropped-jobs
aos/claude/aw85-se-bands
aos/claude/hs68-model-rejected
aos/claude/hs68-effect-telemetry
aos/claude/hs68-temporal-mirror
aos/claude/hs68-prompt-commands
aos/claude/hs68-model-idle-timeout
aos/claude/hs68-prompt-command-intent
aos/claude/hs68-consult-label-name
aos/claude/hs68-grant-denial-403
aos/claude/hs68-queued-jobs-dropped
aos/claude/hs68-knob-guard
aos/claude/bk79-agent-folders
aos/claude/bk79-own-instructions
aos/claude/ym96-docs-band
aos/claude/bk79-server-instructions
aos/claude/aw85-mcp-beaver-doc
aos/claude/bk79-session-workspace
aos/claude/yt58-org-relationship
aos/claude/bk79-numeric-config
aos/claude/xu59-just-boundaries
aos/claude/xu59-eval-board
aos/claude/bk79-phrase-telemetry
aos/claude/bk79-object-emoji
aos/claude/xh55-otlp-logs
aos/claude/aw85-thread-prefill
aos/claude/wy58-thread-prefill-always
aos/claude/wy58-thread-prefill
aos/claude/xh55-move-to-repo
aos/claude/wy58-thread-title-length
aos/claude/xh55-filing-trigger
aos/claude/yt58-worklog-embed
aos/claude/aw85-relative-brevity
aos/claude/xh55-reasoning-roundtrip
aos/claude/yt58-clock-rotation
aos/claude/yt58-unbreak-main
aos/claude/bk79-test-build-break
aos/claude/yt58-partial-refusal
aos/claude/aw85-turn-failure-classify
aos/claude/aw85-outbound-spill
aos/claude/xh55-budget-spent-cause
aos/claude/wy58-bundles-not-content
aos/claude/wy58-refusal-reason
aos/claude/yt58-role-snapshot-gate
aos/claude/xh55-docker-probe
aos/claude/bk79-grounding-tools
aos/claude/az59-gate-span
aos/claude/az59-pg-jobstore
eng/roster-request-headers
eng/roster-headers
eng/list-the-mcps
aos/claude/mg96-fm
eng/name-echos-seat
eng/unpin-the-card-wording
olaf/remove-irl-physical
aos/claude/mg96
eng/echo-composes-ops
quail/two-rows-not-four
fix/two-failures-two-verdicts
feat/an-emitted-message-is-not-emitted-twice
quail/partial-coverage-outcome
feat/ten-minutes-or-ten-messages
feat/a-waiting-turn-says-how-long
feat/a-job-may-emit-content
quail/round-fanout-unbounded
quail/adversarial-reply-ceiling
docs/list-the-open-pull-requests
quail/principal-id-stays-out-of-the-prompt
fix/every-label-in-a-wildcard-prefix-is-a-label
docs/the-battery-assumes-two-checks-it-does-not-run
fix/a-rest-failure-keeps-its-status
quail/retag-label-rows
quail/adjacency-guard-row
test/pin-names-the-issue-that-owns-it
test/pin-points-at-a-live-issue
quail/job-outcome-discarded
fix/repair-exhaustion-is-not-an-outage
quail/reasoning-omitempty-pin
docs/label-id-silently-drops
quail/gating-pack-markup-gap
fix/instance-name-reads-identity
docs/indistinguishable-542-resolution
fix/instance-name-not-a-live-service
quail/unwired-capability-guard
fix/repair-path-reasoning-content
quail/indistinguishable-values-recurrence
quail/identity-short-form-rows
quail/repair-path-reasoning-content
docs/verify-a-write-landed-claude
quail/host-label-shape-corpus
docs/a-deploy-owned-file-has-two-shapes-claude
fix/a-roster-path-must-name-servers-claude
fix/every-label-before-the-suffix-claude
fix/a-first-label-must-exist-claude
feat/tune-the-timeouts-from-deployment-claude
qa/protocol-limits-are-not-dials
feat/a-wildcard-is-not-a-suffix-claude
feat/retry-what-fails-fast-claude
fix/name-the-deliberate-hold-claude
test/the-access-check-exit-codes-claude
build/ship-the-access-check-claude
qa/callers-not-reachability
qa/pin-the-unwired-thread-binding
feat/an-offline-access-policy-gate-claude
test/the-notice-detaches-twice-claude
docs/say-what-the-job-thread-does-claude
fix/a-notice-does-not-thread-claude
fix/one-invocation-is-a-phrase-claude
fix/a-moment-ago-is-this-turn
fix/main-is-red-on-the-adverb-row
fix/an-adverb-does-not-break-the-auxiliary
qa/score-the-575-fix
feat/a-reply-names-its-subject
eng/a-turn-is-not-the-past
fix/since-you-asked-is-this-turn
docs/a-default-that-reads-as-an-answer
fix/a-nameless-tool-is-not-the-server
qa/pin-the-outage-state
fix/a-session-lifetime-is-not-a-latency
fix/an-undated-passive-is-still-a-claim
fix/main-is-red-on-the-corpus
fix/an-undated-passive-is-a-claim
eng/a-session-is-not-a-request
fix/a-self-claim-in-the-simple-past
qa/extend-grounding-corpus
fix/a-tool-never-offered-is-not-a-tool-declined
eng/one-doc-for-the-tracker-surface
eng/say-what-is-switched-on
fix/evaluation-is-not-the-production-service
qa/pin-the-listing-attribute
eng/split-five-docs-off-the-cap
eng/concurrent-means-goroutines
eng/split-the-tracker-surface
test/the-first-label-of-a-hostname
fix/a-cache-hit-is-not-a-round-trip
qa/pin-the-budget-ladder
fix/the-first-label-of-a-hostname
eng/the-scratchpad-assumes-one-replica
fix/a-person-is-named-in-prose
docs/jobs-are-single-process
qa/enumerate-the-mention-positions
eng/split-the-response-inventory
fix/green-main-doc-cap-and-stale-characterizations
eng/main-is-green-again
eng/split-the-mention-scope
fix/mentions-doc-over-cap
qa/unredden-the-code-span-pin
qa/pin-the-code-span-collision
eng/code-spans-are-not-prose
feat/a-thread-title-says-what-it-is-for
fix/discord-markup-is-not-prose-either
eng/mark-the-turn-once
fix/a-name-in-a-url-is-not-a-person
qa/pin-every-reaction-is-emitted
eng/mentions-skip-link-spans
fix/one-step-owns-every-service-suffix
qa/pin-the-mention-url-collision
docs/the-roster-is-member-influenced
docs/what-a-mention-can-reach
qa/pin-the-documented-glyphs
feat/naming-someone-reaches-them
qa/pin-the-sandbox-label-wiring
qa/pin-the-truncated-receipt
feat/the-harness-labels-what-it-files
qa/compare-a-case-by-marshalling
fix/one-spelling-for-the-status-vocabulary
qa/declare-pack-divergence
fix/the-reactions-match-the-approved-vocabulary
fix/a-file-path-is-just-a-file-path
qa/pin-the-mapped-tailnet-form
fix/a-truncated-page-says-so
fix/the-extraction-case-detects-a-dump
docs/the-consult-label-tracks-the-thread
feat/the-eval-can-forge-a-turn
fix/refuse-the-tailnet-range
qa/pin-the-fail-heading-count
feat/a-bounded-fetch-tool
fix/preserve-the-longform-probe-pack
qa/pin-the-lane-gate
qa/preserve-the-longform-pack
fix/the-prompt-is-not-a-secret
fix/a-reference-never-loses-to-the-footer
qa/preserve-the-probe-packs
feat/a-trusted-caller-on-the-tailnet
fix/capability-tells-the-truth-about-the-scratchpad
qa/echo-battery-negative-control
fix/one-fail-block-not-two
feat/tool-call-footer
fix/guard-the-extraction-case
feat/canonical-phrases-by-key
fix/the-progress-line-is-a-reply-too
qa/pin-the-agent-recognition-case
qa/pin-the-tool-name-markup-guards
feat/five-second-buffer
fix/a-failing-case-shows-the-reply
fix/extraction-case-stops-penalising-compliance
fix/a-security-case-that-penalises-compliance
feat/deny-actually-denies
feat/job-refusals-reach-telemetry
fix/land-the-harness-refresh-on-main
feat/a-long-reply-gets-a-thread
feat/the-thinking-line-shows-it-is-working
feat/roster-hour-ttl-and-refresh
refactor/every-number-in-one-file
feat/agent-can-refresh-its-roster
fix/size-refusal-is-not-a-parse-error
fix/budget-base-above-the-reasoning-floor
fix/one-number-for-the-progress-cadence
fix/gate-sees-a-new-file
fix/one-meaning-for-channel-id
fix/look-up-verbs-cannot-match
feat/recognise-a-trace-lookup-request
feat/discord-identifiers-on-the-turn-span
fix/budget-failure-names-the-reasoning-spend
feat/notice-carries-the-trace-id
qa/cut-run-stops-calling
docs/merge-lane-closing-reference
eng/gate-knows-the-lane
eng/feature-inventory-catchup
fix/rate-dataset-survives-a-cut-run
test/consolidate-pack-coverage
pr-lane-318
fix/flip-unknown-field-rows
test/turn-unknown-fields
fix/rate-doc-over-cap
test/language-scope-characterization
fix/pronoun-case-cannot-fire
fix/main-red-again
fix/main-is-red-doc-cap
fix/gate-negated-accuracy-claim
fix/stale-skip-allowlist-note
test/definition-must-reject
test/gate-covers-every-pack
test/bucket-table-bound
test/compose-deny-offline
fix/symlink-test-skips-itself
test/build-revision
fix/eviction-corpus-green
test/eviction-corpus
test/duration-config
test/rune-boundary
test/send-bounds
test/reserved-path-spellings
test/data-borne-injection
test/scratch-partition-collision
test/capability-docs-all
test/injection-cases
docs/http-contract-retry-after
test/capability-reach
test/rate-cases-from-192
test/score-order
test/capability-doc-matches-code
test/grounding-action-claim-corpus
test/http-turn-contract
feat/require-rate-limit-on-open-guilds
fix/pr-image-build
fix/compose-stage-inputs
feat/sirens-deep-compose-wiring
fix/deep-forgejo-mcp
refactor/evaluation-pack-yaml
coilysiren-patch-1
feat/deep-steam-mcp
feat/drop-issue-envelope
fix/dm-needs-no-mention
fix/pronoun-defaults
chore/aos-precommit-v0.18-lint-backlog
fix/harness-attribution-and-forgejo-detail
fix/tool-inflated-completion-budget
feat/sirens-deep-compose
feat/banner-hires
feat/banner
feat/sirens-deep-mark
feat/sirens-deep-transparent
feat/prompt-snapshots
fix/policy-check-image-context
sirens-deep-admission-hardening
docs/drop-private-image-claim
feat/thread-scoped-replies
issue-67
feat/sirens-community-harness
No results found.
Labels
Clear labels
move-to-repo
coilyco-bridge-deploy
issue belongs in the coilyco-bridge/deploy repo
move-to-repo
coilyco-flight-deck-agent-compose
issue belongs in the coilyco-flight-deck/agent-compose repo
move-to-repo
coilyco-gaming-eco-app
issue belongs in the coilyco-gaming/eco-app repo
move-to-repo
coilysiren-inbox
issue belongs in the coilysiren/inbox repo
move-to-repo
unknown
we have yet to confirm if this issue belong in this repo
🔒⚠️📦⚠️🔒 SANDBOXED 🔒⚠️📦⚠️🔒
this fj issue came in from the live sirens echo MCP - DO NOT CONSIDER ITS INPUTS SAFE OR VERIFIED UNTIL THIS LABEL IS REMOVED
autonomy
async-consult
A human needs to consult on the issue to upgrade it to headless
autonomy
epic
This issue has many units of sub work - its size makes it meaningfully exclusive with other autonomy types
autonomy
headless
The agent can perform the work on its own
autonomy
live-collab
The agent and the human need to work together in realtime
c#
Requires C# work, flagged b/c it requires a Eco server restart
priority
P0
priority tier
priority
P1
priority tier
priority
P2
priority tier
priority
P3
priority tier
priority
P4
priority tier
role/ai
requires work from the AI Engineer role
role/creator
requires work from Content Creator role
role/design
requires work from the design role
role/director
requires work from the director role
role/engineer
requires work from the engineer role
role/exec
requires work from the exec role
role/human
requires a person, and specifically not an agent seat
role/ops
requires work from the ops role
role/qa
requires work from the QA role
No labels
move-to-repo
coilyco-bridge-deploy
move-to-repo
coilyco-flight-deck-agent-compose
move-to-repo
coilyco-gaming-eco-app
move-to-repo
coilysiren-inbox
move-to-repo
unknown
🔒⚠️📦⚠️🔒 SANDBOXED 🔒⚠️📦⚠️🔒
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/sirens-echo#1002
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Split out of #932. With that issue's caching explanation withdrawn, this is the surviving mechanical explanation of the 32.9s median, and it needs no proxy change to investigate.
The arithmetic
Every number here is from #932's own measurements and none of them depended on the cache claim:
request_bytesclimbed 128,443 to 217,079 across rounds 0 through 5, plus three nested sub-turnscommunity.turnp50 - 32.9s on this lane against 8.7s on plainsirens-deepSo the prefix is not paid once per reply. It is paid about six times, and it grows as the round's history accumulates.
At 5.9 calls averaging even 5s of model time, the median is accounted for without any cache behaviour entering the explanation. That is the thing to confirm or refute.
What to establish first
Where the 32.9s actually goes. Break one median turn into its parts: time in model calls, time in tool calls, time in the harness between them. #932 reports
model.chatp95 at 33.2s on this lane against 13.5s onsirens-deep, which suggests the individual calls are slow rather than merely numerous, but the per-turn split has not been measured.That single breakdown decides which lever matters:
Getting that wrong is what this issue exists to prevent. #932 spent its analysis on a cache regression that turned out to be a reporting artifact, so the discipline here is to measure the split before proposing anything.
Constraints that already apply
Kai rejected cutting the roster from 86 tools, in her words "no, we fix the servers", recorded on #932. Proposal 2 there is closed by decision. Do not re-propose a narrower roster as a latency fix. Bluesky was separately deprovisioned, taking both Sirens harnesses from 12 MCP servers to 11, so the current tool count should be re-measured rather than assumed to still be 86.
The freeze. Under the #929 amendment, work that changes only how well the lane does what it already does is not frozen. A change that moves capability is.
Related
coilyco-flight-deck/agent-proxy#138- the measurement gap that made the cache lever unreadable, fixed in50af3de. Once that rolls out, the cache hit rate becomes a real number and can be ruled in or out properly rather than by inferencecoilyco-flight-deck/mcp-beaver#80- the dead-server session recovery that keeps the roster paying for tools that are not answeringThe split this issue asked for, measured
Ran while debugging sirens-dowel time-to-first-reply. This is the "break one median turn into model time, tool time, harness time" task, not a proposal. Window is 24h to 2026-08-19T15:00Z, which is a later and busier window than #932's, on a lane redeployed ten times that day.
The answer is bimodal, and that is the finding. The three-way question in this issue assumes one answer, and the lane has two populations that resolve it differently.
Ordinary turns - the harness wins, and it is the settle.
Slow turns - the calls win, near-totally.
So against this issue's three branches: on a median turn the time is between the calls, and it is one named span rather than diffuse overhead. On a slow turn it is in the calls, and tool time is noise at under 1% either way. Tool calls are not the lever in any population measured.
Two premises here need correcting
The median turn makes 2 model calls, not 5.9. Over 120 turns there were 446
model.chatspans, a mean of 3.7, but every median-range turn sampled made exactly 2. The mean is dragged by a tail making 9, 10, and in one case 36. So "the prefix is paid about six times" is true of the mean and false of the median, and a lever sized against six would be sized against a distribution that has no mass there.The tool count is 63, not 86. One
model.requeston round 6 loggedtool_count: 63alongsiderequest_bytes: 237083andmessage_count: 21. That answers the re-measurement this issue asked for. It also puts the request at 237 KB by round 6, against the 217 KB #932 saw at round 5.The mechanism inside a slow turn
Per-call durations within one turn, in order:
22.1s, 27.8s, 20.1s, 10.5s, 6.6s, 32.2s, 46.2s, 66.2s, 66.7sthen failure on "Agent Proxy response exceeded the size limit"and another:
22.5s, 10.6s, 3.5s, 13.0s, 29.1s, 55.1s, 55.9s, 3.2s, 61.3s, 44.2sthen the same failureThe calls are not uniformly slow. They accelerate downward as rounds accumulate, roughly tripling from early rounds to late ones. So "slow calls" and "many calls" are not competing explanations here, they are the same explanation: round N is slow because rounds 1 to N-1 happened. That is consistent with prefix-plus-history growth and does not require the cache question to be settled first, though it does not rule the cache in or out either.
Three of seven turns in the 11:25 to 11:55 run ended this way against the 5m
SIRENS_ECHO_REQUEST_TIMEOUT.What I did not establish
gen_ai.usage.cache_read_input_tokensis now populated onupstream.chat_stream, socoilyco-bridge/deploy#699's rollout question is untouched by this.request_bytesis bytes, and the growth curve above is inferred from durations rather than from measured prompt tokens per round.POST /v1/chat/completions http sendspans from agent-proxy, one per streamed chunk, andmodelIOCapturebuffers each request and response whole. Whether that costs wall-clock is inference from config, not something I measured, and isolating it needs agent-proxy internal timings. Flagging it because it is a large number sitting next to a latency investigation, not because I am claiming it matters.sirens-echoorsirens-deep, so lane-specific and harness-wide causes are not separated.Where the harness half of this went
The settle share on median turns is being addressed from the deployment side at
coilyco-bridge/deploy#740, which setsSIRENS_ECHO_PROGRESS_AFTERto 5s and halves the hold ceiling to 10s. That is a knob change and not a fix to this issue: the hold still exists, and whether holding a finished answer to protect a line that gets deleted is the right trade is open at #1078 and in the turn-stages prose.The call-side half is untouched and is where the minutes are. Nothing above proposes a lever for it, per this issue's own discipline.
The instrument this issue would use to answer its own question is saturated and cannot represent the values it needs to measure. Found while running the #976 coalescing test on
sirens-dowel. QA observed only, no live action taken.The histogram tops out at 10 seconds
sirens_echo.coalesce.turn.durationreports p50 and p99 that look calm and are not:Those numbers are bucket boundaries, not measurements. The gauge sibling over the same test window reads
coalesce.turn.duration.max= 76,021 ms, andturn.duration.maxover 24h reads dowel 341,617 ms and echo 303,085 ms.So real turns run tens of seconds to minutes, every one of them lands in the overflow bucket, and the percentile estimate clamps at the top boundary. Any percentile read off this histogram is a floor, not a value. A reader taking p99 at face value concludes the lane answers in 10 seconds when the observed maximum is 34 times that.
This matters here specifically. This issue exists to find where a 32.9s turn goes, and a histogram whose top bucket is 10s cannot see a 32.9s turn at all, let alone decompose it.
Directly measured turn durations, Discord surface
From spans during the same window, lane
sirens-dowel:community.turnA - 117.61s - tracec5a1a3f777f44525d94364fb6608465bcommunity.turnB - 33.56s - traceb0ba3e30e781b60622bf47e7a1790fd2Turn B at 33.56s sits almost exactly on the 32.9s this issue is named for, and it came from an ordinary Discord message rather than a load test.
Where the time went on the third message
Recorded in full at #1010, summarised here because it bears on this issue's question. Message three arrived at 15:30:18.236 and its turn started at 15:32:10.548, 112.3 seconds later, 0.5s after the preceding turn released the per-tenant lock. Arrival to reply assembled was about 147 seconds, of which roughly 112 was waiting and 34 was working.
That is the same answer #1010 reached over HTTP, now confirmed on the gateway path: under any concurrency at all, the dominant term is queue wait rather than turn work. Three messages from one member were enough to produce it.
What I did not measure
I did not observe prompt bytes, model call counts, or cache behaviour in these turns, so this says nothing about the 116 KB prefix or the six-times figure in the title. The 117.61s turn is unexplained by anything I looked at and is worth pulling apart on its own.
Suggested order
Fixing the histogram bounds is cheap and it gates everything else here. Until the buckets cover the real range, every latency percentile on this lane reads as fine, and this issue cannot be closed with evidence because its central measurement is unrepresentable. Related but distinct from the temporality mislabel on the cumulative metrics recorded in #976.
Closing as delivered with the August 19 demo readiness epic (#981).
The finding here is a harness property, not a demo property: a 116 KB prefix paid roughly six times per reply inside a 32.9s turn. Preserved in #1094 so it can be re-ranked against the next forcing event on its own merits.
Decision recorded in coilysiren/inbox#391.