Files
AIPass/.aipass
AIOSAIandClaude Opus 4.8 beb048dadf fix(hooks): presence_gate keys per-branch via hook_data cwd; engine propagates block exit code (FPLAN-0289 P1)
Activation fixes for the single-session presence gate. Two bugs blocked it,
both caught by live testing after all units were green:

1) Wrong branch key. presence_gate used Path.cwd().name, but under the Claude
   Code bridge the hook process cwd is the project root, so every session keyed
   to "AIPass": the gate never enforced one-live-session-per-branch and would
   have rejected sessions project-globally (any 2nd interactive session in any
   branch). Now _resolve_branch(hook_data) reads the event payload's cwd (the
   real session dir) and walks up to the branch root (.trinity/ or apps/),
   mirroring branch_loader. Applied in handle() and handle_stop().

2) Block never reached Claude Code. engine.dispatch() returned only stdout, so
   the bridge could not surface a non-zero exit. dispatch() now returns
   (stdout, exit_code) and the bridge exits with it on a block. Pre-existing gap
   affecting every block hook on every event; now fixed engine-wide. An
   intentional block (exit 2 + {"decision":"block"}) propagates; a crashing hook
   (exit 2, non-JSON stdout) is logged and falls through, so the gate fails open.

Proven: 110 hooks unit tests pass (6 new for branch resolution); seedgo @hooks
100%, no type errors. Live bridge end-to-end (real live holder + real bridge):
duplicate into a held branch -> exit 2 + block reason naming the branch; a
different free branch -> exit 0 (per-branch isolation intact). Gate remains
dormant: not yet wired into provider settings.

Design: DPLAN-0225 / FPLAN-0289 P1 activation. Build by @hooks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CqoxFdbDMirzkQ5kjRVVos
2026-06-29 17:46:09 -07:00
..

.aipass/ — project prompt & hook config

This folder holds the project-level prompt and hook configuration for the AIPass repo, plus the templates aipass init stamps into every new project. It is the project layer; each branch additionally has its own branch prompt at src/aipass/<branch>/.aipass/aipass_local_prompt.md.

Nothing here is dead weight. Every file is live injection, live config, or a required new-project template. Superseded files live in .archive/ (never deleted).

One prompt system, every runtime

There is one source of prompt truth — the tier files — and all runtimes inject the same content. We do not keep separate prompts per CLI. Only the delivery differs:

Runtime How the same content is delivered
Claude Code Tiered by cadence (FPLAN-0284): tier0_kernel.md every turn + tier1_navmap.md periodically + post-compaction
Codex CLI Injected once at SessionStart (no per-turn cadence): the same tier content, combined

⚠️ Migration in progress. The Codex SessionStart hook (.codex/hooks/session_start_identity.py) currently still reads the legacy aipass_global_prompt.md. @hooks is wiring it onto the tier files. Retire for one runtime = retire for all — once Codex is on the tiers, aipass_global_prompt.md is read by nothing and moves to .archive/.

Files

Live — this repo's prompt + config

File What it is
tier0_kernel.md The kernel — tiny identity + drone --help reflex + don't-get-lost rules. The always-on core, for every runtime.
tier1_navmap.md The navmap — full agent roster, framework, terminology. The periodic/fuller layer, for every runtime.
hooks.json Claude Code handler registration for this repo — which prompt/gate/notification handlers fire on which events.
PROMPT_STYLE.md The writing-style guide every prompt here follows.
.gitignore Whitelist guard — only files listed here are tracked; everything else in .aipass/ is ignored.
aipass_global_prompt.md Legacy single global — being retired. Disabled for Claude Code; Codex still reads it until its migration lands, then archived. Not the source of truth.

Templates — stamped into new projects by aipass init (bootstrap.py)

File Stamps → Notes
project_hooks.json new project's .aipass/hooks.json REQUIRED — without it a new project's hooks never fire. Mirrors the live wiring (tier0 + navmap enabled, global disabled).
project_CLAUDE.md new project's CLAUDE.md the project's Claude Code instructions.
project_global_prompt.md new project's aipass_global_prompt.md Legacy — same retirement path as the global above (new projects ship tiers-only once Codex is migrated).

(AGENTS.md — Codex's equivalent of CLAUDE.md — is generated by bootstrap.py when no project_AGENTS.md template exists, so none is kept here.)

What a new project gets (aipass init)

bootstrap.py seeds a fresh project with the tiered system:

  • tier0_kernel.md + tier1_navmap.md → the prompt content (every runtime)
  • hooks.json (from project_hooks.json) → tier0 + navmap enabled, global disabled
  • CLAUDE.md (from project_CLAUDE.md) + a generated AGENTS.md
  • aipass_global_prompt.md (from project_global_prompt.md) → legacy, retiring with the above

aipass init update backfills the tier files + refreshes hooks for existing projects.

Changing a prompt here

Run the prompt-change playbook so a change reaches every runtime and every seed path:

drone @flow create . "What changed" prompt_change

Golden rule: live ≠ seeded. Editing this folder fixes this repo only. New projects come from the project_* templates + bootstrap.py; fresh clones get their machine-local wiring from setup.sh + .claude/provider_manifest.json + cadence.py defaults. And every runtime (Claude Code + Codex) must point at the same tier content.

Archive & recovery

Superseded files move to .archive/ (never deleted — house rule). Recover from there, or from git history, any time. Current archive: the pre-tiering aipass_global_prompt.BACKUP-2026-06-09-S211.md snapshot.