Skip to content

#1068 Deliver ambient rulebooks mechanically, retiring GLOBAL.md - #1075

Merged
williamthorsen merged 10 commits into
mainfrom
1068
Jul 23, 2026
Merged

#1068 Deliver ambient rulebooks mechanically, retiring GLOBAL.md#1075
williamthorsen merged 10 commits into
mainfrom
1068

Conversation

@williamthorsen

@williamthorsen williamthorsen commented Jul 23, 2026

Copy link
Copy Markdown
Owner

What

A rule declared in a rulebook holds in every session, on both Claude Code and Rovo Dev. Previously it held only when an agent chose to look it up, so one session could obey it and the next ignore it, with nothing to show which had happened. Claude Code's built-in Explore and Plan agents are the exception; they do not pick up global rules.

Machine-specific guidance can be declared through a local source rather than committed to the repository.

~/.agents/GLOBAL.md is retired: sync --global removes it, preserving any hand-written content. Upgrading requires running install once before the first sync --global.

Why

A rulebook declared ambient reached an agent's context only when that agent elected to follow a discovery instruction and read the file holding it. The omission was silent by construction: no error, no failing check, and a skipped read indistinguishable from a read whose rules went unapplied. Declared guidance could therefore go missing with nothing to signal it, and captured sessions record both failure modes.

Details

🎉 Features

  • A co-writing contract lets install and sync share one file: the guidance templates carry an empty region delimited by <!-- codeassembly-ambient:start --> / <!-- codeassembly-ambient:end -->, so the region's location is install's and its content is sync's. ambient-region.ts supplies the transforms as pure string functions.
  • install splices existing region content into every re-render and excludes it from drift detection. computeContentHash strips region content before hashing; files carrying no markers hash over their raw bytes unchanged, so stored hashes stay valid and no manifest migration is required.
  • sync --global injects the resolved ambient set into each targeted harness's region, regenerating it wholesale on each run. HarnessConfig gains guidanceFileName so the target resolves per harness.
  • A guidance file that is missing or carries no region is skipped with a warning naming the remedy, so a not-yet-upgraded install degrades delivery for that harness alone rather than failing the sync.
  • sync --global retires a legacy ~/.agents/GLOBAL.md: sync-owned blocks are stripped, and the file is deleted only when nothing hand-written remains.

🐛 Bug fixes

  • sync --global --dry-run probes each targeted guidance file and previews the skip the real run would take, rather than promising an injection the run would decline.

♻️ Refactoring

  • SyncDomain's ambientHostPath becomes a discriminated ambient union — host-file for the repo domain, harness-regions for the home domain — so the home domain no longer names a host file it does not write, and the compiler rules out reaching host-file logic without a path.
  • Ambient delivery, host-file state reading, dry-run target description, and legacy retirement move out of reconcileDomain into named helpers. probeAmbientTarget is the single classification the real run and the dry-run reporter both consume, which is what keeps the two in agreement.

🧪 Tests

  • ambient-region.test.ts covers the shapes that break string-region code: absent region, empty region, unclosed open marker, unpaired close marker, idempotent re-injection, and bodies containing $-sequences.
  • Install tests pin the splice across a deliberately changed template (so preservation is exercised as a genuine splice, not a skipped re-render), region content excluded from drift, hand edits outside the region still detected as drift, and hash equality across an empty and a filled region.
  • Sync tests cover per-harness injection, both warn-and-skip paths, dry-run previews for injection and for skip, and all three legacy-retirement paths plus the dry-run guard ahead of the delete.

📚 Documentation

  • The project-discovery instruction now names only reads that remain an agent's responsibility; the GLOBAL.md and preferences.yaml lines are dropped.
  • README.md and content/guidance/README.md document the region contract, the install-before-sync --global upgrade order, and the machine-local source channel for per-machine ambient content, including the guidance/rulebooks/<slug>.md layout it requires.
  • The mechanical-delivery claim is scoped to the home domain; the project domain's bullet names its own bridge and states that delivery there carries no mechanical guarantee until the repo wires the import.

Closes #1068

…iles

Adds the string transforms that manage the codeassembly-owned ambient region inside a harness guidance file: the region sync fills with ambient guidance and install preserves across re-renders.
…emplate

