Claude Code Credo Plugin - Marcel-Bich/marcel-bich-claude-marketplace GitHub Wiki
The mentor framework for Claude Code: a self-contained process layer that governs how a whole session runs - per-session modes, a work-item lifecycle with a hard Definition of Done, budget-aware autonomy, visual verification, and safety rules that travel into every subagent. It is the recommended default; get-shit-done is optional as an alternative task backend.
Credo (Latin: "I believe") is the mentor - it governs how a whole session runs, and the other tools slot in around it. It turns a loose set of good habits into an enforced, project-local workflow. Instead of relying on tribal knowledge that drifts between sessions, credo puts the process on disk: the working mode of a session, the status of every task, the requirements you approved, and the safety rules that must survive delegation.
It is opinionated by design and stands alone. No dependency on foreign skills - every rule lives inside the plugin. Only three touchpoints are external and all are documented honestly below: the limit plugin (recommended prerequisite for a few features), tmux (strongly recommended, needed by the self-compact and self-reload commands) and ntfy (optional push notifications).
Design principles:
- Self-contained - every rule lives inside credo; there is no dependency on foreign skills.
- Folder is the truth - an item's status is the folder its file lives in, not a field that can drift.
- Proof over claims - done means audited, and for a UI change visually verified in a real browser, not "the test passed".
- Rules travel - safety and quality rules are re-injected into every subagent so delegation cannot dilute them.
-
State survives compaction - requirements, handoffs, and items live on disk under
.credo/, not only in conversation.
claude plugin install credo@marcel-bich-claude-marketplaceOr within a Claude session:
/plugin install credo@marcel-bich-claude-marketplace
Note: Restart Claude after installation for the plugin to take effect.
After installing, run /credo:setup to initialize a project and, optionally, pre-fill config.
Strongly recommended: Start Claude Code inside tmux. /credo:self-compact and /credo:self-reload only work there, and /credo:self-restart only waits for an idle pane there. /credo:setup detects tmux and helps install it - see tmux (strongly recommended).
| Command | Description |
|---|---|
/credo:psalm |
Interactive guide to available topics and workflows |
/credo:setup |
Interactive setup wizard: install plugins, sync instructions, init project, choose a model preset, detect tmux and help install it (strongly recommended) |
/credo:migrate |
Migrate an existing repo into the .credo/ structure (one-time onboarding) |
/credo:project |
Pin which repo credo targets (hub-aware), or show the resolved target |
/credo:session-init |
Load the main-agent delegation-first workflow instructions |
/credo:session-active |
Set the session mode to active |
/credo:session-passive |
Set the session mode to passive |
/credo:session-autonomous |
Set the session mode to autonomous |
/credo:role-task |
Set this session's default role to task/build (owns implementing GO items incl. commits/push per dogma) |
/credo:role-plan |
Set this session's default role to plan/clarify (owns clarifying 1_clarify items, no commits/push) |
/credo:role-clear |
Clear this session's default role (back to no role; the agent does everything) |
/credo:sandbox-promote |
Promote an accepted sandbox artifact from .credo/sandbox-tmp/ to .credo/sandbox/
|
/credo:explain |
Explain something in depth (what/why/example/consequences) |
/credo:optimize |
Run the opt-in optimisation audit for this repo (read-only scan, findings offered one by one) |
/credo:disable |
Disable credo for this directory (silence onboarding and the [credo] line here, reversible) |
/credo:enable |
Enable credo for this directory (opt in; overrides a previous decline) |
/credo:self-restart |
Restart this session and resume exactly the same session in the same profile (e.g. to load plugin updates); check (dry run), run --user-confirmed / run --announce 300 (autonomous only) [--update], both only with --no-background-work after checking that no own background subagent or shell still runs, cancel, status
|
/credo:self-reload |
After a plugin update, the cheap first try: type /reload-plugins and /reload-skills into this session's own tmux pane once it is idle, then . to wake it (60 s fallback re-send); the woken turn checks whether the reload was enough, else /credo:self-restart --update (cc-up); check, run --auto (autonomous only) / run --user-confirmed (after an Ask yes) [--update], cancel, status; no background work of any kind blocks it |
/credo:self-compact |
After a green compact-plus report, type the real /compact into this session's own tmux pane once it is idle with an empty input field; check (dry run), run --auto (autonomous only) / run --user-confirmed (after an Ask yes), cancel, status; no background work of any kind blocks it (subagents, shells, scripts, monitors survive /compact); afterwards the session wakes itself with .
|
/credo:session-move |
Move sessions (caption or id) from one profile (CLAUDE_CONFIG_DIR) to another: dry-run plan (detects shared symlinks vs separate profiles per artifact), copy + verify, the user tests the resume in the target, then cleanup-script --user-confirmed writes a literal-path script the user runs; class C (only on the user's explicit invocation, from a new session; refuses live and current sessions; the agent never deletes) |
/credo:peer-lan |
Start, stop, or check the LAN peer relay (cross-machine peer messaging, no cloud); also guided setup, network binding, pairing status and the local trusted-peers list (trust list / add / remove) |
Skills and hooks are auto-discovered by Claude Code from the skills/ and hooks/ directories, so only the commands are declared in the manifest.
Every session runs in exactly one of three modes. The mode is per session, stored on disk keyed by the session id (under ~/.claude/credo/session-modes/, overridable via CREDO_SESSION_MODES_DIR), so it survives compaction, new sessions, and subagents. A UserPromptSubmit hook re-injects a one-line reminder of the active mode on every prompt and names the matching skill to load, so the mode can never be silently forgotten. The hook is failure-safe: any problem means exit 0 with no output, never a blocked prompt.
A second UserPromptSubmit hook (credo-datetime-inject.sh) injects the current local date and time on every prompt, independent of the mode and with no dependency on the limit plugin, so the agent is date/time-aware and can sense a large gap since the last prompt. The same hook also refreshes the clock on PostToolUse (throttled and delta-guarded), so during long autonomous runs the time stays fresh instead of freezing at the last prompt. On that basis the session skills add three mode-awareness behaviors: when no mode is set the agent proposes a fitting presence mode via the Ask tool (never silently, and autonomous is never proposed or set automatically; when the mode is not even determinable, for example inside a subagent, it neither proposes nor asks), and on opt-in it also pins the session's credo project target (offering the current repo, or asking for the target when the cwd is a launch hub); an autonomous run is never interrupted by a mode-change question, even if the user keeps prompting (a switch happens only on an explicit request or command); and the agent names the active mode in its output from time to time, especially after a long gap. In the presence modes the agent also clarifies one item at a time - each item gets its own Ask round rather than a multi-item dump, and independent questions may share a round.
A third UserPromptSubmit hook (credo-skill-nudge.sh) re-surfaces a single low-cadence self-assess reminder, because the SessionStart knowledge list ages out over a long session and the credo skills get underused. It never forces a skill: the agent is asked to judge by effort and risk and actively use the fitting credo skill (diag / verify / audit / items / requirements-verbatim) on non-trivial or complex work, and skip it on small or trivial changes. It fires in all credo modes. Toggle with CREDO_SKILL_NUDGE (default true) and set the cadence with CREDO_SKILL_NUDGE_EVERY (default 5); the fire slot is offset by half the window from credo-attended-reminder.sh so the two reminders never stack in the same turn.
A SessionStart hook (credo-session-start.sh) makes each session credo-aware, driven by the same on-disk, session-keyed state so it survives compaction. It has two separate jobs. First, a one-time activation: while the session has made no credo decision yet, and only on a human-present (re)start (source is startup or clear), it asks via the Ask tool whether to use the credo workflow; yes runs /credo:session-init, no records a declined marker (under ~/.claude/credo/session-decisions/, overridable via CREDO_SESSION_DECISIONS_DIR) so it never asks again. It never asks on compact, resume, or fork, nor while a full-autonomy run is active for that same session (its per-session flag ~/.claude/credo/autonomy/<session_id>/active), so an autonomous session is never blocked by an unanswerable prompt. Autonomy state is keyed by session_id, so an autonomous run in one session never affects another session. Second, a knowledge re-feed: once credo is active for the session (a mode is set, or the decision is accepted), it re-injects the full credo command and skill list on every start - including after a compact, when the model context is gone - tagged by execution class so it is clear which commands the agent may run itself, which need the user, and which it must never trigger autonomously (/credo:setup, /credo:migrate, /credo:session-autonomous). The activation ask can be turned off on its own with CREDO_SESSION_START_ASK=false, the whole hook with CREDO_SESSION_START_INJECT=false; and when the task backend is gsd the workflow text stays silent, since GSD is then the task system rather than credo. Third, it always appends a compact user-shorthand legend (see Chat Shorthands), in every state. Like the other hooks it is failure-safe: any problem means exit 0 with no output.
-
active (
/credo:session-active) - intensive live collaboration with the user at the keyboard. Progress is logged via the limit thresholds and compact-plus, open GO items are picked up alongside, clarifications happen during subagent waits. No keep-alive. -
passive (
/credo:session-passive) - the agent carries most of the work while the user is reachable only for clarifications. Every item is pushed toward a full GO; only genuinely ambiguous items go back to the user. No keep-alive. -
autonomous (
/credo:session-autonomous) - approved GO items are worked unattended. Keep-alive is hook-enforced: a registeredStophook (credo-autonomy-keepalive.sh) blocks a stop when autonomy is active and no self-wake is scheduled, and instructs the agent to call ScheduleWakeup (and mark it); a registeredUserPromptSubmithook turns autonomy off on any real user message; a registeredNotificationhook (credo-autonomy-permission-notify.sh, matcherpermission_prompt) sends one high-priority ntfy when a permission prompt appears in an autonomous session, because nobody is at the keyboard to answer it. This is a nudge, not a guarantee of infinite wakefulness (staying awake still relies on the agent then scheduling the wake), and it is loop-safe (at most one forced continuation per stop via thestop_hook_activeguard) and completely inert outside autonomous mode. Budget caps are enforced, ntfy sends immediate come-to-PC pushes (questions, blockers, completion) plus a mandatory content-rich progress digest on a fixed interval, and progress is secured via compact-plus. Near a weekly-limit reset that falls on the same local calendar day the run pauses across the reset via chained wake-ups and resumes on the fresh budget rather than stopping; at the end of a run the machine is only powered down if you opted in at setup (see below).
Each command sets the mode and loads its skill. The three session skills share one canonical common core (defined in the session-active skill) and layer their mode-specific rules on top.
Orthogonal to the mode, a session can carry a persistent default role that scopes which part of the item lifecycle it owns. Like the mode, the role is stored on disk keyed by the session id, so it survives compaction and new prompts.
-
plan/clarify (
/credo:role-plan) - owns clarifying1_clarifyitems; it does not commit or push. -
task/build (
/credo:role-task) - owns implementing GO items, including commits and push per dogma. -
none (
/credo:role-clear) - clears the role, back to no role, so the agent does everything.
Entering autonomous mode needs no credo-specific line in your global ~/.claude/CLAUDE.md. Two fail-safe mechanisms bootstrap it, and neither turns autonomy on by itself: the session-autonomous skill auto-triggers on an unambiguous full-autonomy or AFK-handoff grant (it recognizes both English and German phrasings) and confirms first when the grant is vague - a loose "keep going" or "carry on" is not such a grant; and session-mode-inject.sh adds one informational hint line when no mode is set, pointing at /credo:session-autonomous and the active/passive commands, without setting any flag or running any command (toggle with CREDO_AUTONOMY_BOOTSTRAP, default true). Net effect: a user who never asks for autonomy is never made autonomous, and the host global CLAUDE.md needs no credo-specific line.
credo teaches the agent a few short chat shorthands, so you can type them without adding anything to your own CLAUDE.md - a plain plugin update is enough. The SessionStart hook injects a small legend on every start (startup, resume, clear, compact, fork), so it survives compaction. It is pure user-intent parsing, not workflow: it applies in every directory - credo active or not, launch hubs, directories without .credo/, directories silenced via /credo:disable, and the gsd backend. Each shorthand refers to what precedes it and has a general meaning first, plus a credo-item mapping when an item is named.
| Shorthand | Meaning |
|---|---|
dd |
Done. <thing> dd = that thing is done; bare dd = the last discussed or requested thing is done; cc-up dd = the update is done. On a single Definition of Done point, dd ticks only that point, never the whole item. For a credo item (#123 dd) the agent runs the normal Definition of Done gate (audit, plus verify for ui: true) and on a pass moves it with credo-item-move.sh 123 done. The shorthand is your statement, never a gate bypass: if the gate fails, the agent reports instead of moving. |
vf |
Verified or verify, by context. In a manual test round where you were asked to check something, vf means you checked it and it passes. The scope is exactly what it refers to: on a single Definition of Done point only that point is ticked as verified and the item stays where it is; only when the whole item was under test (#123 vf) does it move to 3_verified/ via credo-item-move.sh 123 verified --user-authorized (main agent only). Otherwise it is an instruction to verify for real with runtime proof, not a code review (in credo: the verify skill, via subagents). If it is unclear which is meant, the agent asks briefly. |
cf |
Start or continue a clarify round: structured questions until the open points are resolved. In credo: the 1_clarify items, one item per Ask round, or the named one (#57 cf). |
go / bk / pk / ar
|
Item moves, valid only right after an item ref (#57 go); bare they are ordinary words. #N go = your GO approval: the agent adds a (GO: <your words>) line to the item History and moves it to 2_go if the GO entry gate (G1-G6) passes, otherwise reports why not. #N bk = block it: the agent asks for the concrete blocker if you did not name one (blocked_by is mandatory) and moves it to 3_blocked. #N pk = park on hold, #N pk future = park for later. #N ar = archive. All moves go through credo-item-move.sh. |
??? |
Explain the thing it follows (or the last thing, when alone) in depth: What / Why / Example / Consequences. Same behavior as /credo:explain. |
cc-up |
You fully updated Claude Code (plugins and marketplaces fetched and installed, /reload-plugins, full quit and restart, possibly resumed). The running state is current; the agent takes this at face value and never asks for update steps or proof. Also valid when mentioned in passing. |
cm |
Commit, following the repo's commit rules. No push. |
ph |
Commit and push, following the repo's rules (push only where they allow it). |
exclude / excluded
|
Always the local .git/info/exclude, never .gitignore. Only ignore / ignored / gitignore means .gitignore. |
#N vs §cct_N
|
#N only for real items (credo items, issues, PRs, tickets). Claude's harness tasks and any other numbering are §cct_N (cct = Claude Code task, e.g. §cct_2), so the two never get confused. §cct_2 dd = harness task 2 done. |
| Test/question letters | Every manual test and every question to the user gets a letter from one continuous sequence shared by both (A..Z across replies, wrap to A after Z), under a visible heading ### 🧪 B) <topic> (test, numbered steps, 1-2 items per round) or ### ❓ Y) <topic> (question). Answer with B vf, B2 vf (step 2 of B) or Y: .... Each reply ends with the open letters in bold (**Open for testing: C, D** · **Open questions: Y**); the next free letter survives a compact via the handoff. |
Turn off only the legend with CREDO_SESSION_START_SHORTHANDS=false; CREDO_SESSION_START_INJECT=false silences the whole hook, legend included.
scripts/credo-init.sh creates a per-project .credo/ tree in the target repo (idempotent) and adds the git-exclude lines so .credo/** is not committed by default (except RULES.md, see below). The layout:
.credo/
docs/ stable "how we work here" conventions
screenshots/ visual-verify evidence: <task>-<viewport>-<YYYY-MM-DD>.png (a PostToolUse hook files screenshots here automatically, even from a hub and for subagents)
items/
1_todo/{1_clarify,2_go,3_blocked}
2_done/
3_verified/ human-authorized; agent files here only on your explicit instruction
4_archived/
parked/{hold,future}
process/
requirements/ append-only verbatim log
handoffs/ rolling HANDOFF.md plus handoffs/archive/
reports/ diag / audit / verification reports
checklists/ auto-generated cross-cutting checklists
generated-skills.md register of skills built from recurring workflows
skill-candidates.md recurring-workflow candidates seen but not yet built
config per-project config (YAML)
id-counter deterministic integer counter
RULES.md per-repo special rules (grants); versioned by default
.credo/** is deliberately kept out of git, with ONE exception: RULES.md (per-repo special rules) is versioned by default, because those rules are meant to travel with the repo. Everything else's persistence across a compact is the files on disk plus your normal backups, not commits.
Opt-in versioning (per project). The default (all of .credo/** excluded except RULES.md) is right for solo or private work. If you want the items and process visible in the team's history, run credo-init.sh with CREDO_VERSION_TRACKED=1: it then versions .credo/** in the repo except the per-project config and the screenshots/, which stay local always. The exclude entries are kept in a marker-delimited managed block in .git/info/exclude, so re-running switches the mode cleanly in either direction (drop the variable to go back to fully unversioned). This is a deliberate per-project decision; the default is unversioned.
To onboard an existing repository into this structure, run /credo:migrate - it sets up .credo/ and walks the repo through the migration procedure once.
credo resolves the target .credo/ in this order: the CREDO_DIR environment variable, then a session pin set with /credo:project <path>, then the current repo (git top-level of the shell cwd). This matters when you launch work from a shared hub directory instead of from inside the repo you are editing: pin the real target with /credo:project <path> and the item tree, config, task backend, and the per-repo RULES.md all resolve to that repo, wherever the shell sits.
A directory can be marked as a hub with hub: true in its .credo/config. credo never auto-targets a hub's own .credo/ - it always requires an explicit target (a pin or CREDO_DIR), so a launch hub that also has its own credo project is never silently used for work that belongs to another repo. To prevent silent mistakes, credo-init refuses to create a new .credo/ at a hub or an ambiguous location and asks for the target instead; /credo:setup handles this with a short question and writes the hub: true marker for you when you confirm - you never edit config by hand.
Config is YAML, merged lowest to highest:
builtin (templates/config.default.yaml) < global (~/.claude/credo/config) < profile ($CLAUDE_CONFIG_DIR/credo/config) < project (.credo/config)
The builtin template ships universal, safe-for-everyone defaults: the verify viewports (320, 768, 1440), the timing windows, the compact thresholds (80, 92), the budget schedule, and the wakeup offsets. On first need the global config is created from this template. Personal and environment-specific fields (ntfy topic, commit-identity hint, WSL reachability, living-docs list) are intentionally left empty and are filled just-in-time by the skill that needs them, with permission per change. /credo:setup is an optional way to pre-initialize this.
The profile layer sits between global and project: $CLAUDE_CONFIG_DIR/credo/config (for example ~/.claude-private/credo/config) lets a second Claude Code profile override the shared global per key, while every key it does not set still falls back to global. It is optional and never auto-created; for the default profile it equals global and is skipped. Session state (modes, decisions, project pins) and the autonomy flags likewise follow the active profile, so two profiles run side by side without sharing state. A minimal example - only the keys you want to change:
budget:
weekly_pause:
enabled: falsecredo-config.sh paths lists the layers for the active profile; credo-config.sh source <key> names the layer (builtin / global / profile / project) and the file that supplies a key's merged value, e.g. credo-config.sh source budget.schedule -> global: ~/.claude/credo/config. On the default profile (~/.claude, CLAUDE_CONFIG_DIR unset) the global config is the profile config; there is no separate profile layer.
Item ids come from scripts/credo-id-next.sh. The counter file holds the last id given out; allocation is atomic under flock: read the counter, scan the items tree, take max(counter, highest existing id) + 1, write it back, print it. The counter, not the folder, decides the number - deleting the highest item never lowers the next id, so a deleted id is never reused. The folder scan is a safety floor only: it lifts a counter that fell behind the items on disk (branch merge, clone, backup restore, sync) so a stale or rolled-back counter can never reissue a used id, and prints a drift warning to stderr when it does. stdout carries only the id. Always take an id from the helper; never hand-pick one.
A work item is one Markdown file (templates/item.template.md). Its frontmatter is lean and mandatory: id, title, created, type (bug | optimization | feature | question | chore), and ui (true means a visual verify is part of the Definition of Done). The optional audit: full forces the full audit tier (see Audit depth). There is no status field, because the folder is the status.
The lifecycle, moving the file with scripts/credo-item-move.sh:
-
clarify (
items/1_todo/1_clarify/) - requirement captured verbatim, success criteria drafted. -
go (
items/1_todo/2_go/) - GO given; ready to build. A human-owned item (from the user's own words;clarify_owner: humanor missing) gets its GO only from the user - the move helper refuses it otherwise. An agent-owned item (clarify_owner: agent,parent: <id>- slices, follow-ups, build questions, audit findings) may get an agent GO under the agent decision rule (see below). On entry an item becomes agent-owned (go=go: never self-demoted for size, UI, or "not sure it is verifiable"). A stale-looking body is likewise never a reason to self-skip or demote a2_goitem (body-freshness invariant). The one sanctioned way back is the Named-Decision-Test: a genuine user-only decision surfacing mid-build sends the item to1_clarifymarked URGENT - never "too big / too hard". -
blocked (
items/1_todo/3_blocked/) - GO'd but hard-blocked by another, unbuilt credo item (structuredblocked_by/blocksrelations). A deterministic sweep (credo-unblock-sweep.sh, run on every move into2_done/3_verifiedand at every SessionStart) returns the item to its origin - theunblock_totarget,goorclarify, recorded when it was blocked (legacy items without the field default togo) - once every blocker is in2_doneor3_verified;4_archiveddoes not count as delivered. Items whose blocker is not heading toward done (blocker still in1_clarify, archived, or itself blocked) are surfaced as a nudge, never auto-moved. Distinct fromparked/hold, which is for an external dependency. "Too big / too hard" is never a block. -
done (
items/2_done/) - built and wired, and the Definition of Done gate has passed. A move to done (or verified / archived) also cleans up merged and clean worktrees per DOGMA-PERMISSIONS (see "Worktrees for every code track"). -
verified (
items/3_verified/) - human-authorized. The agent never self-verifies, but may perform the mechanical move on your explicit instruction (credo-item-move.sh <id> verified --user-authorized). Rawmv/git mvof item files is blocked and redirected to the move helper.
Parked work lives under items/parked/{hold,future}; abandoned work under items/4_archived/.
The default intention is to build everything as well as at all possible; how much work it is never counts against an item (feasible = GO). Who decides depends on the optional frontmatter clarify_owner (missing = human, fail-safe):
-
Human-owned items (
clarify_owner: humanor missing) are always clarified with the user. The agent recommends (Recommended option first) and the user decides; only the user gives the GO.credo-item-move.sh gorefuses such an item unless its History carries a(GO: <user quote>)line or the main agent passes--user-authorizedon the user's explicit GO, from every source folder. -
Agent-owned items (
clarify_owner: agent, items created by an agent withparent: <id>, and everything in2_go): Uncritical questions are decided by the plan agent, or, when no plan agent peer is known, by the executing agent in a temporary pseudo plan role, under the decision rule of the active model preset (itsmainagent-prompt, see Model presets). An agent-owned clarify item may move to2_gowith a logged(GO: agent decision, <reason>)line; the older(GO: agent per SOTA rule, <reason>)marker is still accepted. A child item (parent:) gets an agent GO only while its parent is GO'd, and the gate counts an item as agent-owned only when its origin is recorded (the owner flip written by the move helper, or creation as an agent item). Every decision is logged in the item History and named in the next reply or report, so the user can veto it. - Always the user's call, also on agent-owned items: anything infeasible or really not good, the user's taste or preference, deleting user data, installs, money, the hard safety rules, and any answer that would change or narrow the verbatim requirement.
- By mode: interactive modes decide the uncritical questions and ask the rest via the Ask tool; autonomous mode decides them and parks the rest for the end-of-run report.
- Every move back into
1_clarifysets the item to human-owned again (--keep-ownerkeeps it for an agent-internal re-clarify), and a GO written before such a send-back no longer counts.
Read-only helpers let any renderer (a terminal, a status line, a Claude Code mod, another harness) show credo state without knowing the layout:
-
scripts/credo-item-counts.sh [--json]- the item count per status folder of the resolved project (keysclarify go blocked done verified archived hold future; exit 4 when no credo project resolves). -
scripts/credo-item-list.sh [--json] [--per N]- per status folder the total plus the newest N items (default 15) as id and title (frontmattertitle:, else the slug); same resolution and exit codes. -
scripts/credo-session-status.sh [--json] [session_id]- one session's mode, role and autonomy state (running, paused, next scheduled wake) from the per-session state files; the session id comes from the argument,CREDO_SESSION_IDorCLAUDE_CODE_SESSION_ID(exit 2 when none resolves).
The project is CREDO_DIR when set, otherwise credo-config.sh resolve-project (session pin, hub-aware).
An item may move to 2_done/ only when all of these hold:
- the success criteria are observably met and the new code is actually wired in (a caller reaches it),
- a dedicated audit subagent (not the builder) has reviewed the work against its stated requirement and Definition of Done and returned a pass,
- for
ui: true, a visual verify has driven the real surface in a browser across the configured viewports and captured screenshot evidence under.credo/screenshots/, - docs are updated in the same change, tool-aware: prefer
/dogma:docs-updatewhen dogma is installed (canonical README plus wiki sync), otherwise a best-effort manual update; the scope explicitly includes the project wiki, a separate repo, not just files in the same commit.
The audit gate always runs, by a dedicated subagent that is not the builder; only its depth follows risk. full (every audit check, current verify evidence) applies to ui: true items, security-relevant work (permissions, allow/block hooks, secrets, deletion, installs), writes outside the repo, data migration, large scope (guide value: more than ~10 files or a new component), items with the optional frontmatter audit: full, and anything in doubt. lean applies to everything else: the diff against each DoD point, wiring of new code, docs current for the change, and stale claims inside the item - still with severity-ranked findings and a verdict. The main agent picks the tier and the report states it with a one-line reason. There is no audit: lean override, so a risky item is never downgraded. Builder and audit run dogma's relevant test stage when the repo defines one; the full suite runs where dogma places it (for example once per release bundle), not per item. Several lean items may share one audit subagent with one verdict each; full items are always audited singly.
The gate leaves nothing silently dropped: every finding at every severity, including MINOR and NIT, must be explicitly dispositioned - fixed now, deferred as a tracked item with a recorded reason, or a conscious wontfix (in autonomous mode a documented default) - and a clean code fix always takes priority over a documentation workaround. Acting on findings is mode-aware: in the presence modes (active and passive) the agent explains each finding and recommends the fix, while in autonomous mode it fixes inline by default without asking.
credo has two layers, and only one of them is a task system:
- Operating layer (always on) - session modes, WSL environment awareness, budget and limit awareness, subagent orchestration and priming, and safety that travels into every subagent. This layer is orthogonal: it sits on top of whatever task system you use.
-
Task model (
.credo/items/plus a hard Definition of Done) - this is an alternative to Get-Shit-Done, not a layer on top of it. Use one task system per project.
credo is the recommended default and is self-contained for day-to-day work: items, bug fixes, incremental features, each gated by an observable Definition of Done. credo deliberately has no large up-front project bootstrap or roadmap; it stays flat and reactive. GSD is optional for heavy up-front planning (PROJECT -> ROADMAP -> milestones -> phases -> plans), or if you already prefer the original GSD flow.
If you run GSD as your task system, set the task backend to gsd so credo's own item features stand down - that avoids two competing sources of truth (.credo/ items vs GSD's .planning/). The backend is config-driven: it lives in .credo/config as task_backend (default credo), and /credo:setup writes gsd there for you when you pick GSD - you do not have to set anything by hand. The CREDO_TASK_BACKEND environment variable overrides the config if you ever need it. Any value other than gsd (including credo, none, or unset) keeps credo's items active; the operating layer above stays on regardless of the value. Technically the two do not collide: their hooks are disjoint and their directories are separate. The one point of friction is the status line - a single slot - so in a combined credo + GSD + limit setup, keep the limit status line and let GSD skip installing its own.
Auto-discovered under skills/. Each auto-triggers when it applies, including inside subagents.
-
audit - read-only quality gate; reviews already-built work against its requirement and Definition of Done before it may move to
2_done/. Proposes a severity-ranked decision (BLOCKER / MAJOR / MINOR / NIT), never a fix. - diag - read-only root-cause diagnosis for a symptom; establishes the mechanism at file:line before any fix. The fix is a separate, GO-gated step.
-
verify - visual verification as the Definition of Done for any change with a runtime surface; proves behavior in a real browser with computed layout. Per-layer verification state is honest and 4-valued (
not-started,present,wired-but-behavior-unverified,exercised); a verify that surfaces a defect is a failed verify - a defect outcome, not a progress state. A down surface may be brought up or restarted autonomously ONLY when the target is positively verified local (a process on this machine, not a deployed/remote/shared environment - judged by where it runs, not by the git branch), viaverify.local_bringup; otherwise the visual verify defers as human-only. - pr-vetting - rigorous multi-subagent vetting of external pull requests across technical, security, value/fit, contributor reputation, and license/compliance dimensions, with automated mass-PR / product-injection detection; merges findings into one decision-ready report while the merge/close decision stays with the maintainer.
- issue-triage - selection-first GitHub issue triage: shortlist and prioritize before deep-triaging chosen issues via parallel subagents, then recommend close/fix/keep/needs-info for the owner to approve before any action.
- items - the work-item model where the folder is the status truth, gated by the Definition of Done.
-
sandbox - WRITE pre-work for a
1_clarifyitem blocked by a knowledge gap (a missing measurement, a mockup, or a feasibility proof), done under.credo/sandbox-tmp/without touching production code and without git, so the task/build agent is never disturbed. An accepted artifact is promoted to.credo/sandbox/via/credo:sandbox-promote. -
rules - per-repo special rules in
.credo/RULES.md: project-local grants that widen credo's autonomy for that one repo (for example "restarting local services is always allowed without asking" in a debug-only repo). Loaded and honored every session and inside subagents, versioned so they travel with the repo, resolved via the project layer (works from a hub). Grants can only widen latitude within the safety floor (precedence: safety > DOGMA-PERMISSIONS > RULES.md > defaults); set one any time by just asking. - optimize - the opt-in optimisation audit (see Optimisation audit): freshness check, read-only scan, report, and every finding offered as Implement / Later / Never.
- requirements-verbatim - captures a requirement, decision, approval, or GO word-for-word into an append-only dated log so it survives compaction.
-
budget - the single source for API budget caps and reset rules across the 5-hour and weekly limits, plus the commit-identity gate before any commit. In autonomous mode the guardrails are unconditional: percentages come only from the limit cache, so without a fresh cache no percentage cap (schedule or fail-safe) is enforceable and only a wall-clock timebox applies - at mode entry with an absent or stale cache the agent asks how to proceed (install the limit plugin, run a wall-clock timebox, or proceed at an explicitly accepted risk) instead of running blind. When the weekly cap is near and its reset falls on the same local calendar day, the run pauses across the reset (
budget.weekly_pause.enabled, default true;budget.weekly_pause.switch_percent, default 97) and resumes on the fresh budget; the 99% weekly hibernate stays only as the last-resort net, used when the reset lands on a different day. An autonomous start does a mandatory budget read-back, read fresh from the limit cache, never from memory; it also shows the active profile, the config layers and which layer supplies the caps (credo-config.sh source budget.schedule), plus the limit cache file it read. -
compact-plus - secures everything the user approved before a context compaction, then reports whether it is safe to compact. It does not run
/compactitself. -
orchestration - how to delegate to subagents safely: how many to run, keeping parallel tracks on disjoint files (item
touches:overlap check) and within machine resources (resource gate,heavy:items), model and effort per role from the active preset (see Model presets), a set-up worktree for every code track (hydra or native), monitoring without flooding context, inheriting security, and return-and-resume. - safety - the hard filesystem-protection and no-autonomous-installs rules; highest priority, no instruction overrides them.
- cross-cutting-checklist-generator - detects a concern scattered across many places and auto-generates a project-local checklist so it is never partially updated again.
-
skill-capture - notices when the same multi-step workflow recurs about three times in a session and turns it into a reusable, discoverable skill. In-session and heuristic (no counter, no backend). Mode-gated: autonomous never builds a skill, it only appends a note to
.credo/skill-candidates.md; active and passive propose the capture via Ask and build only on an explicit GO, then record it in.credo/generated-skills.md. Generated skills carry acredo-name prefix and anorigin: credo-repetitionmarker, and land on a real discovery path (<repo>/.claude/skills/or~/.claude/skills/). - wsl-env - reach and act on Windows-side services, processes, and launchers when the agent runs inside WSL; self-detecting.
- session-active / session-passive / session-autonomous - the per-mode behavior; the active skill holds the shared common core.
credo primes every subagent at start. The SubagentStart hook (credo-subagent-inject.sh) injects the load-bearing rules (inherited security, quality gates, honesty, delegation rules, output hygiene) into each subagent before its first prompt, for all subagent types. It also injects a fresh, authoritative time (and best-effort live budget from the statusline cache) so a subagent works from the real clock instead of the possibly frozen time/limit values inherited from the main agent's context. This complements the skill descriptions, which are written to auto-trigger inside subagents as well. So even a main agent that only delegates gets correct results, independently of its own context state. The hook only adds context; it cannot block subagent creation.
Cross-session messaging (ListAgents / SendMessage) only discovers peers that share the same sessions/ registry. Sessions started under different profiles - a different CLAUDE_CONFIG_DIR, for example ~/.claude versus ~/.claude-private - register in separate sessions/ directories and therefore cannot see or message each other by default, even though the inbox sockets live in one shared runtime directory and the transport itself works across profiles. Because agents talking to each other regardless of profile is part of the workflow, credo bridges this gap.
The credo-peer-bridge.sh hook (wired into SessionStart, UserPromptSubmit, and PostToolUse) autodiscovers sibling profiles (~/.claude* directories that own a sessions/ registry) and mirrors each live peer descriptor into the current profile's sessions/ directory as a regular file tagged with an ownership marker (credoPeerBridge). That makes cross-profile peers appear in ListAgents and become reachable via SendMessage. Regular-file copies are used deliberately: the discovery reader enumerates regular files only and does not follow symlinks.
-
Resume stays clean.
/resumereads transcripts underprojects/, neversessions/. A mirrored descriptor has no local transcript, so it never appears in the resume picker. Work and private history stay fully separate. -
Safe by construction. The hook only ever removes files that carry its own marker (plus leftover legacy symlinks and its own temp files). A real local descriptor is an unmarked regular file and is never touched or overwritten - even if the OS later reuses a pid, because the CLI's overwrite drops the marker along with it. It never removes directories and never touches anything outside
<config>/sessions/, and it always exits 0 so it cannot surface as a hook error. - Freshness. Live peers are mirrored on session start and refreshed during activity; entries whose source session has ended (its pid is gone) are pruned on the next run.
-
Disable with
CREDO_PEER_BRIDGE=0. - Caveat. The descriptor format is internal to Claude Code and undocumented, so a future version may change it. The bridge is fail-safe: if that happens, peers simply stop appearing and nothing is corrupted.
The cross-profile bridge only reaches sessions on the same machine. /credo:peer-lan (scripts/credo-peer-lan.py) extends the same peer model to sessions on DIFFERENT machines in one trusted network, without any cloud. A daemon on each machine publishes its local sessions to its configured peers over TCP and mirrors remote sessions into the local registry, so they appear in ListAgents and are reachable via SendMessage. One relay per machine serves the Claude Code profiles chosen at setup (default: all profiles of that machine; change it later with credo-peer-lan.py profiles): every served profile's sessions/ gets the mirrors, the roster names each session's profile, a session in any served profile starts the relay, and a pairing reaches every served profile while a trusted peer applies only in the profile where it was granted (trust add in that profile). It is off until a config exists (/credo:peer-lan init <other-ip>), fail-closed to bound networks and an allowlist, pairs each pair of relays with per-peer keys on first link, and leaves every receiving session's own consent gate in place. Trusted peers are an optional local opt-in on top (see Peer message etiquette). Full setup and security model: commands/peer-lan.md.
To start over cleanly ("disconnect all devices"), credo-peer-lan.py disconnect-all removes every pairing, pending repair, trust grant, stored peer address and mirrored remote session in every served profile, then restarts the relay if it was running. It first lists exactly what it will remove and asks for confirmation (--dry-run only lists, --yes skips the prompt, no terminal and no --yes refuses). The own identity, bound networks, the profile choice and the listen settings stay, so pairing again works like the first time. --full also removes the Windows pieces the setup created under WSL (port proxy, firewall rule, scheduled task). Run it on both machines.
Two robustness rules of the relay:
- Delivery only to live descriptors. After a crash or resume the registry can hold several descriptors of one session (a dead process with an old socket path next to the live one). The relay delivers only to descriptors whose process is alive (start time and pid namespace match), newest first, tries the next live one when an inject fails before any bytes were sent, never retries after a partial send (no double delivery), and logs the chosen descriptor. With no live descriptor it logs a clear drop reason. Descriptor files are never modified.
-
Windows tools under WSL without fixed paths. If a WSL session's PATH has lost the Windows directories (for example after a WSL crash), the relay and its autostart hook still find
powershell.exeandcmd.exe. Under WSL only, they searchWindows/System32(case-insensitive) on every mounted Windows drive listed in/proc/mountsand below the automount root from/etc/wsl.conf, so any mount root and drive letter works, and the system drive is preferred. If the tool cannot be found at all, the reason for the disabled LAN side names it and the PATH fix.
A peer that is missing from ListAgents is not necessarily down. ListAgents only reads the current profile's registry. A Codex session appears there only as a LAN relay mirror (it disappears while the Codex relay or the credo relay is down), a session of another profile only through the peer bridge, and a session whose descriptor is gone not at all - while the process may keep running in its tmux pane. credo's rule is therefore to never report a peer as down only because ListAgents does not show it, and to run the peer check first.
scripts/credo-peer-check.py (--json for machine-readable output, --no-lan-check to skip the relay reachability probe) is read-only. It sends no message, opens no inbox socket and writes no file. It lists every channel side by side:
- Claude sessions from the profile registries
- Claude inbox sockets in both candidate socket directories (the one under
XDG_RUNTIME_DIRand the/tmpfallback), counted only while they are really bound - LAN relay mirrors (a Codex mirror is shown as kind codex)
- the Codex relay (its session list, whether its port listens, the tail of its log)
- the credo LAN relay (daemon status and its
checkoutput) - tmux sessions (a pane that runs a known session is merged into that row)
Each row carries a kind (claude, codex, lan, tmux-only), how it can be reached (SendMessage, a2a, tmux only, none) and when it was last seen. Warnings come first and name the cause. They cover a LAN relay that is disabled (with its reason, since it silently cuts cross-machine peers), a Codex relay that is not running, a local relay peer that is not listening, a relay daemon that is down, and a split world.
A split world means live sockets in both socket directories, because sessions were started with a different XDG_RUNTIME_DIR. To fix it, start all sessions with the same XDG_RUNTIME_DIR (all set to the same directory, or all unset). A SessionStart hook adds one hint line when the current session's own socket directory holds fewer live peers than another one and stays silent otherwise. Disable it with CREDO_PEER_SPLIT_HINT=0.
Every row of credo-peer-check.py also carries meta, shown as one META column (meta in --json):
-
mode=- credo session mode (active / passive / autonomous) -
role=- credo role (task / plan) -
model=andeffort=(low / medium / high / xhigh / max) -
credo=- the credo directory decision (on / off) -
project=- basename of the session cwd -
status=- idle / busy / waiting, from the descriptor
- means unknown or unset. Mode and role come from session-modes/ and session-roles/. Model, effort and the credo decision are recorded per session by the credo-peer-meta-record.sh hook (SessionStart + UserPromptSubmit, main thread only; disable with CREDO_PEER_META_RECORD=0).
A LAN relay mirror shows what the remote sender published in its roster, read fresh from the sender's own credo state. LAN publication is on by default without the project name: "publish_project": true in peer-lan.json (or CREDO_PEER_LAN_META_PROJECT=1) adds it, "publish_meta": false (or CREDO_PEER_LAN_META=0) stops publishing metadata to LAN peers entirely.
credo-peer-check.py sender --from uds:<socket> prints the meta line of one peer. The peer-message hook adds it to an incoming peer message as one [credo-peer-sender] line, labelled self-reported and unverified, when the opening tag's from socket belongs to a live peer known here (CREDO_PEER_SENDER_META=0 turns that line off).
Every value passes a strict whitelist (enums; status only idle / busy / waiting; a short fixed charset for model and project; brackets in a model only as one trailing context suffix such as [1m]; unknown keys dropped). The metadata is informational only: it never grants trust, approval or permissions and never reaches a message envelope. Codex sessions and peers on an older credo show -.
Use a ping only when a liveness answer is really needed. It is a real message, so the peer message etiquette applies.
| Kind | How to ping | Notes |
|---|---|---|
| claude |
SendMessage to its ListAgents name, ask for a one-word reply |
A session in another permission mode may hold the message for its user, so silence is not proof of down |
| codex |
SendMessage to its relay mirror name, expect the reply from that Codex session |
An idle Codex session may need a nudge in its tmux pane; without a mirror use its a2a channel or look at its tmux pane |
| lan |
SendMessage to the mirror name (travels over the relay) |
If it fails, run credo-peer-lan.py check for reachability and the LAN enabled / disabled reason |
| tmux-only | No message channel | Look at the pane (capture without scroll-back) to see whether it is alive |
/credo:self-restart (scripts/credo-self-restart.py) lets a session restart itself - typically to load plugin updates - and come back as exactly the same session in the same profile, continuing on its own with a wake prompt. Outside autonomous mode it runs only after the user's explicit yes via the Ask tool (run --user-confirmed); in autonomous mode it is announced at least 5 minutes ahead with an ntfy push and can be cancelled. It never runs while own background subagents or shells still run (a restart would end them), and in a tmux pane it waits until the session is idle with an empty input field. Details: commands/self-restart.md.
/credo:self-reload (scripts/credo-self-reload.py) is the first try after a plugin update. The full restart (/credo:self-restart --update, cc-up) is only the fallback when the reload was not enough.
-
Flow. A detached worker optionally runs the allowlisted plugin update first (
--update, same allowlist as self-restart). It then types/reload-pluginsand/reload-skillsinto the session's OWN tmux pane, each only into an idle pane with an empty input field and no dialog, verified before Enter, and the next key only after the command'sReloadedresult line (or its timeout). The reload commands do not start a model turn, so it finally types.to wake the session. -
Fallback. A UserPromptSubmit hook consumes the wake file on the next prompt of the session (any prompt counts), which cancels the timer. When no new turn started within 60 s, the
.is sent again, but only while the pane is idle and the wake is still pending, at most 3 times. The helper's own.never pauses autonomous mode; a real message that arrives first is handled normally. -
cc-up only if needed. The woken turn gets a note with the loaded vs newest installed credo version. When the reload was not enough, the agent falls back to
/credo:self-restart --updateunder its owner rule. - Nothing in the background blocks it. Running subagents, background shells, scripts, monitors and other background services are ignored; they survive a reload.
-
Owner rule. Autonomous mode runs it without a question (
run --auto); interactive modes ask once via the Ask tool, thenrun --user-confirmed. It never runs at the same time as/credo:self-compact. -
tmux required. Outside tmux
checksays so; reload by hand or use/credo:self-restart.
Details: commands/self-reload.md.
/credo:self-compact (scripts/credo-self-compact.py) runs the real Claude Code /compact on the same session, to save tokens - only after a green compact-plus report (it refuses without the fresh rehydrate breadcrumb compact-plus leaves). It works only inside tmux: a detached worker types the /compact line into the session's OWN pane once the session is idle, the input field is empty and no dialog, Ask question, permission prompt or menu is open, and never retypes user input. Autonomous mode runs it automatically (run --auto); interactive modes ask once via the Ask tool, then run --user-confirmed. No background work of any kind blocks it (subagents, shells, scripts, monitors and other background services survive /compact). A classified dialog or permission prompt that blocks the pane for 2 minutes (also one raised by a background agent, which replaces the input box in the main pane) triggers one early ntfy push per blocked wait asking you to answer it (the generic "no input box" state, which may be a pane that is not Claude Code, never counts); the worker keeps waiting and continues by itself afterwards (the same applies to /credo:self-reload and the idle wait of /credo:self-restart).
After the compact the session wakes itself. A finished /compact does not start a model turn, so the worker waits for a deterministic signal: Claude Code fires SessionStart with source compact when the compaction is done, and the credo SessionStart hook then drops a compact-done marker, but only while a self-compact of that session is in flight. The worker then types . into the idle prompt to start the next turn, with the same 60 s fallback as /credo:self-reload. Without the signal in time it types . only into an idle pane (the woken agent checks whether the compact happened); otherwise it types nothing and sends an ntfy push. Details: commands/self-compact.md.
/credo:session-move (scripts/credo-session-move.py, skill session-move) moves one or more sessions, given by caption / custom title or full id, from one profile (CLAUDE_CONFIG_DIR, e.g. ~/.claude) to another (e.g. ~/.claude-other). Execution class C: only on the user's explicit invocation, never autonomously, and only from a new session that is not one of the moved ones. It refuses the current session and any live session: a Claude process whose argv names the id (e.g. --resume <id>), or a pid file sessions/<pid>.json naming the id - in the source, the target or any sibling .claude* profile dir - whose pid is alive, whatever the process is called (a dead pid is stale, a pid file older than the process start is pid reuse). Without /proc (e.g. macOS) it falls back to ps; when liveness cannot be determined at all, it refuses.
-
Captions resolve from
projects/<slug>/<id>/custom-title.json, else the newest custom-title record in the transcript - never from the stalesessions/*.jsonpid files. Ambiguous captions are refused; pass the id. -
Setup detection, not 1:1 copying. The
plan(dry run) shows the target layout (top-level symlinks shared with the source vs real entries) and plans each artifact that exists for the id: the transcript, theprojects/<slug>/<id>/dir (the slug follows the session cwd and can differ per session), and every entry whose name holds the full id (tasks, todos, session-env, file-history, credo / dogma per-session state, mode files, ...). Each item isCOPY,PRESENT(already identical),SHARED(the target path resolves into the source through a symlink: already there, never copied, never cleaned up),CONFLICT(the target holds something different: stop) orBLOCKED(a symlink or special file in the source, a target symlink to a third place, an entry directly at the profile root, or a leftover<file>.partfrom an interrupted copy: never followed, never written through, a.partis removed by the user). A session whose files contain symlinks (e.g. subagent files symlinked into another session's dir by an earlier manual move) cannot be moved with this command; the plan says why. Short-id names are listed for review only. Shared logs (e.g.credo/peer-lan.log), profile-global config andplugins/are never copied. -
Copy + verify. One source per explicit target path; each file is written to
<file>.part, fsynced and hard-linked into place, so nothing is overwritten and no target file is ever half written; no symlink followed, mode and mtime kept. Re-runningcopyafter an interruption completes it (identical files are skipped).verifyreads every file once on both sides (size, sha256, entry count) and, when green, records source and target size + sha256 per file in<target>/credo/session-move/<id>.json; refused sessions (live, current, conflict, blocked) get no manifest. -
Cleanup only by the user. After the user tested the resume in the target (
cd <cwd> && CLAUDE_CONFIG_DIR=<target> claude --resume <id>) and explicitly approved it,cleanup-script --user-confirmedwrites a sh script with literal paths only (newmktempdir under/tmp, 0700 / 0600). It refuses while the session is live in any profile other than the target (or liveness cannot be determined), when a manifest item is not part of the session's fresh plan, when the source changed since the verify, or withoutsha256sum/shasum. A source file whose target copy is missing, smaller or no longer starts with the verified content is left out (reported as KEPT). The script removes each file only while it still has the recorded checksum, is not a symlink, its target copy is a regular file and its directory still resolves (pwd -P) to the recorded physical directory, and directories only withrmdir. The user runs it with!; it is not removed automatically (rm -f -- '<dir>/cleanup.sh' && rmdir -- '<dir>'). The agent never deletes. - The report stays in chat: ids, slugs, every path, the
cdpath, the resume command (plus a launcher alias for that profile if the user has one), and the notes that profiles have separate auth / accounts and possibly launchers with different permission flags, and that project-local.credo/handoffs do not move. Details:commands/session-move.md,skills/session-move/SKILL.md.
Peer sessions tend to over-communicate: every ack, status note or handoff lands as a new turn, and the receiver often reacts right away (a reply, an immediate commit and push). credo-peer-message.sh only informs (the one optional exception is the strict trust guard below):
-
Receiver (UserPromptSubmit): when the prompt is a
<cross-session-message>, it injects the handling rule.[urgent](or untagged but asking a question or needing a decision) is handled now;[info]and other untagged messages get no reply and no immediate action, and resulting.credo/item changes are batched into the next natural commit (idle time, next release, before a compact). -
Sender (PreToolUse
SendMessage): reminds the agent to start the message with[info]or[urgent], bundle points, never send pure acks, and end with "No reply needed" when no answer is needed. -
Autonomy: a peer message never pauses autonomy (
credo-autonomy-clear.shexempts it); only the user's own messages do. -
Trusted peers (LAN relay): Trust is local and per receiving machine. Only the user of that machine can declare, on that machine, that tasks from one named session on one PAIRED peer count like the user's own (
credo-peer-lan.py trust add <peer> <session>); unpaired, token-only and same-machine senders never get trust, and apair-resetof the peer drops its entries. For a trusted sender the relay adds a marker that the hook verifies against the local trust list and pairing store (trust verify, never the message text). For a verified message that session's tasks are carried out without asking, except dangerous ones (deleting user data, installs, money, permission, credential or security changes, the hard safety rules, irreversible steps outside the repo), which are reported to the user; the peer still cannot grant permissions or change trust. A marker that does not verify adds a warning. The hook recognizes trust grants with a shell-aware parser: a Bash run ofcredo-peer-lan.pywithtrustand lateradd(directly, viapython3, a wrapper or a variable such as"$P"), a Bash write topeer-lan-trust.json(redirect,cp/mv/tee/ln/dd,sed -i,rm, interpreter code naming the file as a path literal) and a Write/Edit/MultiEdit of it; mentions (read-only commands, commit messages, echo strings, heredoc bodies) are not grants. Trust guard switch: by default (peer.trust_guard.quiet: true) a grant only gets a non-blocking reminder that only the user grants trust, so autonomous runs with peers are never stopped by a confirmation dialog; strict mode (quiet: false, or envCREDO_PEER_TRUST_GUARD_QUIET=false, env wins) makes the user confirm every grant, and/credo:setup(Step 12) offers it. The key is read from the global and profile config layers only (a repo's.credo/configcannot downgrade it); withoutpython3the config is not read and only the env variable selects strict mode. Strict mode also asks on obfuscated forms (arguments from variables,$'...', brace expansion, globs,eval, a trust file name built from pieces). The guard is a best-effort reminder, not a security boundary: the boundary is that only the user runs trust grants. Details:commands/peer-lan.md. -
Disable with
CREDO_PEER_ETIQUETTE=0.
credo picks the model and effort for each subagent from a preset. The main model stays your own choice (/model, /effort); a preset only recommends one for the main agent.
Three presets ship as a builtin layer (templates/presets.default.yaml). Print any of them in full with scripts/credo-preset.sh show <name>. Haiku is claude-haiku-5-5, Opus is claude-opus-5-5.
| Role | quality | balanced (default) | budget |
|---|---|---|---|
| main agent (recommendation only) | Opus, medium | Opus, medium | Haiku, xhigh |
| explore | Haiku, xhigh | Haiku, low | Haiku, low |
| build | Opus, medium | Haiku, xhigh | Haiku, xhigh |
| review | Opus, medium | Haiku, xhigh | Haiku, xhigh |
| hard | Opus, medium | Haiku, xhigh (2 attempts), then Opus, medium (5 attempts), then back-to-human | Haiku, xhigh (3 attempts), then Opus, medium (1 attempt), then back-to-human |
Roles without attempts run until done (no attempt cap, see Stages). The roles are explore (locates code), build (implements a 2_go item), review (reviews built work) and hard (a build the main agent judges difficult).
-
preset: <name>in the credo config. It is read through the normal config cascade, so the project.credo/configoverrides the global~/.claude/credo/config. Unset meansbalanced. - Custom presets go under
presets:in a config layer, with the same schema. A preset defined underpresets:replaces a same-named preset of a lower layer as a whole, with no per-key merge, so a missing prompt key stays missing.
preset: my-mix
presets:
my-mix:
mainagent: {model: claude-opus-5-5, effort: medium}
explore: {model: claude-haiku-5-5, effort: low}
build: {model: claude-sonnet-5-5, effort: medium, attempts: 3}
review: {model: claude-opus-5-5, effort: medium}
hard:
- {model: claude-opus-5-5, effort: medium, attempts: 2}
- back-to-humanA role is one stage, or a list of stages that may end with back-to-human.
-
model-claude-haiku-5-5,claude-opus-5-5orclaude-sonnet-5-5. The helper rejects other ids. The Agent tool alias is haiku, opus or sonnet. -
effort- low, medium, high, xhigh or max. -
attempts- a positive integer, oruntil-done, which is the default for a stage withoutattempts.until-donehas no attempt cap. The budget caps stop it, and the same failure twice without progress hands the item back. Only the last stage may beuntil-done. -
subagent-prompt- optional, see Prompts.
A failed attempt (red tests, a red done-gate, an audit FAIL, or a subagent that reports itself stuck) is retried with its findings. When a stage has used up its attempts, the next stage takes over. back-to-human moves the item to 1_clarify with a > URGENT: note and sends an ntfy push; an autonomous run continues with other items, an attended session asks the user.
-
universal-prompt- every agent, main agent and subagents. -
mainagent-prompt- the main agent only. It holds the decision rule for agent-owned open questions. The built-in ones give three steps in order. First, the best solution known today. Second, best effort. Third, note it and present it to the user later. -
subagent-prompt- per stage, added to the brief of every subagent spawned for that stage.
A missing key adds nothing; there is no hidden default text.
-
Main agent - the SessionStart hook adds the universal-prompt and the mainagent-prompt to every start of an active credo session, including the start after a compaction.
/credo:session-activeand/credo:session-initapply it once mid-session. -
Subagents - the SubagentStart hook receives neither the role nor the preset. The main agent therefore passes the stage's
aliasas the Agent tool'smodel, passes itseffort, and appends the printedpromptblock (universal-prompt plus the stage's subagent-prompt) verbatim to the Agent prompt. A builder that may decide agent-owned questions also gets the mainagent-prompt in its brief.
scripts/credo-preset.sh is read-only.
-
stage <role> [attempt]prints the alias, effort, the prompt block, the action (spawnorback-to-human) and the next step after a failure (retry,next-stageorback-to-human).--field <name>prints one value. -
mainagent [--field prompt],show [name],listandactivecover the rest.
An invalid role (unknown model id, invalid effort or attempts, until-done or back-to-human in the wrong place, or a missing role) prints a warning on stderr, and only that role falls back to the built-in balanced definition. An unknown preset name warns and falls back to balanced. A role name other than the four is ignored with a warning.
/credo:setup (step 2d) offers the three built-in presets or a custom one and writes preset: into the global or project config. /credo:session-init hints when the main model differs from the recommendation.
Parallel subagents are wanted; there is no fixed cap on code tracks. They are limited only by file overlap and machine resources.
-
touches:(optional item field) - a list of paths or globs the item will likely edit, set by the plan / clarify agent at the latest at GO. It is guidance, not a contract: right before spawning builders the main agent re-checks that the paths still fit and updates the item when files were renamed or moved.scripts/credo-touches-check.sh [--json] <id> <id> ...prints overlapping item pairs (glob-aware, conservative) and lists items withouttouches:asunknown; exit 0 no overlap, 3 overlap, 4 no project, 1 bad args. Overlapping items run sequentially. Items withouttouches:are classified by the main agent, parallel by default, sequential only in serious doubt or when nasty, hard-to-resolve conflicts are clearly foreseeable. Read-only work (research, clarify) stays freely parallel. -
Resource gate -
scripts/credo-resource-check.sh --running N [--heavy] [--json]printsok(exit 0) orwait:<reason>(exit 5). Belowresources.gate_from_agentsrunning agents it answersokwithout checking; from there on, and always with--heavy, it checksMemAvailable(/proc/meminfo) and the 1-minute load per CPU (/proc/loadavg/nproc). Unreadable values never block. Onwaitno new agent starts; the main agent re-checks when the next agent finishes (completion notification, no polling loop). -
heavy: true(optional item field) - for model or benchmark tests and large downloads: never runs in parallel to another heavy item and starts only when the check with--heavysaysok, even below the gate.
Config keys (builtin defaults):
| Key | Default | Meaning |
|---|---|---|
resources.gate_from_agents |
6 |
check the machine only from this many running agents |
resources.min_free_ram_gb |
4 |
wait when less RAM is available (GB) |
resources.max_load_per_cpu |
1.0 |
wait when the 1-minute load per CPU is higher |
Every code track works in a git worktree, also a single isolated build track, not only parallel ones. Everything here runs automatically - the user never has to run a command.
-
Which flow -
scripts/credo-worktree-flow.sh [--json] [dir]printsflow=hydra|ask|nativeplus thesetup=script. It reads the DOGMA-PERMISSIONS checkboxuse Hydra for 2+ independent tasks(### Hydrasubsection) (stable id§xw1i) throughscripts/credo-dogma-mode.sh [--id <id>] <subsection> <pattern> [dir], a tiny reader that works without dogma (matches the(§xxxx)id first, anywhere in<permissions>, so reworded or moved lines still count; only without an id line the subsection + text pattern; printsauto|ask|deny|missing; when the worktree has no DOGMA-PERMISSIONS.md it reads the main worktree's; it picks the file like dogma -diras the target, else the credo pinned project, else the current folder - and takes every setting that file does not define from the session folder's file (the folder the session was started in, recorded per session by thecredo-session-dir-record.shSessionStart hook so it is still found after acd <project> && ...; without a record$PWD) unless the file says- [ ] (§r3nx) inherit permissions, see the dogma page "Which DOGMA-PERMISSIONS.md applies (and inheritance)").[x], no checkbox or no file (default on) with hydra installed = hydra's create flow automatically;[?]= ask the user once per batch (never in autonomous mode: native);[ ]or no hydra = nativegit worktree add. -
Hard rule - under
flow=hydrathe Agent tool's built-inisolation: "worktree"is never used, and a baregit worktree addwithout the setup script is never run - always hydra's create flow plus its setup. Underflow=nativeeverygit worktree addis followed by the setup script. -
Setup - a fresh worktree only has versioned files, so rules and items are missing. Right after every
git worktree add,scripts/credo-worktree-setup.sh <worktree> [main-checkout](or hydra's identicalworktree-setup.sh) links (relative symlinks) or copies the excluded files: the "Worktree files" list of DOGMA-PERMISSIONS.md (link:/copy:entries, read through dogma'sworktree-files.sh), else the default - CLAUDE.md, CLAUDE/, GUIDES/, DOGMA-PERMISSIONS.md and everything unversioned under.credo/, each only if it exists. Only ignored paths are linked or copied: an untracked path that is not ignored in the main checkout (e.g. a new uncommitted item file) is skipped withskipped <path> (untracked, not ignored - read it in the main checkout), because agit add -Ain the worktree would commit the link and a merge would put it into main; builders read it in the main checkout, and it is never added to the shared.git/info/exclude. Directories with tracked files (or not-ignored ones holding ignored entries) are recursed into and only untracked, ignored entries are linked; versioned paths are skipped with a warning; existing paths are never overwritten. A linked directory ignored only by adir/pattern gets an anchored/dirline in the shared.git/info/exclude(adir/pattern does not match a symlink). Underflow=nativeonly, a harness-created worktree (Agent toolisolation: worktree) is allowed; the builder then runs the setup on its own worktree root first. -
Main checkout in the brief - the setup prints
main=<main checkout>. Every worktree builder brief names that absolute path: when something important is missing in the worktree (neither checked out, linked nor copied), the builder looks it up read-only in the main checkout, never writes, commits or runs state-changing git commands there, and mentions in its report what should be added to the worktree files list. -
Cleanup at item close - every move to done, verified or archived (
credo-item-move.sh) runsscripts/credo-worktree-cleanup.sh [--dry-run] [--json] [--base <branch>] [--fresh-hours N] [dir]per the checkboxclean up merged worktrees automatically(stable id§36ch):[x]remove without asking (user-authorized by the setting),[?]or no checkbox list the candidates and ask,[ ]never. Only worktrees whose branch is fully merged into the main branch (the one checked out in the main worktree) and that have no changes to tracked files are removed - untracked scratch and the setup links go with them - viagit worktree remove --force(symlinks are unlinked, never followed) andgit branch -d. The main worktree, the current one, locked, unmerged and dirty worktrees are kept and reported with the reason; a never-committed worktree is kept while younger than 24h or holding untracked files (an agent may be starting in it). Every run covers all worktrees of the repo, so the first one sweeps the backlog. A cleanup error never fails the move.
/credo:optimize (skill optimize) is an audit credo offers but never forces. It is language-agnostic and respects the repo's existing conventions: it detects what the repo already does first and recommends an ecosystem standard only where nothing exists, for you to confirm.
-
Opt-in per repo. Asked once, together with the credo onboarding question, in
/credo:setupand in/credo:session-init; where credo is already active, thecredo-optimize-hook.shhook asks it on the next fresh start. Nothing is scanned before your answer. Yes = run it now, later offered again only when you return; No = never offered automatically,/credo:optimizestays available by hand. Stored per repo and per profile. -
Only for returners, never while you work. The hook (SessionStart, also on resume) offers it again only when the repo has been idle for at least
optimize.idle_days(default 7, wall-clock): credo's own per-repo last-seen timestamp (updated on every prompt), the newest reflog entry, the mtime of.git/indexand the newest mtime among the filesgit status --porcelainlists as modified or untracked must all be older. Evaluated before last-seen is updated, asked once per return, never in autonomous mode (the offer then waits for the next attended session). Toggle:CREDO_OPTIMIZE_HOOK. -
Fresh state first. Before every run,
credo-optimize-fresh.shchecks that the repo is on its default branch and not behind its remote. If not, credo proposesgit switch <default>andgit pull --ff-onlyand runs them only with your consent; a stale state is never audited silently. -
What it looks at (read-only, by a subagent). Conflict hotspots from
git log(auto-discovery instead of central registration lists, smaller modules, generated mirror lists, splitting a growingCLAUDE.mdinto the dogmaCLAUDE/<topic>.md+GUIDES/pattern with fixed@-paths); changelog fragments (a versionedchangelog.d/assembled by/dogma:versioningin the release commit, never a tag); the test-stage convention (pytesttests/, co-located*.test.ts,Foo.Tests/, Fluttertest/with*_test.dart, Gox_test.go, ...); dogma settings inferred from your workflow (Test Commands stages, the release-only option, the Hydra checkboxes - handed to/dogma:permissionsas suggestions); parallelism readiness (worktree files list, large files that block parallel work). - Instruction consistency (opt-in extra, asked separately). A read-only check of the global and repo instruction files and plugin-injected texts for contradictions with credo; findings are offered like all others.
-
Result. A report at
.credo/process/reports/optimize-<YYYY-MM-DD>.md; every finding is offered as Implement / Later / Never. Larger accepted findings become credo items, small ones may be done directly after confirmation, and Never is remembered per repo and finding.
| Key | Default | Meaning |
|---|---|---|
optimize.idle_days |
7 |
offer the audit again only when every activity signal is at least this many days old |
credo-wait-hint.sh (PreToolUse Bash) adds a hint when a command loops on pgrep -f (until ! pgrep -f "X" matches the waiting shell's own command line and never ends): wait on a result file or one specific PID with a time limit, or rely on the harness completion notification. It never blocks; the rule itself is in the orchestration skill. Disable with CREDO_WAIT_HINT=0.
In Claude Code builds with mods support, credo ships hooks/band.tsx (listed under modules in hooks/hooks.json, state contract in types/index.d.ts). It draws a band above the prompt. It is optional and only a renderer: it runs the read-only core scripts above with this session's id and reads templates/shorthands.json. Everything else in credo works exactly the same without it and in other harnesses.
-
Counts line -
◆ credoand the item count per status (cf go bk,dd vf,pk ar), colored per group (open yellow, blocked red when non-zero, finished green, parked gray), zero counts dimmed. A change flashes for 6 s (fuchsia for moves, white for new items) and raises a toast. Without a credo project (no item system, also in a pinned project without items) the counts and the item controls (i,l,e) are left out, but the session line - mode/role, open test/question letters,hhelp - and the autonomy line still show whenever there is something to show (also in a declined directory or without a credo mode: only the item system is off there); the prompt hint then lists the shorthands that work without items (cf dd vf ??? cm ph) and thehcheatsheet leaves out the#Nitem moves. -
Session line - this session's mode/role (
autonomous paused/taskwhen a user message paused the autonomous run; pausing and re-arming flash the tag like an item move), the open test/question letters (🧪 / ❓) from the last answer, and the controls:
| Key | Button | Action |
|---|---|---|
i |
☰ items |
Items pane: per status the total and the newest 15 items (also /credo-items) |
h |
? help |
Shorthand cheatsheet in the same pane |
l |
⇆ |
Short (go: 12) or long (Go(go): 12) labels; also spells out the prompt hint |
e |
◐ <preset> |
Rotates all / no parked / open + dogma / open only (open only also hides the dogma band) |
-
Autonomy line - only while this session runs autonomously:
⟳ autowith the 5h utilization, the next ladder rung and the next wake time. -
Prompt hint -
Shortcuts: ...lists the shorthands the band does not show (key(word)in long form).
The band refreshes on session start, after Bash tool calls, at turn end and every 10 s.
credo works on its own. Three touchpoints are external.
The Limit plugin is a prerequisite for two features:
-
Context-percent triggers - the auto-run of compact-plus at the configured session-context fill thresholds relies on the limit plugin's inject hook. Point it at credo with:
CLAUDE_MB_LIMIT_COMPACT_SKILL=credo:compact-plusCLAUDE_MB_LIMIT_INJECT_THRESHOLDS=80,92
When the limit plugin is installed,
/credo:setupoffers to write these for you: it detects an unset, empty, leading-slash, or stale value and offers to setCLAUDE_MB_LIMIT_COMPACT_SKILL=credo:compact-plus(plus the thresholds if unset) in~/.claude/settings.json, permission-per-change and idempotent. Hand-editing is therefore optional; the values above still apply if you set them yourself instead of running setup. -
Budget data source - the budget skill reads the limit cache (
/tmp/claude-mb-limit-cache_*.json) for the 5-hour and weekly utilization and reset times.
If the limit plugin is absent, these features are silently unavailable. There is no error; credo simply does not run the budget or auto-compact logic that has no data.
Run Claude Code inside tmux. Several credo features type into the session's OWN terminal pane, and only tmux gives them a pane they can safely inspect and type into:
-
/credo:self-compact- tmux only. Outside tmux it refuses and you compact by hand. -
/credo:self-reload- tmux only (types/reload-pluginsand/reload-skillsinto the own pane). -
/credo:self-restart- works without tmux (new Windows Terminal tab / terminal window), but only inside tmux it waits until the pane is idle with an empty input field, so a prompt you are typing is never lost, and relaunches in the same pane.
This fits WSL too, because tmux runs inside the WSL distro like on any Linux and the Windows Terminal tab is just the window around it. Native Windows has no tmux - use WSL.
/credo:setup (Step 11) detects whether tmux is installed and whether the current session runs inside it, shows the exact install command for your package manager (apt, dnf, pacman, zypper, brew) and runs it only after your explicit yes. It can also add a small ctmux shell function (bash, zsh or fish, again only after a yes) that always starts Claude Code inside a named tmux session and re-attaches to it if it already exists:
ctmux() { if [ -n "$TMUX" ]; then claude; else tmux new-session -A -s "${1:-claude}" claude; fi; }When credo is active and a session starts outside tmux, the SessionStart hook adds one short line recommending tmux. It stays silent after you declined tmux in /credo:setup Step 11 (stored as tmux.hint: false in the credo config), in non-terminal hosts (CLAUDE_CODE_ENTRYPOINT other than cli) and with CREDO_TMUX_HINT=false.
Push notifications use ntfy. The topic is a personal field in the credo config (personal.ntfy_topic). If it is unset, ntfy is silently skipped; nothing else changes. Progress is bundled into a digest on a fixed interval (ntfy.digest_interval_minutes); when a topic is set, sending it is mandatory whenever there is progress (with no topic it stays silently skipped), and each completed item carries a content standard (what / how / where / why, verify state, what needs the user, budget snapshot) so a terse one-liner is never enough. One message is preferred, split into n/m when it would exceed ntfy's size limit.
No configuration is required to start. Run /credo:setup to initialize a project and, optionally, pre-fill the global config. Per-project settings live in .credo/config; personal and environment-specific fields are filled just-in-time by the skill that needs them, with permission per change (see the config cascade above).
Machine power-down at the end of an autonomous run is opt-in and default-off, so a server running autonomous work is never suspended by surprise. /credo:setup handles it: it detects the platform (WSL, native Linux, macOS), checks Linux /sys/power/state availability, and stores the mode and exact command - sleep.enabled (default false), sleep.mode (suspend standby or hibernate), and sleep.command. WSL defaults to hibernate (shutdown.exe /h), native Linux to standby (systemctl suspend), and the proposed command is user-overridable; at runtime the exact stored command runs, while an enabled-but-unconfigured command ends the run cleanly instead of guessing. An explicit session-suspend instruction (for example "suspend when done") overrides the default-off for that run and persists across compaction. Setup also decides ntfy once: it is used when a topic is configured and silently skipped otherwise, and a decline is recorded as personal.ntfy_optout so setup does not ask again.
MIT - See LICENSE for full terms.
See also: Dogma | Limit | All Plugins
Keywords / Tags
Claude Code, Claude Code Plugin, Claude Code Extension, Claude Code Credo, Claude Code Workflow, Claude Code Process Framework, Claude Code Session Modes, Claude Code Autonomy, Claude Code Definition of Done, Claude Code Work Items, Claude Code Budget, Claude Code Visual Verification, Claude Code Subagents, Claude Code Safety, Anthropic CLI, Anthropic Plugin, Anthropic Extension, Anthropic Claude, Anthropic AI, AI Agent Workflow, AI Agent Process, AI Code Assistant, AI Coding, AI Programming, AI Development, Process Framework, Workflow Guides, Best Practices, Definition of Done, Work Item Lifecycle, Session Modes, Autonomous Agent, Budget Awareness, Visual Verification, Subagent Priming, WSL, WSL2, Linux, macOS, Marcel Bich, marcel-bich-claude-marketplace, credo plugin