Repository navigation
fix(bots): never blank a letter, and drop blank paper on the ground - #714
Merged
Merged
Conversation
Disposal put the blanked sheet into pocket slot 0 (containerNoid = the avatar). Paper.PUT does destroy a blank sheet wherever it lands, but a pocket is the wrong place for a bot to aim: anything that survives — a sheet whose blanking didn't take, say — stays in the pocket, and a bot that accumulates paper there runs out of free slots and can no longer pick anything up. Put it down on the ground instead (Randy's rule): the region recycles a blank sheet left on the floor. Paper.PUT defaults containerNoid to THE_REGION (Constants.java:272) and x/y/orientation to the avatar's own, so sending only containerNoid: 0 drops the sheet at the bot's feet. Both disposal paths go through this — drainMailSlot after reading a letter, and discardHeldPaper after delivering one — and habibots/lib/mail.js is shared with sage, so its mail path gets the same behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PP6PsCtYXunah4Y9vczMJb
The Oracle kept ending up with letters in its hands that it could neither read nor safely destroy. Diagnosed from elko's own trace on 2026-09-30: 17:05:01.998 clearing contents for Paper paper-i-2495581085713971936-… 17:05:02.500 PUT success for Paper text-emptypaper: true (that sheet destroyed) 17:05:03.006 Advanced Mail slot … to paper-i-2495581085713971936-… Letter bodies are SHARED. Paper.sendMailToUser reuses the sender's text_path for the queued record (Paper.java:657), and Avatar.advance_mail_slot points the next MAIL_SLOT sheet at that same path (Avatar.java:1990). Paper.WRITE's clear calls deletePaperContents(), which removes the body document outright — so blanking one sheet destroys content other sheets and queued records still reference. The newly handed-over letter is unreadable from birth; clearHands then cannot deliver it and correctly refuses to destroy an unread letter, so it sits in the hands forever and blocks every Paper.GET. Three sheets carried that one body in the trace above. So: never blank a letter. putDownHeldPaper puts the sheet on the ground exactly as it is — Paper.PUT only destroys when is_blank(), so the content survives for whoever else points at it, and the hands come free. Paper.GET's special_get has already spawned the replacement sheet in MAIL_SLOT, so nothing needs the old one. Blanking stays for sheets we wrote ourselves, whose bodies nothing else references. A human rarely blanks a letter they received, which is why this went unnoticed; the bot did it to every letter it read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PP6PsCtYXunah4Y9vczMJb
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.
Supersedes #702, which is included here as the first commit — the two changes touch the same lines and are the same subject: where paper goes when the Oracle is done with it.
1. Blank paper goes on the ground, not in a pocket (your rule)
Paper.PUTdefaultscontainerNoidtoTHE_REGION(Constants.java:272) and x/y/orientation to the avatar's own, so this drops the sheet at the bot's feet, where the region recycles it. A pocket would keep it, and a bot that accumulates paper runs out of slots.2. Never blank a letter — it deletes a body other sheets still point at
Elko's trace, 2026-09-30:
Letter bodies are shared:
Paper.sendMailToUserreuses the sender'stext_pathfor the queued record (Paper.java:657), andAvatar.advance_mail_slotpoints the next MAIL_SLOT sheet at that same path (Avatar.java:1990).Paper.WRITE's clear callsdeletePaperContents(), deleting the body document — so blanking one sheet destroys content other sheets and queued records reference. Three sheets carried that one body in the trace.The handed-over letter is then unreadable from birth.
clearHandscan't deliver it and correctly refuses to destroy an unread letter, so it stays in the hands — and a full hand blocks everyPaper.GET, killing mail in both directions. That is what left husks in the Oracle's hands in September and again on Sept 30.putDownHeldPaperputs a sheet down exactly as it is.Paper.PUTonly destroys whenis_blank(), so a letter survives intact and the hands come free.special_getalready spawned the replacement in MAIL_SLOT.drainMailSlot— after reading a letter: put down, no blankingoracle.js— after relaying a recovered letter: put down, no blankingdiscardHeldPaper— unchanged, now documented as our own drafts only: we created those bodies, so blanking them is safeA human rarely blanks a letter they received, which is why this went unnoticed; the bot did it to every letter it read.
npm test— 58 pass, including new tests that a blanked sheet goes toTHE_REGIONwith no pocket slot, and that a letter read from the mail slot is not blanked.What this does not fix
Read letters now accumulate on the floor of
context-oraclehome, one per inbound mail, because the region only recycles blank paper. The real fix is server-side — don't delete a body another sheet or queued record still references, or copy the body on delivery rather than sharing it. That's elko, so it needs your sign-off.🤖 Generated with Claude Code
https://claude.ai/code/session_01PP6PsCtYXunah4Y9vczMJb