project-config
Shows and changes what a project configures in its own .claude/, through ArchHook.jar config, the only writer.
project-config, section by section
The sections of the skill's own SKILL.md, excerpted. Hover or click one to see which project rules, templates and references/ files it cites. The sections are also chips: click one to jump to it.
## Current settings
!java -jar "${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/ArchHook.jar" config list 2>&1
The block above is one JSON line from config list: every file this project may write for itself, each key with its type, its allowed values, its default, its current value, what it changes (effect), fixed: true when upstream owns it, available: false when the audit trail is off, in_force and problems as doctor would print them. Where it did not expand — a host with no ` ! `` injection, such as the GitHub Copilot CLI — run the same command first:
java -jar .claude/hooks/ArchHook.jar config list## Why this is a skill (Form 2) and not an agent
A short procedure over one command's output, typed by hand because it changes a versioned file (axes 2 and 3 of decision 0187). An agent was rejected: no context to preserve, no tool to restrict beyond what config itself refuses, the same model — none of invariant 5's reasons. The validation is not here either: it lives in ArchHook.jar config, so a person, this skill, another agent and a later mod reach the same rule.
### 1 · Show
No argument: render the block as one table per file — path, summary, then the keys whose value is not null and every key whose in_force mentions it — and the problems, if any, first. For audited, list only the pieces whose value differs from default; the full list of skills and agents is noise until asked for. End with the decision of each file (decision), cited by path, for whoever wants the reason.
problems not empty → say so before anything else: doctor reports the same line red, and a gated one (doctor.gate.labels) fails CI. The way out is config unset <id> <key> for each key it names.
### 2 · Decide what to change
An argument or a request names a change → map it to <id> <key> <value> from the block. A key not in the block does not exist: say which keys do, never invent one. Ambiguous (which skill, which value) → one AskUserQuestion with the candidates from the block, each option carrying its effect; when a value differs from the default, say what that default protects — the effect text and the decision record hold it.
### 3 · Confirm, then write
State the command and the line of the file it changes, and ask once. On yes:
java -jar .claude/hooks/ArchHook.jar config set <id> <key> <value>
java -jar .claude/hooks/ArchHook.jar config unset <id> <key> # back to the default
Exit 0 prints the change. Exit 2 wrote nothing and printed why — relay it as printed and offer the valid values from the block; never retry with a guessed value. Exit 1 is a usage error.
### 4 · Report
The file and the line changed, that it is versioned (commit it with the change it serves), and the doctor line that now validates it (doctor_label). /arch-adopt never touches these files: the setting survives every update.
## Failure modes
- The block is a stack trace or
Unknown mode: config. The project'sArchHook.jarpredates config: no project_config. Same cause,extensions.jsonside —/arch-adopt.- A guard refusal naming
config set. Something tried to write the file directly. Use the available: falseand the person wants a setting of the audit trail. Creating
What it reads, writes and refuses
The skill's own contract, from SKILL.md, in the original wording.
Class
ops — the territory is skill_classes.ops in @.claude/schemas/extensions.json, and it is empty: this skill writes no file with a tool. Every change is java -jar .claude/hooks/ArchHook.jar config set|unset, which writes the file itself after the validator doctor runs passes. guard refuses a Write, an Edit or a shell redirect into a registered path, so editing the JSON by hand from here is not a way around it.
Reads
the config list output above. Which settings exist, their keys, values, defaults and the decision behind each are data in project_config of @.claude/schemas/extensions.json; this skill never restates them.
Writes
nothing directly. Through config: the files project_config lists, and only those.
Out of reach
a key marked fixed (today arch-adopt in audited, never audited); a setting whose file is available: false (the audit trail is off — .claude/audit-usage/ missing — and writing a setting of it would switch the trail on); anything in .claude/settings.json, settings.local.json or extensions.json itself, which /arch-adopt overwrites.
Source: SKILL.md § Contract, at nerviz e4cae27.
What the guard does with it
ops is the skill's class, and the list on the left is its territory. The phase opens when the skill runs on a prompt of its own, and ArchHook judges every write against that list. The text on the right is the hook's own.
write_allow of project-config
any file: the territory is empty
A refusal exits with code 2 and the message goes back to the model.
> /project-config … UserPromptSubmit guard prompt exit 0 # phase opened: project-config (class ops) # write_allow: [] — this class writes no file
PreToolUse Write(pom.xml) guard write exit 2 ❌ `project-config` is class `ops` — pom.xml is outside its territory. write_allow: (nothing — this class writes no file) Put the content in the spec as a code block, or finish the run and invoke the skill that owns this path. If the path is legitimately this skill's, widen skill_classes.ops in .claude/schemas/extensions.json — retrying will not help.
Who calls it
It is not a step of a chain. It starts from a prompt of its own, /project-config, and the guard treats it like any other skill: the phase opens, and the territory of its class applies.