An agent session should be able to run the full workflow against a real repository — including skills that push branches or create issues — without anything leaving the machine. Today that depends on the agent following an instruction. It should depend on the environment instead.
Why
Demonstrations, workshops and a first look at an unfamiliar project all want the same thing: let the skills act for real, and be certain nothing is published. architecture-impact, for example, classifies requests, prefixes issue titles and creates sub-issues; it has no analysis-only mode. A sentence in the prompt is not a guarantee, and a permission rule only matches a command as it is written.
Proposal
A cross-engine helper in adapters/shared/, next to install-skills.sh and journal-config.sh:
setup <source> [target] clones the source into a directory of its own, makes the clone's push URL unusable, and installs a pre-push hook through a clone-local core.hooksPath that rejects every push — including a push to an explicitly named URL, which an unusable push URL alone would not stop.
start <target> [-- command] runs the agent (Claude Code by default) in an environment without credentials: no gh or glab login, no SSH agent, GIT_SSH_COMMAND=false, every git credential helper reset, no terminal prompts.
check <target> attempts every write path against a target that does not exist, so even a failing layer publishes nothing, and requires the right reason for each failure. A probe that fails only because its target is missing is reported as open, not as blocked.
For Claude Code, setup also writes deny rules to .claude/settings.local.json. That layer is soft; the guarantee rests on the two hard layers.
Acceptance criteria
An agent session should be able to run the full workflow against a real repository — including skills that push branches or create issues — without anything leaving the machine. Today that depends on the agent following an instruction. It should depend on the environment instead.
Why
Demonstrations, workshops and a first look at an unfamiliar project all want the same thing: let the skills act for real, and be certain nothing is published.
architecture-impact, for example, classifies requests, prefixes issue titles and creates sub-issues; it has no analysis-only mode. A sentence in the prompt is not a guarantee, and a permission rule only matches a command as it is written.Proposal
A cross-engine helper in
adapters/shared/, next toinstall-skills.shandjournal-config.sh:setup <source> [target]clones the source into a directory of its own, makes the clone's push URL unusable, and installs apre-pushhook through a clone-localcore.hooksPaththat rejects every push — including a push to an explicitly named URL, which an unusable push URL alone would not stop.start <target> [-- command]runs the agent (Claude Code by default) in an environment without credentials: noghorglablogin, no SSH agent,GIT_SSH_COMMAND=false, every git credential helper reset, no terminal prompts.check <target>attempts every write path against a target that does not exist, so even a failing layer publishes nothing, and requires the right reason for each failure. A probe that fails only because its target is missing is reported as open, not as blocked.For Claude Code,
setupalso writes deny rules to.claude/settings.local.json. That layer is soft; the guarantee rests on the two hard layers.Acceptance criteria
adapters/shared/dry-run-session.shwithsetup,startandcheck, without a JSON parser or other runtime beyond git and a POSIX shellfeatures/dry-run-session.featureand bridged totest/dry-run-session.test.mjs; the tests are hermetic and need no networktest/dry-run-session.test.mjsruns as part of./build.sh test-jsadapters/shared/README.mdand referenced fromREADME.mdand from the talk material that uses itcheckis the live counterpart on a user's machine; what it does not guarantee is stated, not implied