aide records the architectural decisions a project has made and injects them into every session. That works right up until your project contains other projects: a superrepo full of submodules is really one estate with one set of opinions, but each subproject's store had no idea the others existed. As of v0.1.8, decisions travel: down from ancestors, and sideways between teams.
The Estate
aide now works out where it is (and what sits above it) from VCS evidence, with exactly one resolver:
aide anchor --json
Everything else reads that one answer, which also fixed a family of bugs where a session opened at the superrepo wrote into the wrong project's store. Sorry about those. Session context gains an Estate section (parents above, subprojects below), and aide-web draws the whole tree.
Inherit from Ancestors
Nothing to configure. At session start aide walks up the chain and overlays each ancestor's decisions onto your context, labelled with where they came from. A worked example: parent repo tl decides fav-colour = orange and team-editor = vim; the nested repo tl/webshop has its own store with api-style = REST and fav-colour = blue. A session inside webshop sees:
api-style: REST [local]
fav-colour: blue [local] <- shadows the parent's orange
team-editor: vim [parent: tl] <- inherited
Shadowing is by topic and nearest wins: webshop's blue means the parent's orange is never even looked at, and the parent is none the wiser. Nothing is copied between stores; provenance is synthesised at read time, so renaming or re-nesting a project can't corrupt anything. It isn't just plumbing, either: ask a headless Claude in each directory and the one in webshop explains that fav-colour is blue, decided locally, overriding the parent estate; the one in tl still answers orange. The labels carry the semantics, not just the values.
To override a parent, then, you just set your own (theirs stays intact upstream):
aide decision set fav-colour "blue"
To record a decision at the estate level instead, aim the write upwards:
aide --store parent decision set logging "slog, structured" # nearest container
aide --store top decision set go-version "1.26" # the estate root
And AIDE_CASCADE_DISABLED=1 switches the whole cascade off.
Subscribe to Peers
For teams that don't share a filesystem, subscriptions run over plain git. Name your sources in .aide/config/aide.json:
{ "subscriptions": [
{ "name": "platform-team", "url": "git@host:platform/context.git", "branch": "main" },
{ "name": "proto-repo", "path": "../protos" }
] }
That's the setup done: the next session start fetches them, and peer decisions appear in your context as a read-only layer labelled from peer platform-team. Where you override a parent, you adopt a peer:
aide decision adopt api-style --from=platform-team
which copies it into your store with adoption provenance. Add "publish": true to a subscription and the loop runs both ways: your own decisions go back out for others to subscribe to. Decisions only, mind; memories never cross a project boundary.
Why Not Just Import?
aide already had two ways to get decisions into a store from outside: blueprints (curated best-practice defaults you import when bootstrapping a project) and aide share import (a point-in-time merge from a directory a teammate exported). Both are copies, and both are exactly right for what they do: a blueprint is a template, and once imported the decision is genuinely yours to keep or overturn; a share import is one team converging one project's stores.
Copies are the wrong tool for a living ADR owned by somebody else, though. The platform team's api-style decision is theirs; they will re-decide it, and a copy you took in March says nothing about what they think in July. Copies rot, silently, and worse, they lie with confidence. A subscription is a reference: you always read the owning team's current word, it arrives labelled with where it came from, and it never leaks back out of your store (you can't accidentally re-publish somebody else's ADR as your own). Adoption is the deliberate act that turns a reference into a copy, with a stamp saying so. Ownership stays where the decision lives; that's the entire justification, and it's the same one that makes the ancestor cascade read at session start rather than syncing records downward.
The Session Is the Scheduler
My first instinct for the publishing side was a systemd timer, and it was wrong. Nothing here needs a scheduler, because aide already has one: the session lifecycle.
Decisions are only ever made inside sessions. So session start pulls (any subscription cache older than an hour is refreshed, quietly, offline-silent) and session end pushes (publish-enabled subscriptions ship whatever the session decided, bounded to a few seconds, silent if the network is away; unpublished records simply go out at the next session end). The event that creates the record is the event that ships it. If you find yourself writing a cron job for this, that's a bug report.
The other cases need even less. Inside a superrepo there's nothing to sync at all: the cascade reads the ancestor's store directly at session start, same disk, always current. And a team sharing one repo already has its sync mechanism: the context records are files that commit with the repo, so git pull is the import, git push is the publish, and a pull request is the review process. Teams that want ADR changes reviewed before they propagate can publish through a PR into the context repo instead of enabling the automatic path; subscribers can't tell the difference. aide sync survives as the manual lever, and it exits non-zero when a subscription fails, for the CI-inclined who want a red light rather than silence.
Precedence in one line: local beats nearest ancestor, ancestors beat peers. Your project gets the last word; it just no longer starts the conversation ignorant.
