Survive the console this will actually be run from

The report prints an arrow between the old and new word counts, and it prints
the memories themselves, which are model-written prose. A Windows console
defaults to cp1252 and cannot encode either, so the run dies on
UnicodeEncodeError partway through — after some memories have been rewritten
and committed, which is the worst place to stop. STATUS already carries the
same warning for tools/dbmeter.py.

stdout is reconfigured to UTF-8 with errors="replace" instead, so the report
degrades a character at a time rather than failing.

The usage notes were also written for a POSIX shell, and this project is
developed in PowerShell, where `VAR=x command` is not a thing. Both docs now
give the PowerShell form first, via Read-Host so the Neon URL and the secret
stay out of the history file, and name the venv's Python.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tqgupw5CZGjSZrUTNUd4fW
This commit is contained in:
Claude
2026-08-31 14:44:16 +00:00
parent 4c94dd0fc0
commit eeab8ef5bb
2 changed files with 24 additions and 5 deletions
+18 -3
View File
@@ -68,10 +68,18 @@ ask to have rewritten. `--email` restricts the run to the accounts you name and
`--adventure` to single adventures; a dry run costs nothing and lists both, with `--adventure` to single adventures; a dry run costs nothing and lists both, with
the owner of each. Guests have no email and can only be reached by id. the owner of each. Guests have no email and can only be reached by id.
Two environment variables reach that database from a checkout: Two environment variables reach that database from a checkout. In PowerShell,
which is where this project is developed, they are set first and then persist
for the rest of the session:
AIDND_DATABASE_URL=<the Neon URL from the Render dashboard> \ $env:AIDND_DATABASE_URL = Read-Host 'Neon URL'
AIDND_SECRET_KEY=<the same value the web service has> \ $env:AIDND_SECRET_KEY = Read-Host 'Secret key'
.venv\Scripts\python.exe -m tools.rewrite_memories --email you@example.com
`Read-Host` keeps both values out of the PowerShell history file. On a POSIX
shell the same thing is one line:
AIDND_DATABASE_URL=... AIDND_SECRET_KEY=... \
python -m tools.rewrite_memories --email you@example.com python -m tools.rewrite_memories --email you@example.com
`AIDND_SECRET_KEY` is not optional there. Stored API keys are encrypted with it, `AIDND_SECRET_KEY` is not optional there. Stored API keys are encrypted with it,
@@ -308,5 +316,12 @@ if __name__ == "__main__":
parser.add_argument("--api-key", help="override the owner's API key.") parser.add_argument("--api-key", help="override the owner's API key.")
args = parser.parse_args() args = parser.parse_args()
# A Windows console defaults to cp1252, which cannot encode the arrow this
# prints, let alone whatever is in a story's prose. Ask for UTF-8 and
# replace what the terminal still cannot render, so a run never dies
# halfway through on an encoding error.
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
raise SystemExit(asyncio.run(main(args))) raise SystemExit(asyncio.run(main(args)))
+6 -2
View File
@@ -145,10 +145,14 @@ people's stories and each adventure is summarized with its owner's key, so `--em
a shell on Render — the image copies `backend/app` alone, so `tools/` is not on the box: a shell on Render — the image copies `backend/app` alone, so `tools/` is not on the box:
``` ```
AIDND_DATABASE_URL=<Neon URL, direct endpoint> AIDND_SECRET_KEY=<the web service's value> \ $env:AIDND_DATABASE_URL = Read-Host 'Neon URL' # direct endpoint, not -pooler
python -m tools.rewrite_memories --email you@example.com $env:AIDND_SECRET_KEY = Read-Host 'Secret key' # the web service's value
.venv/Scripts/python.exe -m tools.rewrite_memories --email you@example.com
``` ```
`Read-Host` keeps both out of the PowerShell history file. Use the venv's Python: the
system one on this machine is 3.10 and has none of the dependencies.
`AIDND_SECRET_KEY` is not optional there: stored API keys are encrypted with it, and `AIDND_SECRET_KEY` is not optional there: stored API keys are encrypted with it, and
with the wrong one `decrypt_secret` returns "" and every adventure is reported as having with the wrong one `decrypt_secret` returns "" and every adventure is reported as having
no key — a run that looks fine and does nothing. Hand-written memories, and memories whose actions have been deleted, are left no key — a run that looks fine and does nothing. Hand-written memories, and memories whose actions have been deleted, are left