Ticks leak python3 -m http.server daemons; stale listeners can answer another tick's verification requests #418
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
Total time spent: 8 minutes 4 seconds
Due date
igor
8 minutes 4 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor#418
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?
Rescoped from the original logwatch filing (see history). The original framing — that the agent passed off a hand-rolled simulation as real verification — is not borne out; the passing observation about a stray listener is the actual defect.
What is actually wrong
Ticks that verify built static output start a local HTTP server and never reap it. Four orphans were live on the host as of 2026-07-24 22:12, all reparented to init (
ppid 1), all bound to0.0.0.0:/home/igor/Code/joshtronic.com/_site/home/igor/Code/joshtronic.com/_site/home/igor/Code/ageofcombat.com/dist/home/igor/Code/snail.io/distAll four were killed manually. Nothing in the harness would have reaped them.
This directly caused the misleading response the original filing noted in passing:
A leaked server from an earlier tick was squatting on the port and answered a request the running tick believed was its own. That tick caught it. A tick that does not catch it reports a verification result sourced from a stale build of a different site.
Severity
Exposure is limited: the host is on
192.168.4.26/22,igor.sherver.orgresolves to127.0.1.1on-box, and the served content is public build output. The cost is unbounded process accumulation and a verification signal that can silently come from the wrong server, not disclosure.What the original filing got wrong
The claim that the agent reported a simulation as real verification does not hold. idolidle.com#24 states plainly that nginx could not be started, calls the substitute a stand-in, and leaves the live-nginx checkbox unchecked:
That labeling is the behavior the original ticket asked for as its fix. No change needed there.
Fixed looks like
A tick does not stand up a web server to verify static routing at all. The deploy barrier (deploy-sha marker +
agent.json.smoke.url) is the smoke test for served behavior; in-tick verification should stop at the build output on disk. Doing this makes the sandbox's inconsistent gating ofnginxmoot — nothing gets spawned, so nothing leaks and nothing collides.If any tick-local listener survives that change, it must bind loopback only and be reaped on tick exit regardless of how the tick ends.
Tests
python3 -m http.serveror equivalent is spawned by the static-verification path.nginx binary gated in one worktree but runnable in another; agent substituted a hand-rolled simulation as verificationto Ticks leakpython3 -m http.serverdaemons; stale listeners can answer another tick's verification requestspython3 -m http.serverdaemons from ticks #422python3 -m http.serverdaemons from ticks #422