# Keep AI Files and Settings in Sync: Frozen-Tree Proof

- Article: `keep-ai-files-and-settings-in-sync`
- Evidence date: 2026-07-19 Pacific / 2026-07-20 UTC
- Stage 4 status: sealed before this experiment
- Frozen source: public WarpOS commit
  `8b083d78948263c998134ac5d34947c383e17a85`
- Reproducible helper:
  `scripts/experiments/keep-ai-files-and-settings-in-sync.mjs`
- Machine-readable result:
  `docs/research/keep-ai-files-and-settings-in-sync-proof-2026-07-19.json`
- Recorded result: **PASS**
- Machine report SHA-256:
  `0facd0ace458ee9ce3df0da16642f14d881de9c53a3a775b1b63e4d2558ac366`

## Question

Can one shared path value produce every declared tool-facing copy, expose stale
or hand-edited copies before use, and return to the exact known-good bytes after
a rollback?

The test uses one invented relative value. It never reads a live WarpOS working
tree into the fixture. Each of two independent runs creates a new,
path-restricted `git archive` from the frozen tracked commit, works only inside
a disposable directory, and removes that directory after the assertions pass.
No untracked file, private runtime record, credential, customer data, network
call, provider call, or outside action enters the proof.

## Frozen source boundary

The helper resolves the exact commit and rejects the run unless these Git blob
IDs match:

| Frozen file | Git blob |
| --- | --- |
| `framework/paths.registry.json` | `aba0be06992cd4a9e61e086b133a07c8886d13bc` |
| `scripts/paths/build.js` | `267de41f6ff5491144cd63b4b2c2648d154749d8` |
| `scripts/paths/gate.js` | `0adf90bf3a5dc8a626b3435eb7f6dfb8c88b0333` |
| `scripts/checks/path-usage.js` | `9d26b86d7f884515b21c49230ab62c33d53bd392` |

The restricted archive also includes the five declared generated files. It has
SHA-256
`536e2059832764a5314a1471b7117f8a892c3953c6f72611516122e9e0f6adb9`
in both runs. The registry has 134 keys: 133 active and one removed. The frozen
`.claude/paths.json` has the same 133 active mappings.

## Exact run

```powershell
$env:WARPOS_PROOF_SOURCE_REPO = "<local checkout of the public WarpOS repo>"
node scripts/experiments/keep-ai-files-and-settings-in-sync.mjs --write
```

The helper performs these steps twice from separate archives:

1. Run the generator in check mode and the artifact-only gate against the
   frozen baseline.
2. Change only `paths.eventsFile.path` from
   `.claude/project/events/events.jsonl` to the invented value
   `.workbench/shared-events/events-v2.jsonl`.
3. Prove the pre-generation check exits `1` and reports all five artifacts as
   stale.
4. Generate the files and prove all five SHA-256 values change.
5. Change only `eventsFile` inside `.claude/paths.json` to the invented stale
   value `.workbench/stale-copy/events.jsonl`.
6. Invoke the frozen artifact gate through the proof harness. The gate exits
   `1`; the harness returns `BLOCK`, suppresses execution, and records zero
   downstream invocations.
7. Repair the generated file and run a small exact validator owned only by the
   proof. It rejects an unknown active key and a known key paired with the
   wrong path. Both cases suppress downstream execution.
8. Restore the original registry bytes, regenerate, rerun the checks, and prove
   every output plus the complete restricted-tree fingerprint matches the
   baseline.
9. Compare both independent receipts byte for byte, run the privacy scan, and
   verify both disposable directories are gone.

## Hash evidence

The frozen baseline passed `build.js --check` and the artifact-only gate with
exit `0`. Changing the registry before generation made the check exit `1` and
name all five files as stale. After generation, each output had a different
hash:

