## Configuration and launch precedence

A displayed setting answers a configuration question\.&#32;It does not necessarily answer the wrapper’s final policy question\.

Nia’s fictional settings view says always\-ask\,&#32;yet an exec\-tier recording call proceeds without a question\.&#32;Before assuming a broken gate\,&#32;she checks whether the launch supplied&#32;`autoApprove`&#32;separately\.

### Keep persisted configuration and runtime overrides separate

The supplied&#32;`Settings`&#32;implementation merges the active profile’s persisted layer\,&#32;project settings\,&#32;explicit configuration overlays\,&#32;and runtime overrides\,&#32;in that increasing order of precedence\.&#32;`get()`&#32;resolves a value from the merged view\,&#32;falling back to the schema default when it is absent\.

`Settings.set()`&#32;changes the persisted layer and queues saving\.&#32;`Settings.override()`&#32;changes a non\-persisted runtime layer\.&#32;An ordinary session transition is not a factory reset of those settings\.

For well\-formed object layers\,&#32;maps are deep\-merged\;&#32;arrays such as&#32;`bash.patterns`&#32;are replaced by the higher layer rather than concatenated\.&#32;Therefore the effective ordered rule list must be inspected as a list\,&#32;not imagined as every rule from every file in sequence\.

The wrapper reads mode and user policies from its execute\-time&#32;`context.settings`\.&#32;A tool’s own classifier can also read settings bound to its tool instance—for example\,&#32;`BashTool.approval()`&#32;reads its session’s&#32;`bash.patterns`\.&#32;A dump from an unrelated settings instance cannot establish both inputs\.

### Read the isolated CLI observation

The supplied configuration report used the installed&#32;**`omp/18.0.7`**&#32;CLI\,&#32;an exclusively owned fresh named profile with no linked authentication\,&#32;and an empty temporary working directory\.&#32;It did not inspect or change the reader’s personal settings\.

This section reproduces the observation\,&#32;not an executable recipe\.&#32;The report does not include a complete profile\-creation preamble\,&#32;so no launch or profile\-creation command is invented here\.&#32;The default route is to read the recorded roundtrip\.

Setting&#32;`tools.approvalMode`&#32;to&#32;`write`&#32;with JSON output returned\:

~~~json
{"key":"tools.approvalMode","value":"write"}
~~~

Setting the&#32;`tools.approval`&#32;record to the JSON object&#32;`{"bash":"deny"}`&#32;returned\:

~~~json
{"key":"tools.approval","value":{"bash":"deny"}}
~~~

The saved configuration was YAML\:

~~~yaml
tools:
  approvalMode: write
  approval:
    bash: deny
~~~

Getting each setting with JSON output returned an object\,&#32;not merely its value\:

~~~json
{
  "key": "tools.approvalMode",
  "value": "write",
  "type": "enum",
  "description": "Default approval behavior for tool calls. 'Always ask' auto-approves read-only tools only. 'Write' auto-approves read and workspace-write tools. 'Yolo' auto-approves all tiers; user policy may still prompt or block."
}
~~~

~~~json
{
  "key": "tools.approval",
  "value": { "bash": "deny" },
  "type": "record",
  "description": "Per-tool approval policies. Set to 'allow' to auto-approve, 'prompt' to require confirmation, or 'deny' to block. Overrides are honored in every approval mode."
}
~~~

Those descriptions are the observed CLI copy\.&#32;Their shorthand about read\-only\/workspace\-write behavior does not establish containment or override the more precise resolver precedence\.&#32;The supplied capture also contains wall\-time annotations\;&#32;those are not fields in either JSON setting object\.

**Recorded boundary\:**&#32;the roundtrip demonstrates configuration serialization and inspection\.&#32;It does not demonstrate an approval dialog\,&#32;a live session override\,&#32;effective wrapper policy\,&#32;or a model invocation\.&#32;`commands/config.ts`&#32;delegates to&#32;`runConfigCommand()`\;&#32;the full delegated CLI implementation is not in this selected pack\,&#32;so the observed JSON shapes are kept attached to the report\.

### Launch flags add a second source of precedence

