Problem
Use-case 3 in ADR-001, the hard one. A developer wants the agent-init scaffold present and used locally in a specific repo, but completely hidden from other contributors — with no trace even in that repo's committed .gitignore. A teammate cloning the repo must not be able to tell agent-init is in use.
A global ignore (#52) does not suffice here: it hides the scaffold in every repo, which conflicts with having other repos where agent-init is committed openly. This case needs a per-repo mechanism that is local to one repo and leaves nothing in any tracked file.
Design (ADR-001, accepted 2026-05-24)
Part of one flag with four values: init --visibility=<shared|local|hidden|global-default>. This issue covers hidden. --private is an accepted alias for --visibility=hidden.
agent-init init <flavor> --visibility=hidden writes the fenced full-envelope block to .git/info/exclude (per-repo, local, never committed).
This is distinct from local (#51), which writes the block to the committed .gitignore: local keeps files untracked but intentionally shares the ignore rule with the team (for collaborators on a different setup). hidden instead leaves zero committed trace — .git/info/exclude is git's purpose-built location for "patterns specific to one user's workflow that should not be shared" (gitignore(5)) and applies identically to .gitignore. This satisfies the strong reading of "hidden from other contributors." The two are separate modes; neither replaces the other.
Block content (identical across modes):
# >>> agent-init (private) >>>
.agent/
/AGENTS.md
/CLAUDE.md
.devcontainer/
/Justfile
.pre-commit-config.yaml
# <<< agent-init <<<
Discoverability / undo affordance — new agent-init status subcommand
.git/info/exclude does not show in git diff, so the owning dev can forget the repo is in hidden mode (R-F4). Pair hidden with a small read-only subcommand:
agent-init status [target] prints:
status is the only new subcommand and it writes nothing.
Precedence / interaction model
Modes are mutually exclusive per-repo choices; they do not stack. Highest-to-lowest git ignore precedence: committed .gitignore > .git/info/exclude > core.excludesfile. hidden touches only the current repo's .git/info/exclude — no machine-wide effect, no committed trace, fully independent of other repos (R-F2, R-N2). Full model in ADR-001 and #52.
Acceptance criteria
Not building (bloat to resist)
- No
skip-worktree / assume-unchanged (designed for tracked files; brittle and surprising — Option 4 in ADR-001, dismissed).
- No per-file/per-group selection; the envelope is one unit.
- No automatic mode-conversion command; change modes by deleting the old block and re-running
init. status shows how.
- No persisted config store.
Related
Problem
Use-case 3 in ADR-001, the hard one. A developer wants the agent-init scaffold present and used locally in a specific repo, but completely hidden from other contributors — with no trace even in that repo's committed
.gitignore. A teammate cloning the repo must not be able to tell agent-init is in use.A global ignore (#52) does not suffice here: it hides the scaffold in every repo, which conflicts with having other repos where agent-init is committed openly. This case needs a per-repo mechanism that is local to one repo and leaves nothing in any tracked file.
Design (ADR-001, accepted 2026-05-24)
Part of one flag with four values:
init --visibility=<shared|local|hidden|global-default>. This issue covershidden.--privateis an accepted alias for--visibility=hidden.agent-init init <flavor> --visibility=hiddenwrites the fenced full-envelope block to.git/info/exclude(per-repo, local, never committed).This is distinct from
local(#51), which writes the block to the committed.gitignore:localkeeps files untracked but intentionally shares the ignore rule with the team (for collaborators on a different setup).hiddeninstead leaves zero committed trace —.git/info/excludeis git's purpose-built location for "patterns specific to one user's workflow that should not be shared" (gitignore(5)) and applies identically to.gitignore. This satisfies the strong reading of "hidden from other contributors." The two are separate modes; neither replaces the other.Block content (identical across modes):
Discoverability / undo affordance — new
agent-init statussubcommand.git/info/excludedoes not show ingit diff, so the owning dev can forget the repo is in hidden mode (R-F4). Pairhiddenwith a small read-only subcommand:agent-init status [target]prints:statusis the only new subcommand and it writes nothing.Precedence / interaction model
Modes are mutually exclusive per-repo choices; they do not stack. Highest-to-lowest git ignore precedence: committed
.gitignore>.git/info/exclude>core.excludesfile.hiddentouches only the current repo's.git/info/exclude— no machine-wide effect, no committed trace, fully independent of other repos (R-F2, R-N2). Full model in ADR-001 and #52.Acceptance criteria
init <code-flavor> --visibility=hidden(and alias--private) appends the fenced full-envelope block to.git/info/exclude, creating the file if needed..gitignorein this mode;git statuson a clean clone by a teammate shows no agent-init trace.initprints the absolute path of the.git/info/excludeit wrote (the side effect is announced, R-N3)./CLAUDE.md→AGENTS.md,.agent/CLAUDE.md) is ignored correctly: the block lists/CLAUDE.mdand.agent/; symlinks are ignored by path like any file. The engine still creates the symlinks (visibility controls tracking, not creation).agent-init status [target]reports the mode, the carrying file (absolute path), and the undo command; read-only.--dry-runprints the target path and block, writes nothing.claude-cowork,project-management) with a clear error, like--agents-only.docs/cli.mdand--help.Not building (bloat to resist)
skip-worktree/assume-unchanged(designed for tracked files; brittle and surprising — Option 4 in ADR-001, dismissed).init.statusshows how.Related
specs/adr-001-per-repo-scaffold-visibility.mdin the PM workspace) — case 3; the load-bearing recommendation (hiddenwrites to.git/info/exclude).local, committed.gitignore). A distinct mode (openly-shared ignore rule), not folded into this one. Owns the--visibility=localvalue;--privatealiaseshidden(this issue).global-default). Shares the--visibilityflag and the fenced block.