fix: agent-read resilience -- ARG_MAX, error context, retry, fragments #81
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!81
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/agent-read-resilience"
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?
A single reading tick can blow up four different ways and end the
whole tick. Each path now either survives the failure or gives a
useful error.
ARG_MAX: the real fire.
agent-read.sh passed the truncated HTML (up to 200KB) to jq as
--arg u "$USER_MESSAGE". The full payload landed on theprocess's argv, hit the kernel's ARG_MAX, and exec'd jq with
"Argument list too long". The tick died there.
Fix: build the request payload via
--rawfileagainst a tempfile. jq reads the file content as a literal string and embeds
it correctly in the JSON. No argv pressure. Verified with a
200KB synthetic payload -- jq reports the full content length
preserved.
Vague error context.
The old "API call failed for X" swallowed the curl exit code
and HTTP status under
2>/dev/null. Could be anything: ratelimit, auth failure, DNS, 5xx, the ARG_MAX above.
Fix: split curl exit (network/transport) from HTTP status
(application). Drop
-f, use-w '%{http_code}' -o file, andread the error body via jq. Errors now say "curl failed (exit
22): " or "API returned HTTP 529 -- Overloaded".
No retry across URLs/sources.
discretionary-read.sh picked ONE URL via try_source -> shuf -n 1
and bailed on first agent-read failure, even when the source's
homepage had 20 other fresh URLs sitting right there.
Fix: factored try_source into list_source_candidates (returns
ALL fresh URLs from a source). Restructured the main loop into
an attempt-bounded retry. Up to MAX_ATTEMPTS=3 agent-read calls
per tick. Failed URLs drop from the in-memory pool for this
run only -- still re-tryable on future ticks since the failure
was probably transient. When the current source's candidates
are exhausted, sample a new source.
URL fragments leaking through.
joshtronic.com linked to https://www.11ty.dev/#why-should-you-
use-eleventy. The fragment made it look distinct from the
11ty.dev homepage and the picker happily handed agent-read a
200KB marketing page -- which triggered #1.
Fix: extract_links strips
#...fragments and drops bare-domain URLs (https://example.com, https://example.com/) since
those are usually the source's own homepage or a footer link
to an aggregator, not a content page.
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com
A single reading tick can blow up four different ways and end the whole tick. Each path now either survives the failure or gives a useful error. 1. ARG_MAX: the real fire. agent-read.sh passed the truncated HTML (up to 200KB) to jq as `--arg u "$USER_MESSAGE"`. The full payload landed on the process's argv, hit the kernel's ARG_MAX, and exec'd jq with "Argument list too long". The tick died there. Fix: build the request payload via `--rawfile` against a temp file. jq reads the file content as a literal string and embeds it correctly in the JSON. No argv pressure. Verified with a 200KB synthetic payload -- jq reports the full content length preserved. 2. Vague error context. The old "API call failed for X" swallowed the curl exit code and HTTP status under `2>/dev/null`. Could be anything: rate limit, auth failure, DNS, 5xx, the ARG_MAX above. Fix: split curl exit (network/transport) from HTTP status (application). Drop `-f`, use `-w '%{http_code}' -o file`, and read the error body via jq. Errors now say "curl failed (exit 22): <stderr line>" or "API returned HTTP 529 -- Overloaded". 3. No retry across URLs/sources. discretionary-read.sh picked ONE URL via try_source -> shuf -n 1 and bailed on first agent-read failure, even when the source's homepage had 20 other fresh URLs sitting right there. Fix: factored try_source into list_source_candidates (returns ALL fresh URLs from a source). Restructured the main loop into an attempt-bounded retry. Up to MAX_ATTEMPTS=3 agent-read calls per tick. Failed URLs drop from the in-memory pool for this run only -- still re-tryable on future ticks since the failure was probably transient. When the current source's candidates are exhausted, sample a new source. 4. URL fragments leaking through. joshtronic.com linked to https://www.11ty.dev/#why-should-you- use-eleventy. The fragment made it look distinct from the 11ty.dev homepage and the picker happily handed agent-read a 200KB marketing page -- which triggered #1. Fix: extract_links strips `#...` fragments and drops bare- domain URLs (https://example.com, https://example.com/) since those are usually the source's own homepage or a footer link to an aggregator, not a content page. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>