Google Workspace helpers resolve Epoch OAuth credentials through
op-automations. Calendar uses gcalcli-epoch, which validates the canonical
grant and atomically refreshes gcalcli’s credential cache before each operation.
This prevents a separately expired Calendar grant from blocking automation.
This directory contains the tracked parts of my Claude Code setup. The shared Claude/Codex contract lives in the shared configuration guide; this file covers Claude-specific layout, activation, and settings.
claude/ ├── CLAUDE.md global instructions ├── bin/ service and maintenance commands ├── context/ reference material loaded when needed ├── hooks/ hook implementations ├── skills/ tracked public global skills ├── private-skills/ encrypted skills exposed through local shims └── README.org
The live ~/.claude/CLAUDE.md and ~/.claude/skills paths are symlinks to the
tracked instruction file and skill tree. By contrast,
~/.claude/settings.json is a mutable regular file: Claude rewrites it when
settings, permissions, hooks, or plugins change, so a symlink would be unsafe.
~/.claude/settings.local.json holds machine-local permissions and native
skill-disable state.
The shared live settings set disableClaudeAiConnectors to true. Claude Code
therefore does not load hosted claude.ai connectors or their tool schemas.
Service access uses the canonical local CLIs and scripts documented in
CLAUDE.md instead.
Per-project configuration belongs in <project>/.claude/. Repo-root
.claude/ directories are project-local and are never global symlink targets.
Account-specific homes selected with CLAUDE_CONFIG_DIR isolate authentication,
projects, history, plugins, and settings while continuing to use deliberately
shared tracked artifacts.
Four OAuth accounts use separate configuration homes:
~/.claude-personal/, ~/.claude-tlon/, ~/.claude-epoch/, and
~/.claude-trajectory/. Each keeps its own OAuth identity, Keychain credentials,
and .claude.json. Settings, skills, projects, history, and plugins are shared
through symlinks to ~/.claude/. The account homes do not contain a second
CLAUDE.md, because the user-level file is already loaded from ~/.claude/.
The selected account is stored in ~/.claude-current-account. Emacs reads that
selection through agent-claude-start-or-switch and changes it with
agent-claude-select-account; terminal aliases select the same four account
homes. Before launching a newly configured account, run
agent-claude-init-account so its shared paths are symlinks from the start.
Otherwise Claude may create divergent regular settings and history files on
first login. The initializer heals untouched files but leaves non-virgin files
for explicit migration.
The claude PATH shim removes ambient ANTHROPIC_API_KEY and
ANTHROPIC_AUTH_TOKEN because they take precedence over the selected OAuth
account. CLAUDE_CODE_ALLOW_API_KEY_AUTH=1 is reserved for a deliberate
API-key-authenticated Claude session.
claude/CLAUDE.md is the user-level instruction source. A project may add a
sibling CLAUDE.md and project-local settings. User and project settings are
additive. Account selection changes which user-level native state is active; it
does not introduce a third precedence layer. Effective behavior therefore
depends on both tracked instructions and the selected live state.
Operating rules in CLAUDE.md stay short and state the behavior directly. The
file is a lean always-loaded instruction source, not a manual: detail belongs in
skills and context files that load on demand. User-facing replies lead with the
answer and stay plain and brief: short sentences, no preamble, and nothing that
does not change what the user does or decides.
The global instructions state the repository-root contract shared with the
Codex side: every repository lives outside Drive under ~/repos/ (Epoch
repositories under ~/repos/epoch/), nothing under the Drive sync root may
hold dependencies, builds, caches, virtual environments, or worktrees, and
every linked worktree lives under ~/repos/.worktrees/<repo>/<name>. The
108 repositories that used to sit under ~/My Drive/repos/ were moved on
2026-08-03; regenerate-coverage-map.sh and the other hooks that name a
repository path were updated in the same change.
The live global settings register hooks by absolute path. Stop forwarding to
Emacs is a turn-end signal, not proof that the agent process exited. Reusable
lesson capture belongs to the Emacs agent-before-exit flow and must not be
silently reintroduced as a Stop hook. The permission mode is automatic: guards
return allow or deny and never prompt as an approval mechanism.
Auto mode routes every non-read tool call through Anthropic’s server-side
classifier, which reads only the user-level ~/.claude/settings.json (never
project or local settings) and drops broad Bash allow rules. Its false
positives are tuned with the autoMode block, whose source of truth is
claude/auto-mode.json (git-crypt encrypted; unlock the checkout before
using apply-auto-mode): environment entries describe the trust boundary
(single-user laptop, the user’s repositories as project scope, 1Password via the
brokers, the Epoch services the user administers, Emacs agent orchestration) and
allow entries name the built-in soft-deny rules that misfire on that work.
Both lists begin with "$defaults" so the built-in rules stay and keep
updating. claude/bin/apply-auto-mode copies the block into the live settings
with a backup, and --check reports drift; run it yourself, because the
classifier’s Self-Modification rule refuses to let a session widen its own
permissions. Add an entry only for a class of false positive that has actually
recurred, and phrase it as the action and why it is inside the boundary.
The secret guard inspects replacement text and notebook cell source as well as whole-file writes. Security-hook bootstrap and unexpected runtime failures block with exit code 2; the hook contracts describe the covered guards. The regression fixtures check malformed input, missing dependencies, missing startup helpers, and benign or secret-shaped replacement text without executing the proposed tools. These guards run with the agent’s OS user and filesystem access.
Claude-specific browser, OAuth, hosted connector, and account state stay in
Claude’s native stores. Shared MCP wiring is audited only when it is declared in
ai-config-sync.json; placement and account guidance lives in
the MCP reference.
Instruction files, skills, and hook reminders state current rules with their
reasons and without incident history, migration-relative wording, shouted
emphasis, or numeric output caps. The prompt audit recorded in
the 2026-09-02 prompt-audit plan lists the removed patterns and the items
left in place on purpose, including the deliberate model: aliases on the
GitGuardian, publication, and proofread skills.
The command index documents the tracked service clients, wrappers, and maintenance tools. It is the owner for command behavior; this overview does not duplicate a command-by-command catalog.
The ai-provider-key helper owns the autonomous spend ceilings for automation
runtime keys directly.
The context index routes account, service, browser, secret, and MCP procedures. Sensitive procedures should be loaded only when the task needs them. In particular, read the secrets context before handling credentials rather than copying credential paths or token recipes into this public overview.
The Claude skill index documents discovery, pairing, private and programmatic roots, and maintenance. The generated tracked skill inventory is the repository-wide catalog. It covers tracked public skills only; runtime plugins, private skills, ignored system content, and skills owned by other repositories are outside its scope.
The org-note-conventions skill applies only to personal notes. It distinguishes
root-backed and rootless heading layouts, preserves established structure, and
joins soft prose wrapping without removing intentional Org hard line breaks.
The overnight-todos skill requires an explicit personal-TODO run. Its default
dry run classifies metadata without reading note bodies or starting workers.
Act mode uses private outputs, token-based task accounting and an idempotent
ledger; only verified outcomes justify completion, and budget limits produce
deferrals. Existing ledger history requires explicit migration, not a reset.
The paste-via-kill-ring skill separates manual handoff from sending and is
one command: claude/bin/kill-ring-put reads the text from stdin or a file,
finds the running Emacs server socket, and verifies exact non-secret ring
placement without implicit clipboard forwarding, honoring text-transform
acceptance and never echoing the payload. The Lisp form and private temp-file
handling live in the helper, not the skill text. Credentials follow the secrets
workflow, not the persisted Emacs kill ring; clipboard placement (--clipboard)
is reported separately.
The personalize skill keeps private voice examples out of public artifacts
and separates voice matching from factual or personal claims. Missing samples
are explicit; concision preserves required answers, and prose preferences do
not alter quotations, code or links. Drafting does not authorize sending.
The pin-elisp-pr skill preserves one effective installation owner per active
profile, including explicit-owner/config-only timing exceptions. It reuses the
shared PR and profile lifecycle and distinguishes a configured recipe from an
installed revision and verified loaded behavior.
The post-push-ci skill observes an exact pushed target without pushing again.
Its helper reports a bounded run snapshot; expected-check coverage, run attempts
and pending or non-success outcomes remain explicit. Status checks alone do
not authorize repairs, reruns or publication. Attempt inspection validates
GitHub’s attempt-specific URL against the listed run and exact attempt.
The pr-audit skill binds the requested PR and tested artifact to frozen
base/head revisions. It separates commit selection from the net PR patch,
reviews merge parents explicitly, and keeps readiness evidence distinct from
permission to repair, rewrite history or publish.
The project-local config-audit respects a requested subset and includes
procedural bodies when full skill audits are requested. It distinguishes
skill discovery from instruction loading and checks actual hook coverage
before recommending removal of an overlapping instruction.
The project-local find-skills checks the selected agent and project/global
destination before installation. It preserves canonical paired roots and uses
copies for Drive-backed destinations, then resolves the installed skill to
verify discovery.
The project-local gitguardian-triage separates read-only classification from
authorized rotation and closure, verifies exact credential ownership and
consumers, and treats ambiguous provider responses as inconclusive. Its
bin/gitguardian-incidents reader rejects HTTP redirects so authenticated
requests cannot forward credentials to another endpoint.
The project-local install-mcp-server preserves documented endpoint paths and
uses explicit secret resolution: Claude expands environment references but
does not dereference op:// values. It distinguishes configured, authenticated,
and tool-tested states before reporting readiness.
The project-local optimize-agent-instructions distinguishes always-loaded
imports from references read on demand. It preserves useful instructions until
replacement enforcement and discovery have been checked for each target runtime.
The project-local skill-resolver honors exact session-catalog paths before
name lookup and keeps project edits in their original scope. Its filesystem
inventory is distinct from the runtime’s enabled skill catalog; account and
installed plugin-version evidence determine which sources it searches.
The project-local skill-audit remains explicit-invocation-only. Its historical
collector distinguishes failed reads from successful output envelopes, preserves
personal/plugin identities and exact name boundaries, and handles task-start
context, hidden inputs, and fractional timestamps. Counts remain reconstructed
evidence, not native invocation telemetry or proof of workflow completion.
The dx-audit skill distinguishes observed collaboration friction from imagined
or unmeasured gaps. Its bounded implementation mode accepts plain-language
requests, respects runtime-specific instruction discovery and checks command
effects before running diagnostics.
The dotfiles-context skill resolves canonical sources without guessing from
stale profile directories. It checks buffer and profile identity before tangling,
preserves runtime-specific pairing, and binds local PR pins to the exact reviewed
change while keeping generated files distinct from live activation.
The shared rebuild helper requires runtime-, source- and token-bound completion
evidence. It rejects unqualified cached success and keeps uncertain requests
recorded so cooperating callers cannot silently launch a competing rebuild.
If the original waiter exits, an observer can acquire its now-free package lock
and certify the same completion token after rechecking the recorded source,
runtime and status identity. It neither replaces an active owner nor requests
another rebuild when an existing completion token can be certified.
If the request reply was lost before its token was recorded, the helper checks
the live package under the exclusive owner lock. Only an idle package with no
queued tokens and unchanged source, runtime and status permits archiving that
abandoned request and starting a fresh bound rebuild. The abandoned request
never counts as completion evidence.
A pending status alongside a terminal previous owner can be a producer startup
gap: the observer waits for the new owner instead of resuming the old token. Active
requests still require the exact recorded source, runtime and status identity.
The end-to-end skill separates disposable test fixtures from retained results,
checks startup effects and runtime identity, and accepts automation that observes
the real criterion. Historical scheduler evidence and black-box service checks
are credited only for what they establish; retry cohorts cannot erase failures.
The elisp-conventions skill distinguishes registry IDs, checkout evidence
labels, unmanaged packages and non-package files. Batch and ERT runners use a
clean source-first Emacs without deleting bytecode or falling back to the
package’s build. Staged project checks validate a private indexed snapshot,
not unrelated working-tree bytes. A file rename does not authorize whole-package
unloading, and a metadata predicate does not prove a live menu works.
The documentation guard reads generated-output declarations from the proposed commit’s manual bytes, including explicit selections and inherited amendments. It handles independent Texinfo/Info names without evaluating Org. Unrelated unstaged headers cannot hide outputs; ambiguous pending staging is refused with a reason to stage the intended manual separately.
Automatic manual exports compare source identity and content, allowing metadata-only changes during export. Replaced sources, changed contents and symlinks remain rejected; generated destinations retain strict state checks.
Elisp helpers under standard skill roots’ scripts/ directories, including
project-local .claude/skills/ and .codex/skills/, require their own changed
SKILL.md or references/*.md in the selected commit.
An unrelated package manual or another skill’s documentation cannot satisfy that
requirement. Mixed package changes still need their manual; unresolved combined
staging of skill helpers must be split into separate staging and commit calls.
Candidate indexes preserve Git’s original index timestamp so rapid same-size
source edits remain visible to --all and --include checks.
The document-elisp-package skill preserves established manual paths, credits,
anchors and export identities. It separates documentation from new save automation
and documents supported public contracts without evaluating package source.
Automatic exports preserve validated declared sibling names, including a
README.org manual that generates package-named Texinfo and Info artifacts.
Private staging also preserves those basenames inside the generated Info file’s
navigation headers.
The document-elisp-extras batch separates coverage-only reports from authorized
manual updates, accounts for every source, and preserves per-package ownership.
Exports use reviewed destinations and distinguish format generation from accuracy.
The diagnose skill separates configured, loaded, triggered and acted-on evidence
for the incident’s actual runtime. It preserves uncertain/mixed causes, requires
practical enforcement coverage, and tests legitimate and unsafe guard cases.
The design-audit skill accepts explicit plain-language refactoring requests,
requires concrete maintenance benefits, and preserves runtime/public contracts.
Counts, local call searches and single implementations alone do not justify edits.
The code-audit skill requires supported failure evidence, distinguishes defects
from generic hardening, and checks exact failing behavior after fixes. Audit-only
checks cannot smuggle in snapshot rewrites, installs or external side effects.
The chrome-permission-audit helper defaults to non-recording reads and requires
exclusive closed-browser store access. Revocations consume reviewed exact plans,
preserve deny/transient records, and retain permission-key-only recovery backups.
Its classification rules do not infer safety from generic documentation hosts.
Owner-specific rules live in ~/.claude/chrome-permission-audit/private-rules.json;
changes to them invalidate previously reviewed revocation plans.
The build skill preserves the requested spec/planning/implementation endpoint.
It investigates before interviewing, records decisions incrementally, separates
real blockers from assumptions, and keeps execution plans tied to the accepted spec.
The automate skill distinguishes advice, construction and runtime activation.
It chooses among deterministic, gptel, skill and scheduled implementations,
preserves scope and authorization, and verifies loading separately from behavior.
The add-to-emacs-packages workflow checks the list, existing manual and profile
card independently. It resolves canonical sources, preserves note IDs and keeps
local registration separate from clone and publication authorization.
The add-bib-entry workflow stays enabled across sessions and follows
zotra-extras-add-entry with the actual ebib-extras-process-entry command.
It resolves active bibliography state and serializes attachment callbacks.
It verifies work identity and labels uncertain metadata. Article PDF downloads
go through paper-fetch; metadata, explicit attachment and entry
processing stay in Emacs. The skill has no separate downloader or BibTeX writer.
The download-paper workflow obtains one paper PDF by DOI, URL, arXiv id,
md5 or title through bin/paper-fetch, the single paper-acquisition tool
(shared logic in lib/python/paper_fetch.py). The tool exhausts every route
that works from a shell and verifies the file’s identity; the skill adds the
one step the tool cannot take, a real Chrome session for hosts behind a bot
challenge, and the exact order that step needs. For Anna’s Archive SciDB
records it clicks the page’s Download link and falls back to the page’s
Sci-Hub link when the partner server cannot serve the file. It reports the
tool’s status taxonomy verbatim and hands a staged file to add-bib-entry for
attachment.
Before attachment it stores the verified document language; PDF processing keeps
the intended file and language across buffer switches without a language prompt.
The agent retains one explicit entry/database operation through attachment,
abstract generation and OCR, and polls its own pending task count. Existing
abstracts are preserved; unresolved choices and conflicting edits produce a
blocked result. After resolving a failure and draining callbacks, retry the
existing entry with a new operation. Agent runs load the database in the
background without selecting Ebib entries, displaying PDFs or asking questions.
Manual commands retain their interactive behavior. No global input functions
are rebound.
Metadata corrections use Ebib’s bracing field setter and contextual save wrapper;
verification includes parsing the saved entry back to its original field values.
Paired configuration audits allow matching resource deletions within retained skills while still rejecting one-sided resource or whole-skill deletions.
Both interactive and programmatic walk-list copies use exact input identity
and locked lifecycle transitions. Native atomic exchange detects displaced-file
races and retains uncertain recovery data; new stored copies and evidence use
owner-only mode bits. Workers must finish or stop before claim reuse. Reconcile
lost command acknowledgements before retrying, and distinguish a fully recorded
queue from successful task outcomes.
The programmatic Hartree trial queue reviews source before execution, keeps
trial dependencies outside Drive, and promotes only a user-accepted candidate.
Verdicts, pending evidence and prior verdict history live in one private progress
file outside the repository: ~/.local/state/agent-skills/try-hartree-skills.json,
overridable with HARTREE_SKILLS_STATE. Public sources contain only the candidate
queue and procedure; a completed private queue does not restart itself.
The programmatic open-session-log helper resolves the current runtime’s session identity and exact transcript in its active account root. It opens that path in Emacs and checks the rendered buffer’s identity before reporting success; concurrent sessions cannot be selected by recency or project alone.
The profile-ai-cli-performance skill measures selected client conditions
with exact terminal-success evidence and nullable, failure-aware paired metrics.
Dry runs do not access credentials or launch clients; selected conditions alone
determine dependencies. Unsafe token duplication and identity/provider changes
cannot be hidden as clean baselines. Private reports preserve incomplete cohorts
and unobserved isolation; timing completion does not establish a causal claim.
The paste-via-kill-ring skill owns the procedure for handing over text the
user must paste himself (Emacs kill ring, clipboard for Chrome or native
forms, opening the target thread). The global instructions only point at it,
and the service-access routing table lives in
context/service-access.md for the same reason: procedures load on demand,
while the always-loaded file keeps one trigger line each. That routing table
uses the extension-backed Chrome plugin for Codex automation and reserves
chrome-profile-open for explicit manual page launching because it activates
Chrome and can steal focus.
Browser control is runtime-owned rather than mirrored through a tracked Codex-App handoff skill. Claude therefore carries no pointer skill or helper command for moving a Codex thread into the desktop app.
The move-session-log adapter reassigns individual resumable sessions or whole
renamed projects by moving verified Claude transcript/sidecar owners and selected
history metadata. Preview precedes apply; offline stores, writer checks and private
recovery backups protect against overwrite and lost appends. Encoded-path and
destination collisions fail before mutation, as does a backup directory whose
parent does not yet exist, each with a named reason. Historical tool records remain
unchanged, and project trust/settings remain untouched unless separately
authorized. A recovery journal records partial failures; metadata counts alone
do not establish live resume behavior.
The paired Codex adapter allows single closed-session imports while unrelated
sessions remain open, using SQLite transactions and consistent recovery backups.
Its bulk rename mode retains the full-store offline checks.
Codex relocation also reconciles the exact session’s Emacs buffer and live
working directory, rather than treating a history-listing change as completion.
When Agent Log is the entry point, its cached catalog, rendered file location
and actual agent-log-resume-session command are checked together.
Model-invocable tracked skills do not preapprove bare high-risk tools through
allowed-tools. Loading a skill therefore leaves Bash, write, edit, agent, and
user-question permission decisions to the ordinary runtime policy. A narrowly
scoped Bash pattern may be declared when a skill genuinely needs one.
The paired publish-dotfiles skill is an ignored local workflow, excluded from
this repository’s public distribution. The public publication guard helpers
scan the full history automatically and require manual review of all findings,
risky and opaque source objects, and known manual incidents. Exhaustive patch
review applies to outgoing commits, including comparisons with every merge
parent. Scanner findings carry fingerprint-redacted source context. Runs,
manifests and audit receipts bind the review-policy version and its scope. Raw scanner reports are
confined to a private off-tree temporary workspace. Git scans use the same
zero-context patch stream as Gitleaks and never reinterpret patch coordinates as
blob lines; directory scans use authoritative source lines and advisory
byte-column spans. Schema-4 runs separate scrub values from keyed review
signatures. Review writes are locked so bounded agent pools cannot overwrite one
another’s verdicts.
Readiness uses an enforced non-publishing scan mode that preserves refs and
FETCH_HEAD. Full-audit receipts age from the scan and cannot clear later
incident invalidations; missing advertised public objects fail the audit closed.
Release authorization binds the exact tag name reviewed by the scan. Read-only
checks never authorize history repair or provider-side credential changes.
Audit receipts bind the reviewed scan and manifest, including across concurrent
same-boundary rescans; earlier clean status cannot certify a replacement.
The paired release-dotfiles skill preserves the profile-test gate, excludes the
read-only Elpaca mirror from package pushes, and verifies live recipes before
serializing a lockfile. It uses supported GitHub PR fields, strict release tags,
path-only version commits, and the same approved notes file for review and
release creation. Preparation alone grants no publication authority.
The paired verify skill maps actual requirements to version-bound evidence.
Verification-only requests do not authorize repair. Human judgment and missing
evidence stay visible rather than becoming agent-approved proxies. Criteria
cannot be relaxed to obtain a pass, and completing a review does not certify
that its target is correct. Sampling and fixture limits remain explicit.
The paired test-suite skill binds tests to the intended source and independent
behavior contracts, isolates side effects, and checks discovery and failure
sensitivity. Tests-only work preserves product code and reports valid failing
regressions without claiming a green suite or a repaired bug.
The paired symptom-check skill evaluates a proposed repair against a supported
invariant and related code paths. It preserves read-only diagnosis, allows an
explicitly pending disposition, and requires direct symptom evidence before
claiming repair or closing an architectural issue.
The paired session-learning-capture skill records proposals only after checking
session provenance and permission to use the Drive-synced personal inbox.
Stable full-session record keys and no-clobber publication protect retries;
capture does not promote lessons or imply that a review consumer is installed.
The paired release-package skill distinguishes candidate audits and preparation
from publication. It binds versions, notes, checks and exact branch/tag objects,
compares versions without losing patch components, and reconciles partial releases
without moving published tags or silently widening push destinations.
Some retained local workflows are encrypted with git-crypt at their existing
skill paths. Their working instructions remain available in an unlocked checkout;
the encrypted bodies are not public skill catalog entries.
The paired record-decisions skill records evidenced choices and dated amendments
without rewriting decision history. It preserves numeric IDs beyond three digits,
keeps summaries consistent with records, and leaves no-op runs unchanged. Reading
the skill does not authorize writes or imply automatic summary loading.
The paired proofread skill resolves one external Node dependency runtime for
both setup and execution, canonicalizing both its root and actual node_modules
destination before rejecting paths into this Drive-synced tree. Only the LLM
engine consumes an injected provider key; skill-local plaintext .env files
are no longer loaded. Review-only work does not write copies or imply provider
transfer. Editing preserves source files, requires validated literal changes,
and distinguishes engine failures and protected-syntax gaps from clean results.
The paired personalize skill carries a hard concision rule: outgoing drafts
carry only what the recipient needs to act or decide, lead with the ask, and
hold Slack replies to a few sentences. Short chat replies take a fast path
that skips the humanize catalogue, whose clusters cannot form in a few
sentences, so a one-line reply is one drafting step and one staging command.
It also enforces act-first replies: the draft never says Pablo will do
something he can do now; the work happens first and the reply reports it done.
The lint-elisp runner uses literal file arguments, private bytecode output and
separate compiler/checkdoc completion records. Errors and skipped compilation
cannot become clean results. Its fixes preserve binding and initialization
semantics, and source-first batch diagnostics do not prove live behavior.
The interpretability-audit skill distinguishes sampled from exhaustive coverage,
accepts plain-language fix requests, and grounds clarity findings in actual reader
misunderstandings. Renames and extractions require contract checks; unknown rationale
does not become an invented comment, and audit-only checks cannot rewrite files.
The paired humanize skill owns the single tells catalogue that personalize
reads by reference. Beyond the Wikipedia-derived tells it launched with, the
catalogue covers the engagement register (throat-clearing openers, faux-insight
setups, colon reveals, fake-profound kickers, and kin) merged from
petergyang/no-ai-slop.
Its patterns are editing heuristics, not authorship tests or numerical quotas.
It preserves meaningful qualifications, list items, citations and functional
markup; citation lookup failures do not justify deletion, and URL cleanup keeps
functional query parameters. Inline edits and read-only reviews stay in scope.
Calling workflows invoke it explicitly; it is no longer a wikipedia-article phase.
Org task triage is split across two skills over one engine. triage-personal-todos
here owns personal notes; the project-local triage-project-todos in the Epoch
workspace owns Epoch work. bin/triage-notes loads its owner-supplied engine
and excluded roots from ~/.config/triage-notes/config.json, then binds
personal commands and artifacts to their corpus; project ownership still needs
checking beyond a corpus label. Index/worktree publication uses snapshot checks
and owned rollback, not an indivisible transaction against arbitrary writers.
Personal brief-only requests do not assign priorities. Selection checks the
task’s current state and premise, then rebuilds the eligibility ledger when
that evidence changes. Missing priority values limit verified ranking; old
notes and absent provenance alone do not prove completion or staleness.
VERIFY_WITH is an evidence hint, not authority to execute commands or writes.
The personal a/s/d/r/m choices bind to the exact briefed task. Confirmed d
uses the engine’s supported complete update after checking Org workflow and
date semantics; it does not rewrite unfinished work or create follow-ups.
All mutations preserve foreign index/buffer state and inspect actual postimages
before committing. Failed or ambiguous publication retains recovery evidence.
The paired update-log skill runs only on an explicit bookkeeping request or
the deliberate --auto chain. It preserves established map modes, intentionally
different agent instructions, foreign changes and actual file-tracking policy.
Ignore rules do not make tracked or Drive-synced content private. Post-update-log
hooks refresh the brief before its map is derived, within the caller’s authority;
derived fields cannot originate unverified claims.
Work commits and bookkeeping transactions are separate. Epoch closeouts use the harness’s explicit input set; publication needs its own authorization and verification at the intended destination. Final receipts publish without overwriting an existing target and validate bounded evidence, but do not prove project identity or commit scope. Failed or ambiguous outcomes retain recovery evidence instead of erasing it during cleanup.
The paired orchestrate-review skill coordinates fixed Claude and Codex
sessions through one guarded, stage-atomic workflow. Its helper binds each
actor’s backend, repository, and transcript, and records delivery attempts
before contact. A phase becomes active only when the marker-bearing prompt
itself appears in the actor’s transcript past the recorded boundary; a busy
terminal or background transcript growth is not acknowledgement. Terminal
assistant returns distinguish completion from tool activity. Attempt hashes are taken over the prompt as the terminal
records it, without trailing newlines, and user-role records the harness
injects (teammate messages, task notifications) do not end the prompt turn. Ambiguous restarts and steering require reconciliation,
not another submission. Shared session primitives live in
lib/python/agent_session_lib.py. During implementation, monitoring exposes
the fixed actor’s state and its published progress, not internal task
transcripts or processes. The watcher does not automatically enforce a timed
stop-loss or detect login screens. Agents use supported host waiting mechanisms
and keep the host’s required update cadence. Cleanup closes only run-owned,
confirmed-inactive sessions; adopted or busy sessions remain protected.
The paired request-review skill requests one opposite-CLI review of an
immutable committed plan. It preserves review-only scope, binds a stable
session identity and exact run-specific prompt before dispatch, and accepts
only a terminal return from that submitted turn. Ambiguous delivery remains
pending; missing evidence cannot authorize retransmission or an unsupported
process-loss restart. Its helper reuses agent_session_lib and records private
recovery evidence. Cleanup protects active, reused and unowned sessions.
The handoff skill separates drafting, saving and user-triggered replacement.
It saves private per-session artifacts without later overwrites, preserves shared slots,
and requires exact source/artifact checks and a one-invocation file binding
before preparing a consumer command. Source inspection is not live readiness.
The google-sheets-comments skill binds account/file/thread/reply identity,
uses current API evidence rather than email notifications, and preserves exact
action authority. Its gdoc contract records projection and receipt limitations;
fresh pre/post checks reconcile ambiguous writes before any retry.
The generate-readme skill preserves established Org manuals, README-specific
material and foreign edits. It distinguishes package/feature/repository names,
checks recipe prerequisites and installed revisions, verifies publishable links,
and reserves manual renames or roadmap migrations for explicit requests.
The fix-drive-errors skill separates read-only diagnosis from authorized
repairs and binds live evidence to the displayed account and sync root. Its
reader preserves duplicate rows and exact reasons, refuses incomplete scans,
and labels simulated panels and heuristic filesystem candidates. Repairs
preserve exact files and consumers; Epoch .gdoc replacements require checking
the actual saved .url → OS handler → Epoch document route before authorized
trashing of an unchanged original. Restart and settling checks are bounded.
The Claude hook index owns registration boundaries and the per-file index.
Claude has events with no Codex equivalent here, including Read, Grep,
Glob, Skill, Notification, and Chrome-specific events. Those are explicit
manifest differences, not missing peers.
Hooks that return JSON follow the Claude hook contract exactly:
hookSpecificOutput carries hookEventName and additionalContext, and a
branch that wants Claude to react exits 0 with top-level decision and
reason. A bare message field fails schema validation and is dropped, and
JSON printed beside a non-zero exit is discarded, so both shapes silently lose
the hook’s result. tests/test_hook_output_contract.py exercises every output
branch of load-elisp-after-edit.sh and regenerate-manual-after-edit.sh and
scans both hook trees for the invalid shape. The live registration gives
load-elisp-after-edit.sh a 150 s timeout, matching Codex, because the script
waits up to 120 s for the Elpaca rebuild before reporting.
The SessionStart sync hook, sync-reasoning-tasks-worktree.sh, runs under a
30 s registration timeout and budgets its network steps to stay inside it: the
task-state banner is capped at 15 s (the script’s own alarm fires at 12 s), the
fetch at 10 s, and a TERM during the merge aborts the merge so no worktree is
left with a stale MERGE_HEAD that later sessions would read as dirty. Its
local-settings registration writes atomically.
tests/test_sync_reasoning_tasks_hook.py executes the real hook against
scratch repositories for the no-op, register-and-merge, and interrupted-merge
paths.
Sensitive-read guards permit the security audit’s shell-export classifier only for its exact absolute helper and target paths. The classifier reports names, line numbers, scopes, and classifications without printing values.
Commit gates resolve explicit path selections against a disposable candidate index. A git commit --only checks the selected working-tree changes, including inherited changes when amending, without counting unrelated staged Elisp or documentation. Unsupported selection syntax is denied with a reason; these checks do not alter the shared index.
Candidate documentation audits execute the checker committed at HEAD.
They omit private skill entrypoints from the disposable audit index only when
both their indexed git-crypt attribute and ciphertext header agree. This
keeps encrypted skills out of the public inventory without reading unlocked
private text or executing a staged checker. Declared encryption with a
plaintext indexed blob fails the audit.
Quoted commit-message heredocs are shell input. Their delimiters and bodies are excluded from Git’s selected paths; interpreter-fed heredocs remain visible to the command classifier.
The Elisp evidence gate recovers a nested functions.exec command’s working directory before routing it to a repository. The reduced routing payload cannot recover the parent transcript context afterward. Directory selections include files known to Git, so an untracked manual cannot satisfy the documentation gate.
The Bash dispatcher denies commands when a delegated guard exits unsuccessfully or returns invalid decision JSON. It parses decisions independently of formatting and rejects interactive approval responses. Failure diagnostics identify the guard and exit status without exposing its failed output or the command payload.
The secret-leak guard denies direct agent-shell invocations of raw op,
pass, macOS security, and pbpaste, including wrappers, nested shells,
process substitution, executable globs, and shell-word obfuscation. The
1Password brokers op-automations and op-desktop are the sanctioned access
path: lib-op-policy.py allows a closed list of command shapes whose stdout
carries no credential (masked run, captured or filed read, metadata-only
jq over item output, --out-file documents, writes without --format,
metadata commands, including the vault user list / vault group list /
group user list membership listings) and denies every other shape,
including shapes it cannot place. Broker paths passed to ls, stat, or readlink are inert file
metadata arguments; broker execution elsewhere in the command is still checked.
The exact bash -n FILE syntax-check form is also allowed; extra options are not.
Shell expansions are fine in broker arguments (--env-file
"$ROOT/…"); an expansion in the subcommand position is unclassifiable and
denied. The Claude Bash dispatcher delegates this decision to the standalone
guard instead of carrying a second inline policy copy. Quoted argument globs, including rg
exclusion patterns beginning with !, remain inert data rather than executable
command words. A shell case default pattern is likewise grammar, not an
executable glob. Heredoc bodies fed to a known data sink (cat, tee, git, gh, and
similar) with no pipe or substitution around them are data too, so a commit
message or a Markdown file written through a heredoc is never scanned as
shell text; bodies fed to shells, interpreters, or unknown programs stay in
the scan. For a narrowly recognized quoted Python stdin program, the secret
guard first checks Python protected references, exempting genuine pass
statements and a closed text/JSON document-edit language, then excludes classified
bodies from shell lexical checks. Document edits permit only validated standard
imports, data bindings, text reads/replacements/writes and JSON conversions.
Bound JSON data may receive an update statement with one validated dictionary
literal; the mutation alone does not qualify as a document write.
Unknown calls, executable targets and shell tails retain conservative scanning.
Denials describe a failure to classify the command safely, not proof that a
credential tool ran: protected names inside an unclassified Python program may
be ordinary prose. Programs with subprocess calls remain outside the closed
document-edit language even when those particular calls are benign.
This exception requires one standalone direct Python command. Codex additionally
requires one complete literal functions.exec wrapper with inert metadata;
multi-call and dynamic orchestrations receive no document-edit exemption.
Python varargs are not shell executable globs. Other secret checks still receive
the original input. Literal pyenv exec python - stdin programs use
the same Python classification, including its protected-reference checks; other
pyenv subcommands and dynamic interpreter names receive no exemption.
Consecutive supported Python heredocs receive the same classification in order;
unknown shell structure stops the scan without exempting the remaining text.
This classifier is not a Python sandbox.
The Git classifier also recognizes these quoted Python bodies before parsing
shell substitutions. Backticks and substitution markers in data without
standalone Git/commit references no longer fabricate ambiguous commits;
Git-bearing interpreter source retains conservative scanning. Quoted Git
commit-message input is excluded before substitution parsing as well.
Public routing is classified by lib-public-url-scan.py, whose declarative
registry covers only verified authority/schema pairs. Only URL operands of
recognized literal curl=/=wget commands receive routing projections;
unknown command forms retain the conservative opaque-token scan. Headers,
bodies, filenames and URL tails remain scanned, including bounded percent
decoding. Denials identify the field and rule without printing suspect bytes.
This does not exempt every public PDF or replace known-secret checks on the
original command. tests/test_public_url_scan.py pins the parser boundaries.
The inline-secret scan recognizes public MusicBrainz entity URLs before
tokenizing their identifiers. Queries, fragments and credential arguments
remain scanned; URL components never receive filesystem-path exemptions.
DAHR matrix URLs normalize only the exact public host, fixed route and decimal
record ID. Their free-form title slug, further path, query and fragment remain
scanned, as do credential headers and request bodies.
PMLR proceedings URLs similarly normalize the public host and numeric volume
route; article identifiers and all additional URL content remain scanned.
Jagiellonian University repository URLs normalize only the exact
ruj.uj.edu.pl/bitstreams/UUID/download route and the same host’s
server/api/core/bitstreams/UUID/content route. Queries, fragments and request
credentials remain scanned; UUIDs elsewhere receive no exemption.
UPLOpen’s exact uplopen.com/en/books/NUMBER/files/UUID.pdf route receives the
same narrow treatment; its query, fragment and request credentials stay scanned.
EJPE’s exact ejpe.org/journal/article/download/NUMBER/NUMBER/NUMBER route also
normalizes public record IDs without exempting extra path or request content.
ZNU’s exact files.znu.edu.ua/files/Bibliobooks/InshiNUMBER/NUMBER.pdf route
receives the same treatment for its public library identifiers.
Adelaide’s exact digital.library.adelaide.edu.au/bitstreams/UUID/download
route and its server/api/core/bitstreams/UUID/content counterpart normalize
the public document identifier. ZORA’s exact HTTPS host www.zora.uzh.ch
normalizes only /id/eprint/NUMBER/NUMBER/; filenames remain scanned.
UCL Discovery uses that same numeric eprint prefix on the exact HTTPS host
discovery.ucl.ac.uk. Jacob Barrett’s author site recognizes only the exact
HTTPS host www.jacobbarrett.org and public account prefix
/uploads/1/2/3/6/123631127/. Bob Beddor’s exact HTTPS host
www.bobbeddor.com similarly recognizes only /uploads/3/2/0/3/32037343/.
JESP’s migrated exact HTTPS host www.jesp.org recognizes the complete
/pdf/UUID document route, with no trailing path exemption.
Kent’s exact HTTPS host blogs.kent.ac.uk recognizes only the
/futureofnormativity/files/YYYY/MM/ public conference upload prefix.
Brown’s exact HTTPS host www.brown.edu recognizes only the public
/Departments/Philosophy/bears/ review prefix. Jagiellonian’s exact HTTPS
host ruj.uj.edu.pl also recognizes complete /entities/publication/UUID
metadata routes.
Filenames, query strings, fragments and request
headers/bodies remain scanned; other accounts and lookalike authorities are
not classified as these public routes.
LSE’s exact HTTPS host eprints.lse.ac.uk projects only numeric record/file
prefixes. JESP’s jesp.org projects its complete numeric article-download
route; Frontiers projects only the observed artificial-intelligence article
route with a numeric 10.3389/frai.YEAR.NUMBER DOI. The exact HTTPS host
80000hours.org projects its dated WordPress uploads prefix. Cambridge’s
exact HTTPS host www.cambridge.org projects the public content-view prefix
with a 32-character hexadecimal document ID and numeric article-file ID;
the trailing descriptive filename remains scanned. These are verified source
schemas, not domain exemptions. Unknown routes retain slash-spanning scans,
because splitting every path at slashes would hide Base64 credentials that
contain slashes or payloads distributed across path segments.
Ergo’s HTTPS journals.publishing.umich.edu/ergo/article/NUMBER/galley/NUMBER/download/
route normalizes public article and galley IDs. These routes retain query,
fragment, header and body checks; extra path and spoofed hosts stay scanned.
Sabanci’s exact myweb.sabanciuniv.edu/ozgurkibris/files/YYYY/MM/ HTTPS
upload prefix is normalized without dropping filenames, request payloads or
URL tails; other authors and routes remain subject to the original scan.
HLI’s exact www.happierlivesinstitute.org/wp-content/uploads/YYYY/MM/ prefix
normalizes public upload routing; filenames and all subsequent URL content stay
scanned, along with credential headers and request bodies.
Slash structure never grants a filesystem-path exemption. Only positively
classified literal file operands, including curl @file and output files,
are omitted from the entropy scan. Unknown options and shell forms stay scanned.
Literal file operands of isolated cat, head and tail reads are excluded
from entropy scanning when a separate network check follows. Pipelines,
redirects, shell expansions and unknown read options receive no exemption;
known-secret checks still inspect the original command. Loopback ports and
API-version prefixes are routing metadata; the remaining URL path, query and
fragment remain scanned. Each candidate is classified before choosing a hit,
so a harmless early string cannot conceal a later credential.
False positives require classifier repair, not manual guard bypass.
The sensitive-read guard applies the data-sink rule and names the
heredoc in its denial when a path is mentioned only inside an
interpreter-fed program. A shell eval is recognized only at a word
boundary, so an emacsclient --eval argument is Elisp, not shell.
Since 2026-09-05 the protected names pbpaste, pass and security are
denied only where something could run them: as a command word, behind
env, sudo, xargs or find -exec, joined with === (git -c
core.pager=…), inside bash -c source, or inside a heredoc body fed to a
shell or interpreter, where a string literal counts as a reference. A plain
argument of a read-only text tool (grep -rn pass docs/, git log -S
pbpaste, ls /usr/bin/pbpaste) is inert and passes; lib-inert-mentions.py
performs that projection. Heredoc bodies fed to known non-shell interpreters
(python, node, ruby, emacs, sqlite3, jq, …) are no longer scanned for
executable globs, so ? and [ in a script are not misread as shell words,
and the Python classifier recognizes cd x && python3 - "$S" <<'EOF' shapes.
Wrappers consume only their options, assignments and durations, so
env FOO=2 grep pass f runs grep. The audited bin/op-clipboard-store
consumer is the sanctioned route from a console Copy button into 1Password;
tests/test_secret_guard_inert_mentions.py pins the allowed and denied shapes
for all three guard entry points.
The Elisp post-edit hook rebuilds and reloads complete package worktrees, but skips test-only files and edits while Git has an active operation or unmerged index entries, so a live Emacs never loads tests or a partially resolved tree. Test-only Elisp commits likewise do not require package-manual updates.
Live-verification evidence for a standalone-package label binds to the
package’s own checkout, resolved through bin/elpaca-package-resolve, never to
the shell’s working directory. The verify-after-commit gate keys its debt to
the committing repository while blocking cd, so a harness that pins the
working directory to the dotfiles root could otherwise never clear a debt for
a commit in a package repository.
Commit inspection with --dry-run, status-format options, or help does not
create a live-verification obligation. Those words in message arguments or
pathspecs do not exempt an actual commit.
The live-verification gate permits literal read-only diagnosis through
lib-elisp-diagnostics.py while retaining every pending check. Supported forms
also include emacsclient -e with the exact rebuild-token status call or the
bounded package-filtered registry query. Recovery protocol and diagnostic-gate
tests may run as python3 -I -B ABSOLUTE-TEST-PATH for the two canonical test
files test_elpaca_rebuild_protocol.py and test_elisp_live_diagnostics.py.
These isolated fixture tests retain pending package/commit identities and never
certify live behavior. Extra arguments and other Python programs stay blocked.
Other supported forms
include cat, numeric sed -n ranges and rg --no-config. Git requires
--no-pager; index-reading commands (status, ls-files, diff) additionally
require --no-optional-locks -c core.fsmonitor=false. Diff, log and show
require --no-ext-diff --no-textconv. Only closed option forms are accepted;
required switches cannot be option values or paths after --. Shell composition, expansions,
arbitrary interpreters and mutations remain blocked. Denials identify the
pending package, commit and repository. Only successful bound live evidence
clears the obligation.
The Codex counterparts also depend on native hook trust: a modified test tracker can be skipped while the commit guard continues to require its evidence. Restore trust for the reviewed tracker definition before rerunning the check. Test recorders skip the index hash when the working revision already matches, so an unnecessary index scan cannot exhaust the hook deadline after consuming the receipt but before saving the test result. Staged-only evidence still checks the index revision.
Hooks that judge a Git command resolve the repository from the command itself,
via hooks/lib-repo-root.sh. A cd at any command head decides the repository,
the last one winning, because a session working in one repository routinely
commits in another and the cd is often preceded by a preamble. The target is
extracted by parameter expansion, never evaluated; $HOME is substituted, and a
target carrying command substitution or any other unexpanded variable is treated
as unresolvable. When the target cannot be resolved the helper reports no
repository at all rather than substituting the session’s own, since judging a
tree the command never touched both refuses correct commits and approves ones it
should refuse.
The GitHub write guard resolves the target repository from the command before
it falls back to the surrounding checkout’s remote. gh repo verbs name their
target positionally and gh api endpoints are read through a leading slash or
surrounding quotes; both used to miss, leaving the ambient repository to stand
in, so an unowned target inherited whatever allowlist entry that repository
had. gh repo create now refuses a command that names no OWNER/REPO at all,
because a creation never acts on the current repository and so cannot borrow
its authorization.
GitHub writes require repository authorization or an explicitly authorized
scoped contribution grant. Topic branches, issues, and comments have no exemption;
read-only inspection remains available for undeclared repositories. A registry
match makes the guard fall through silently rather than explicitly approving the
write, including for pull-request merges, so the host’s normal permission layer
and the global user-authorization rule still apply. The guard reads the
allowlist and the automations registry from the committed HEAD revision, so
appending a target to the working tree and retrying confers nothing. The guard
implementation and hook registrations remain agent-editable; there is no
separate self-edit guard.
The dotfiles-context and elisp-conventions workflows prepare a local topic
branch, PR draft and retention plan for external-package fixes even when no PR
was requested. Diagnosis-only and explicitly local-only tasks retain their scope;
publication and profile activation still require applicable authorization.
Scoped fork and PR-creation grants use the operation authorization procedure and a shared checker. Only committed, expiring records match; each binds an exact command and authenticated account, plus the PR body hash where applicable. These grants do not authorize other upstream writes or establish user consent. Completed grants are removed without editing the hooks or broadening repository access.
A change under claude/skills, claude/hooks, claude/settings*.json or
claude/CLAUDE.md must be accompanied by an update to this file. The guard
accepts only that exact path, named among a command’s git add arguments: some
other README does not stand in for it, and a commit message mentioning the file
is not an update to it. Both were previously accepted, which is how the triage
split reached this repository undocumented.
Guards that inspect a Git command read its arguments only, never its message.
Heredoc bodies are dropped before lexing, because an apostrophe in prose made
the lexer raise and the parser fail closed on a commit that staged no Elisp at
all; argument text that genuinely cannot be lexed still fails closed. Since
these are PreToolUse hooks they run before the git add they are judging, so
the paths a command is about to stage count as staged. A second git commit in the same
command is modelled in sequence when && links it to the first: the adds
between the two commits are its content, and the guard audits the union,
which is the tree the whole command leaves behind.
The SessionStart reasoning-worktree synchronization hook is also Claude-only.
It repairs required key links before eligibility checks, updates eligible
worktrees without pushing, reapplies the local overlay, injects private
project skills, and installs worktree-local freshness protection. Because the
key repair precedes the eligibility checks, it delays the start of every
session in every repository, and it therefore starts no subprocess while the
links are correct. Keep it that way: an added basename or readlink for each
worktree previously cost approximately 0.41 seconds of session start time. Its bulk
wrapper fetches shared state once before processing multiple worktrees. All
worktree-creating helpers construct destinations under the shared external
root ~/repos/.worktrees/<repository>/<branch> — never inside a repository
checkout or ~/My Drive — while maintenance helpers keep covering legacy
worktree locations until those are migrated.
Project-local pairing reminders follow the repository’s ai-config-sync.json
policy for local.skills and local.instructions. Explicit single-agent
statuses such as claude-only or codex-only suppress counterpart reminders
for that artifact type only; unrelated hook reminders still apply. Missing,
unreadable or malformed manifests, including invalid text encoding, retain the
default pairing reminders. These are advisory messages, not commit approval.
Run bin/ai-config-sync audit after changing shared configuration. When a
tracked public skill name or catalog description changes, first run
bin/docs-audit generate. For a registered hook change, verify both its
standalone decision logic and the real Claude event path; mutable
~/.claude/settings.json registration is part of that behavior.
Claude’s settings format, event surface, permission model, browser integration, and account overlays are genuine tool-specific state. The sync contract records those differences rather than forcing them into Codex-shaped files.