Installed harness guidance files (~/.claude/CLAUDE.md and ~/.rovodev/AGENTS.md) now carry an empty, marker-delimited ambient region that a later sync fills with ambient guidance.
Re-running install keeps whatever sync wrote into a guidance file's ambient region, and drift detection ignores region content: only hand edits outside the region make install treat the file as user-modified.
…sync --global

sync --global now delivers ambient rulebooks into the ambient region of each targeted harness's guidance file (~/.claude/CLAUDE.md, ~/.rovodev/AGENTS.md), the files the harnesses load mechanically, instead of writing ~/.agents/GLOBAL.md for agents to read on their own initiative.

A guidance file that is missing or predates the ambient region is skipped with a warning directing to `codeassembly-agents install`; the rest of the sync proceeds. Dry-run previews the region writes.
…nc --global

sync --global removes the sync-owned rulebook blocks from an existing ~/.agents/GLOBAL.md, deletes the file when nothing else remains, and preserves any hand-authored content by leaving the stripped remainder in place.
… regions

The project-discovery instruction no longer asks agents to read ~/.agents/GLOBAL.md or .agents/preferences.yaml; ambient guidance arrives mechanically and preferences are consumed by tooling at the point of need, so the section names only the read that remains an agent's responsibility.

Documentation now covers the ambient-region contract between install and sync --global, the install-before-sync upgrade order, GLOBAL.md retirement, and the machine-local source channel for per-machine ambient guidance kept out of source control.
…ciler

Moves host-file inlining, ambient-host reading, and dry-run target description into named helpers so the reconciler and reporter stay under the complexity ceiling, and replaces reduce chains with loops per the lint rules.
sync --global --dry-run now probes each targeted guidance file and previews the same skip the real run would take when the file is missing or carries no ambient region, instead of promising an injection the run then declines. The preview and the run share one probe, so they cannot diverge.

Also pins that a dry run leaves a legacy ~/.agents/GLOBAL.md untouched.
The guidance README no longer implies project-scope ambient rulebooks reach agents mechanically: only home-scope delivery carries that guarantee, and the project bullet now names the bridge each repo wires (the discovery line or a per-repo import).
@williamthorsen williamthorsen added feature Added or improved external functionality scope:agents labels Jul 23, 2026
@github-actions

Copy link
Copy Markdown

Dependency audit

Production dependency audit passed.

@williamthorsen williamthorsen self-assigned this Jul 23, 2026
@williamthorsen
williamthorsen marked this pull request as ready for review July 23, 2026 01:53
@williamthorsen
williamthorsen merged commit c051e46 into main Jul 23, 2026
3 checks passed
@williamthorsen
williamthorsen deleted the 1068 branch July 23, 2026 01:56
williamthorsen added a commit that referenced this pull request Aug 4, 2026
…e-v0.2.2 codeassembly-v0.4.0 factory-v0.2.2 codeassembly-mcp-v0.2.2

codeassembly-v0.4.0
- #1153 feat: Make codeassembly and kb CLI tools publishable (#1164)
- #1091 fix: Anchor a project-deployed link where its target deploys (#1159)
- #1156 refactor: Rename packages to publishable names (#1157)
- #1152 tooling: Run every test in the default gate, classified by what it reaches (#1155)
- #1110 tooling: Migrate Vitest to nmr's centralized model (#1154)
- refactor: Refine typescript-preferences
- #1150 fix: State doc-description form and make comment mood opt-in (#1151)
- deps: Upgrade first-party linting deps to latest version
- #1137 feat: Establish personal rulebooks for code layout and TypeScript preferences (#1144)
- #1126 feat: Check a package's own guidance content before it ships (#1138)
- refactor: Fix lint
- tooling: Remove redundant lint rules
- #1133 fix: Reject an anchor link that names no heading (#1135)
- #1122 feat: Capture lede decisions as an accumulating corpus (#1132)
- #1125 feat: Honor invocation tokens in rulebook bodies (#1129)
- #1107 feat: Render rulebook links and path tokens per harness (#1124)
- #1115 feat: Sync guidance at build and install so an upgrade cannot leave it stale (#1123)
- #1114 feat: Adopt a dependency's guidance by naming the package (#1121)
- #1088 feat: Deliver project ambient rulebooks per harness (#1113)
- #1087 refactor: Rename the authoring rulebook and mark its enforced rules (#1092)
- #1095 tooling: Move compilation out of the install lifecycle into a bootstrap step (#1102)
- #1094 refactor: Remove the ambient ripgrep dependency from the test suite (#1097)
- deps: Upgrade all deps to latest version
- tooling: Upgrade all deps to latest version & modernize configs
- refactor: Fix lint
- #1077 feat: Show the proposed edit above post-review menu options (#1078)
- #1068 feat: Deliver ambient rulebooks mechanically, retiring GLOBAL.md (#1075)
- #1069 feat: Add a no-second-person rule to the lede-voice doctrine (#1070)
- #1050 feat: Add a redundancy rule to the lede-voice doctrine (#1058)
- #1035 internal: Add lifecycle workspace with the canonical envelope, vocabulary & lane fold (#1049)
- #1006 internal: Extend lifecycle-event instrumentation to five high-traffic skills (#1034)
- #1028 feat: Rule out absence-of-removed-code tests (#1032)
- #114 feat: Let reviewers emit gated insights into review artifacts (#1031)
- #1027 internal: Retire input.received and redundant skill.progress emits (#1030)
- #1026 fix: Name the side effects an approval ask authorizes (#1029)
- #1022 fix: Normalize action and question label identifiers across asks blocks (#1025)

