Skip to content

A bare claude in a supervised repository starts with the repository's session-start prompt as its first message, and a run with an argument, outside such a repository, with the opt-out, or with a prompt that cannot be rendered is left exactly as it was

A hook can only add context to a session; nothing but a first message starts a turn. So claude opened in this repository used to receive the whole briefing and then wait for a person to type. With the wrapper sourced, a bare claude here starts with the repository's own prompt as its first message: say how you are attached, read the board, find the work that is owed, check for collisions, announce, then work inside the task's scope and keep everything local.

declared statusdeclared status: guaranteed Declared deterministic and blocking, implemented, and naming the behavioural test that is to prove it. Whether a recorded run supports it is the evidence verdict, shown beside it.

recorded evidencerecorded evidence: not run Declared guaranteed, and not supported by a recorded run: the test is named, and no passing run of the current inputs is recorded. how evidence is recorded

Proved in bash and zsh against stubs of claude and majordomus; the real claude takes the prompt as its positional argument (claude --help). Only Claude Code is wrapped; Codex and Gemini are not claimed until each is proved against the real tool. The installer does not source the file, because it touches nothing outside its prefix.

What it means

A hook can only add context to a session; nothing but a first message starts a turn. So claude opened in this repository used to receive the whole briefing and then wait for a person to type. With the wrapper sourced, a bare claude here starts with the repository's own prompt as its first message: say how you are attached, read the board, find the work that is owed, check for collisions, announce, then work inside the task's scope and keep everything local.

How it works

share/shell/session-start.sh defines one function, claude, for bash and zsh. With no arguments, inside a git repository whose root has .ai/manifest.yaml, it runs majordomus --repo <root> prompt render session-start and passes the result as the one argument to the real claude. The prompt is .ai/repo/prompts/session-start.md, so changing it is a commit and every checkout that pulls it is updated. Any argument, any other directory, MAJORDOMUS_NO_AUTOSTART=1, and a render that fails or prints nothing all fall through to a plain claude "$@". The session's exit status is the wrapper's, and no variable is left behind in the shell.

How to see it

. share/shell/session-start.sh        # from ~/.zshrc or ~/.bashrc, once
claude                                # here: starts with the session-start prompt
MAJORDOMUS_NO_AUTOSTART=1 claude      # here: starts as before
majordomus prompt render session-start
bash test/run.sh 3221_a_bare_session_start_joins_the_cluster

What it does not cover

It is not installed for you: the installer touches nothing outside its prefix, so sourcing the file is one line a person adds. Only Claude Code is wrapped; Codex and Gemini are not claimed until each is proved against the real tool. The prompt asks the worker to stay local, but the wrapper does not enforce it; scope is enforced by the task record at check and finish.

Why it exists

On 2026-10-16 the owner asked why a session opened in this repository did not join the mesh through the hook and start working. The hook had run and the mesh was active; the session simply had no turn to act in. ADR 0156 names that state, a worker that behaves as the only one; ADR 0172 decided the wrapper. The case runs the file in bash and zsh against stubs of claude and majordomus.

Detail rendered from docs/claims/session-start-prompt.md.

From the statement to the proof

  1. 1 · the public statement

    A bare claude in a supervised repository starts with the repository's session-start prompt as its first message, and a run with an argument, outside such a repository, with the opt-out, or with a prompt that cannot be rendered is left exactly as it was

    No feature or README responsibility names it; this page is where it is stated.

  2. 2 · the canonical claim

    session-start-promptdeclared status: guaranteed in docs/CLAIMS.yaml

    Defined in read it on this site · docs/MCP.md

  3. 3 · the implementation

    share/shell/session-start.sh

  4. 4 · the test and the scenarios

    Test: test/cases/3221_a_bare_session_start_joins_the_cluster.sh

  5. 5 · the recorded runs

    recorded evidence: not run how evidence is recorded

Verify it yourself

The test runs in a disposable temporary repository and asserts the behaviour, not a string in the source.

from a clone of the repository
bash test/run.sh 3221_a_bare_session_start_joins_the_cluster

Searches the titles and descriptions of every page this site publishes.