docs(admin): fix the 3× stale-age rules — wrong threshold, wrong timeline - #8
Merged
Conversation
…line Review caught the lifecycle table putting pending-repeater resolution in a row it can't belong to. Two errors, both from treating the two 3x routines as one rule. Threshold: the approve/delete branch tests last_heard against 1x the stale age, not 3x (repeaters_cleanup.php:249). The 3x check is on created_at and only decides WHEN a pending record is judged; 1x decides which way it goes. The docs collapsed both into "3x". Timeline: the table's premise is "a repeater that stops adverting at day 0", under which a pending repeater can only ever be deleted — approval requires being heard within the last 24h. So the row offered a branch with one unreachable side. Pending runs on the record's creation date, not on silence, so it now sits in its own section outside that table. Also corrects the duplicate row, which implied silence alone makes a repeater "eligible for deletion". It doesn't — the delete only fires when another repeater still shares the ID prefix; a unique ID is untouched. And documents the survivor repair that was missing entirely: the surviving repeater is restored from Excluded to Active with the clean ID, so a collision blocking a legitimate repeater resolves itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KojjSrgSQQJW7Z8b3eakEA
…mers Review caught the Repeater Inactive After example claiming a repeater "only heard when someone drives past every few weeks" stays on the map longer with a raised timer. Wardriving has no such effect. repeaters.last_heard has exactly one writer: api.php:1152, the MQTT ingestion path, from repeater adverts. wardrive-api.php never touches it — its only writes to the repeaters table are multibyte_capable flags (:2493, :2510), which touch neither last_heard nor enabled. So a wardriver hearing a repeater records and associates the pings but leaves the lifecycle clock untouched: it still goes stale, still goes Inactive, still gets purged on the schedule it was already on. Return-to-Active is advert-only too, via the enabled CASE in the same UPSERT. The old example had it backwards on the one axis an admin would act on, and would have sent someone raising a timer when their actual problem is observer coverage. Adds an explicit definition of "heard" up front, fixes the example, and flags the failure mode the distinction creates: a repeater transmitting fine but out of observer range ages out regardless, and enabling auto-delete in a region with patchy observer coverage will permanently delete live repeaters. Ghost Retention is unaffected — ghosts genuinely are wardrive-discovery driven, on a separate table. Noted as the exception. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KojjSrgSQQJW7Z8b3eakEA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #7. This correction was pushed to that branch a few minutes after it was merged, so it missed the merge and the incorrect text is currently live on the site.
What's wrong on main right now
Three problems, all from treating the two 3× routines as one rule.
1. Wrong threshold. The approve/delete branch tests
last_heardagainst 1× the stale age, not 3× (repeaters_cleanup.php:249):3× (on
created_at) decides when a pending record is judged; 1× (onlast_heard) decides which way. The docs collapsed both into "3×".2. Wrong timeline. That table's premise is "a repeater that stops adverting at day 0." Under that premise a pending repeater can only ever be deleted — approval requires having been heard within the last 24h. So the row offered a branch with one unreachable side, which is what made it read as nonsense. Pending resolution keys off the record's creation date, not off silence, so it now lives in its own section outside that table.
3. Overstated the duplicate rule. "Becomes eligible for automatic deletion" implies silence alone is enough. It isn't — the delete only fires when another repeater still shares the ID prefix. A silent repeater with a unique ID is untouched and just continues toward Inactive.
Also adds
The survivor repair, which was missing from the docs entirely (
repeaters_cleanup.php:224-238): when the stale twin is deleted and exactly one other repeater shared that ID, the survivor is restored from Excluded to Active and given the clean ID back. Worth documenting, since it means some Excluded repeaters recover with no admin action.Cross-references in the Repeaters tab status list and the New Repeaters Enter Pending State setting updated to match.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KojjSrgSQQJW7Z8b3eakEA