Repository navigation
Operations runbook follow-ups: mask secrets, probe like the nightly, host-wide vs article-specific errors - #78
Merged
Merged
Conversation
…be like the nightly Step 1 masks TOKEN/KEY/SECRET/PASSWORD values from launchctl's environment block. Step 5's token check runs in a subshell, and the launchd probe runs like the nightly's plist (Background, a /bin/bash parent kept alive) and reads runs and the last exit code before bootout. Step 7 says a run registers either way and names the real confirmation. The outcome table splits extract_failed/fetch_failed into host-wide (every article) and article-specific rows, and gains a Full Disk Access row. site/moderate.py line citations, shifted by #52 and #63, become function names. The fresh-checkout note lists what a clone must recreate. site/ops/README.md links the runbook.
…ide only on every article review_runs drops dry runs. extract_failed and fetch_failed point at the host only when every article in the run shows them, matching site/moderate.py's ARTICLE_SPECIFIC_ERROR_RE; otherwise they print as article-specific. Operation not permitted / exit 126 maps to a new Full Disk Access cause. While no wp-update run took more than 100 articles, the report says to read the clear rate as a lower bound. Tests cover each, and the dry-run and host-wide ones fail with the change removed.
Deicyde
force-pushed
the
claude/ops-runbook-followups
branch
from
October 17, 2026 23:36
064cf17 to
dda1da4
Compare
Owner
Author
|
Recommendation: merge (at
Left for a follow-up: the stale Posted by the WikiLean PR swarm (lead); updated 2026-10-18. |
…are rows; fresh-checkout facts The probe's -c script ends in 'exit $?' instead of an echo, so bash still runs the CLI as a child (as for the nightly) and launchd's last exit code is the CLI's, which makes the 126 sentence true. Step 7's token form runs in step 5's subshell. The checklist says to type bash first: interactive zsh does not treat # as a comment. Outcome rows: extract_failed and fetch_failed are host-wide when every article that reached that stage shows them; the article-specific row covers cached HTML and PR #52 scoping; the FDA row lists 'exit code 126' and the older wrapper's limit. The lower-bound note is described for a full old page. Fresh checkout: the wrapper's preflight is what needs wiki/.dev.vars, the job's two KV pushes run npx wrangler, and pending checkpoints must be flushed or copied.
…e note only for a full old page A fetch failure is compared with the articles that got past the Worker read, and an extract failure with those that also got past the fetch, so a host-wide outage no longer prints as article-specific when other articles failed earlier. The lower-bound note fires only when the largest wp-update run took exactly 100 articles: a smaller run took the whole drifted set. 'Command failed with exit code 126' is a tested Full Disk Access case. Both logic fixes fail their tests when reverted.
This was referenced Oct 19, 2026
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.
Problem
Gaps in the operations runbook (#56) and its summary script. #52 and #63 made several worse by shifting the code they cite.
sed -n '/environment = {/,/}/p'prints every launchd environment value unmasked, including anyCLAUDE_CODE_OAUTH_TOKEN.nightly.local.envinto the interactive Terminal, so the token stays in the environment of every later command there, including any agent session started from it.site/ops/launchd-plist.template) setsProcessType Backgroundand runs/bin/bashas the parent. The probe ran the CLI directly, orexec'd bash away, and never readrunsor the last exit code beforebootout.extract_failedandfetch_failedalways map to a host cause, in the outcome table and inmanage/nightly_health.py. Surface review failures without host access #52'sARTICLE_SPECIFIC_ERROR_REtreats them as article-specific, so one failing article reads as a broken host.site/ops/README.mddocuments the TCC failure (Operation not permitted, exit 126).site/moderate.pyare stale after Surface review failures without host access #52 and wiki: serve wp-update the whole drifted set (cap 1000) instead of attempt stamps #63.review_runscounts dry runs, which write nothing.site/cachehistory stays behind.site/ops/README.mddoesn't link the runbook.Change
docs/OPERATIONS.md:bashfirst, because Terminal's default interactive zsh doesn't treat#as a comment.Background, with/bin/bashas its responsible process. Its-cscript ends inexit $?, so bash runs the CLI as a child (as for the nightly) and launchd's last exit code is the CLI's. That holds for the token variant too. The probe printsrunsand the last exit code beforebootout, and the text says whatruns = 0and 126 mean.launchctl kickstart -k(or waiting for 03:20), then a review run with nonzero tokens on/stats.extract_failed/fetch_failedrows apply when every article that reached that stage shows them. A new article-specific row covers the rest, including the cached-HTML case, and it is scoped to PR Surface review failures without host access #52. A new Full Disk Access row listsexit code 126and the older wrapper's limits.site/moderate.pycitations name functions (_import_ba,_write_article,run_jobs,_AbortingSem). A pre-Surface review failures without host access #52batch_annotate.pyline citation is dropped.wiki/.dev.vars(the wrapper's preflight stops without it), a Python 3.12+ venv at.venvorcatalog/.venv,npm ciinwiki/(the job's two KV pushes runnpx wrangler), flushing or copyingsite/cache/.pending_posts/, and thesite/cachehistory that stays behind.manage/nightly_health.py:extract_failed/fetch_failedas article-specific unless every article that reached that stage shows them (a fetch failure counts only articles past the Worker read, and an extract failure only those also past the fetch);site/ops/README.mdlinks the runbook from its Operate section.How tested
manage/test_nightly_health.py: 21 passed, including 5 new tests: dry runs, host-wide vs article-specific, the per-stage denominators, Full Disk Access, and the sample note on and off. The dry-run, per-stage and sample-note tests each fail with their change reverted./bin/bash3.2, the old-cscript (ending inecho) exits 0 when the CLI fails with 126, and the new one (ending inexit $?) exits 126.launchctl printblock, the step 1 maskingsedmasksCLAUDE_CODE_OAUTH_TOKEN,WIKILEAN_API_TOKEN,AWS_SECRET_ACCESS_KEYandDB_PASSWORD, and leavesPATHandHOMEalone.site/ops/brain_release_authority.py.Risks
What Jack must do
site/moderate.py'srun_jobsdocstring still says exit 3 means "aborted (window/budget)", though since Surface review failures without host access #52 it also means an auth or credit abort. That file is release-affecting, so the fix waits for a PR that rides a release.site/cache/cron/moderate-*.logfiles off the host (the wrapper keeps 30) is a host action.