The supported built\-in long forms are&#32;`--approval-mode`\,&#32;`--auto-approve`\,&#32;and&#32;`--yolo`\.&#32;The latter two set&#32;`autoApprove: true`\.&#32;There is no listed built\-in&#32;`-y`&#32;alias in the supplied parser\.

These are flag fragments to interpret\,&#32;not commands to launch for this exercise\:

| Launch input | Settings value after root\-command override | Wrapper mode when the corresponding context is supplied |
| --- | ---: | --- |
| No approval flag | Existing resolved setting | That setting\,&#32;with the wrapper’s documented fallback if absent |
| `--approval-mode always-ask` | always\-ask\,&#32;runtime only | always\-ask |
| `--auto-approve`&#32;or&#32;`--yolo`\,&#32;without an explicit mode | yolo\,&#32;runtime only | yolo |
| `--approval-mode always-ask`&#32;together with&#32;`--auto-approve`&#32;or&#32;`--yolo` | always\-ask remains the displayed runtime setting | yolo\,&#32;because&#32;`context.autoApprove === true`&#32;wins in the wrapper |

`main.ts`&#32;deliberately preserves the explicit mode in settings when both inputs exist\.&#32;`buildSessionOptions()`&#32;separately forwards&#32;`autoApprove`\,&#32;and the SDK supplies it in the tool context\.&#32;The wrapper chooses yolo from that boolean before calling&#32;`resolveApproval()`\.

Changing the order of those two different flags is not a way to make the explicit mode outrank the boolean at the wrapper\.&#32;They populate separate inputs\.

**Recorded comparison\:**&#32;`boundary-auto-approve-mode`&#32;injected configured always\-ask\,&#32;`autoApprove: true`\,&#32;and no UI\.&#32;It returned with zero prompts and one inert execution\.&#32;`boundary-auto-approve-still-denied`&#32;added an effective user deny and stopped before handlers\,&#32;prompts\,&#32;or execution\.&#32;These cases verify execute\-time wrapper behavior\,&#32;not CLI parsing or a full launch\.

### Invalid input does not create a new safe mode

The&#32;`--approval-mode`&#32;setter accepts exactly the three documented values\.&#32;For an invalid supplied value it logs a warning and does not install that value as the parsed mode\.&#32;That is not the same as a hard launch refusal\,&#32;nor proof that it selected always\-ask\.&#32;Other parsed inputs and the resolved settings remain relevant\.

Similarly\,&#32;a type annotation on&#32;`Settings.get()`&#32;is not runtime validation of every hand\-edited value\.&#32;Keep the resolver’s normalization of individual policy strings separate from raw record shape\,&#32;launch parsing\,&#32;and other consumers\.

**Paper checkpoint\:**&#32;a settings view says always\-ask\,&#32;but the execute\-time context has&#32;`autoApprove: true`\.&#32;What mode does this wrapper use\,&#32;and can an effective deny remain\?&#32;**Worked answer\:**&#32;yolo\;&#32;yes\,&#32;the resolver’s explicit deny branches still apply\.

**Failure boundary\:**&#32;no configuration change is required to finish this chapter\.&#32;Do not use a personal profile to recreate the observation or treat a config getter as a diagnostic endpoint for another process’s effective policy\.

**Source anchors\:**&#32;`packages/coding-agent/src/config/settings.ts`&#32;—&#32;`Settings.get`\,&#32;`set`\,&#32;`override`\,&#32;`#rebuildMerged`\;&#32;`packages/coding-agent/src/config/settings-schema.ts`&#32;—&#32;`tools.approval`\,&#32;`tools.approvalMode`\,&#32;`bash.patterns`\;&#32;`packages/coding-agent/src/commands/config.ts`&#32;—&#32;`Config.run`\;&#32;`packages/coding-agent/src/cli/args.ts`&#32;—&#32;`parseArgs`\;&#32;`packages/coding-agent/src/cli/flag-tables.ts`&#32;—&#32;`STRING_SETTERS["--approval-mode"]`\,&#32;`VALUELESS_FLAGS`\;&#32;`packages/coding-agent/src/main.ts`&#32;—&#32;`runRootCommand`\,&#32;`buildSessionOptions`\;&#32;`packages/coding-agent/src/sdk.ts`&#32;— execute\-time context construction\.&#32;CLI observations\:&#32;`proof/cli-config-proof.json`\.