| Generated output | Frozen baseline SHA-256 | Changed-value SHA-256 | Rollback SHA-256 |
| --- | --- | --- | --- |
| `.claude/paths.json` | `343e88cdc5fdfa456fae4ff8c12a5d2ed03e1ed6672e8d4735ea9a5ac689e1c6` | `d84a9a3d3c67132c59c451303574ae4b7a5eaf7a45b1a7ce4b7241f320c33e1b` | `343e88cdc5fdfa456fae4ff8c12a5d2ed03e1ed6672e8d4735ea9a5ac689e1c6` |
| `scripts/hooks/lib/paths.generated.js` | `0acb610b8d89a628e6689d24ace399616848770f49a969075ab9673928bcf758` | `0b1aad482d2bf52bd1b2e3ebd02b9223e25ebc321d0d09e23985731cb9ab0a80` | `0acb610b8d89a628e6689d24ace399616848770f49a969075ab9673928bcf758` |
| `scripts/path-lint.rules.generated.json` | `0a2ef7226351a70322d3846b1f0bbd5aed8076094e616809053cfb48378fd129` | `eef822f8235a08829ea635790a9f247a8f6c776cb97191cf67862cd47981d776` | `0a2ef7226351a70322d3846b1f0bbd5aed8076094e616809053cfb48378fd129` |
| `schemas/paths.schema.json` | `e867c421f7328f0afcaea1d29e08495fd2e8ace183983ccb09bfa9c10610a8a0` | `b4b92bcbdef5645f910047818441b7cc1c90d350a67e66cd30f55c0010921eb5` | `e867c421f7328f0afcaea1d29e08495fd2e8ace183983ccb09bfa9c10610a8a0` |
| `_requirements/03-architecture/PATH_KEYS.md` | `cbb8f2a9cb89a10b10b024d09ac74dc45462bf6af1df86a8c2f214c0939a0e57` | `1d3a2e866853ee8a517ee3e680a5c60692187ea9b3e775193669f0941e81ed58` | `cbb8f2a9cb89a10b10b024d09ac74dc45462bf6af1df86a8c2f214c0939a0e57` |

The full restricted-tree fingerprint was
`7f2a50b0554cc9ec4411b183af5fdfa67ce0c2a50a5ff14c2e5064448da565d0`
before the change and after rollback. The final changed-path list was empty and
the clean-diff verdict was `CLEAN`.

Both independent runs produced deterministic-core SHA-256
`27be6bd28fde49d09898b19008020aaa05f5ebe9f89cfab2ad88438528fd22d8`.
Their archive bytes, changed output bytes, rollback output bytes, and complete
receipts were identical.

## Tamper and exact-consumer boundary

The manual `.claude/paths.json` edit proves the frozen WarpOS artifact gate can
detect that generated bytes no longer match the registry. The downstream
suppression belongs to this proof harness, which refuses to call its synthetic
consumer after a failed gate.

The unknown-key and known-key/wrong-path cases use
`proof-only-exact-consumer-validator/v1`. That validator was written for this
experiment. It is not present in the frozen WarpOS source and must not be
described as a WarpOS feature. Its job is narrow: compare one requested key and
path with the active registry and the repaired generated map, then return
`ALLOW` or `REJECT` before a synthetic downstream call.

## What this supports

The recorded result supports this bounded claim:

> WarpOS gives active paths stable names and can reject stale generated
> artifacts when the artifact gate is invoked.

It also shows that one registry change can alter five declared outputs in the
frozen implementation, and that restoring the registry can restore the exact
frozen output bytes.

## Limits

- The frozen registry validation is shallow and does not validate every field,
  alias, duplicate, traversal, or collision.
- The five files are written sequentially, not transactionally.
- The broader path gate aggregates failures; it is not universally fail-fast.
- Warnings block only under strict mode.
- The generated schema is not itself invoked by the artifact gate used here.
- The path lint uses a fixed catalog and broad exclusions.
- The default usage audit checks only five keys and can count textual mentions
  as consumers. Its `--all` mode includes the removed tombstone and fails in the
  frozen tree.
- Matching generated bytes do not prove a runtime used the correct current
  value.
- The frozen tree does not prove provider-neutral CI enforcement.
- The exact consumer validator and downstream suppression are proof-harness
  behavior, not WarpOS features.
- This fixture covers one invented relative-value migration in one frozen
  commit. It does not prove production safety, security, or universal
  configuration correctness.

## Privacy and cleanup

The machine report persists the public repository URL, frozen commit and blob
IDs, invented relative values, relative file names, exit codes, decisions, and
hashes. It does not persist the local source-checkout path, an absolute Windows
path, email address, token-like prefix, authorization-header secret, private source,
or runtime data. Its privacy scan passed.

Both temporary archive directories were removed in `finally`, and each path was
independently checked as missing after removal.