factory-v0.2.2
- #1156 refactor: Rename packages to publishable names (#1157)
- deps: Upgrade all deps to latest version
- #1152 tooling: Run every test in the default gate, classified by what it reaches (#1155)
- #1110 tooling: Migrate Vitest to nmr's centralized model (#1154)
- tooling: Remove redundant lint rules
- deps: Upgrade deps to latest version
- deps: Upgrade all deps to latest version
- deps: Upgrade all deps to latest version
- tooling: Upgrade all deps to latest version & modernize configs
- refactor: Fix lint
- deps: Upgrade all deps to latest version

kb-v0.3.0
- #1153 feat: Make codeassembly and kb CLI tools publishable (#1164)
- #1156 refactor: Rename packages to publishable names (#1157)
- #1152 tooling: Run every test in the default gate, classified by what it reaches (#1155)
- #1110 tooling: Migrate Vitest to nmr's centralized model (#1154)
- tooling: Remove redundant lint rules
- #1095 tooling: Move compilation out of the install lifecycle into a bootstrap step (#1102)
- tooling: Upgrade all deps to latest version & modernize configs
- refactor: Fix lint

codeassembly-lifecycle-v0.2.0
- #1153 feat: Make codeassembly and kb CLI tools publishable (#1164)
- #1156 refactor: Rename packages to publishable names (#1157)
- #1152 tooling: Run every test in the default gate, classified by what it reaches (#1155)
- #1110 tooling: Migrate Vitest to nmr's centralized model (#1154)
- tooling: Remove redundant lint rules
- #1095 tooling: Move compilation out of the install lifecycle into a bootstrap step (#1102)
- tooling: Upgrade all deps to latest version & modernize configs
- #1038 feat: Add the read-only git adapter for worktree and base-branch ground truth (#1059)
- #1051 feat: Bound fold memory and rescan cost with a retention window (#1057)
- #1035 internal: Add lifecycle workspace with the canonical envelope, vocabulary & lane fold (#1049)

codeassembly-mcp-v0.2.2
- deps: Upgrade all deps to latest version
- #1156 refactor: Rename packages to publishable names (#1157)
- #1152 tooling: Run every test in the default gate, classified by what it reaches (#1155)
- #1110 tooling: Migrate Vitest to nmr's centralized model (#1154)
- #1095 tooling: Move compilation out of the install lifecycle into a bootstrap step (#1102)
- tooling: Upgrade all deps to latest version & modernize configs
- refactor: Fix lint

codeassembly-run-core-v0.2.2
- #1156 refactor: Rename packages to publishable names (#1157)
- #1152 tooling: Run every test in the default gate, classified by what it reaches (#1155)
- #1110 tooling: Migrate Vitest to nmr's centralized model (#1154)
- #1095 tooling: Move compilation out of the install lifecycle into a bootstrap step (#1102)
- tooling: Upgrade all deps to latest version & modernize configs
- refactor: Fix lint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Added or improved external functionality scope:agents

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deliver ambient guidance by injection into harness guidance files, retiring GLOBAL.md

1 participant