docs(prd): inline #88 rationale into PRD 0025
Add an "Alternatives considered" section enumerating the design options from issue #88 (duplicate bottles / agent-side bottle_config / bottle-side extends) and why extends won, so the PRD stands without the forge thread. Repoint the two phrases that depended on the #88 comment thread at the new section. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,41 @@ trust boundary*: only `$HOME` bottles can declare it, only `$HOME`
|
|||||||
bottles can be its target. Cloned repos still cannot author
|
bottles can be its target. Cloned repos still cannot author
|
||||||
bottle-equivalent config.
|
bottle-equivalent config.
|
||||||
|
|
||||||
|
## Alternatives considered
|
||||||
|
|
||||||
|
The question raised in issue #88 was *where composition should live*.
|
||||||
|
Three points in that design space, recorded here so the decision
|
||||||
|
stands on its own without the issue thread:
|
||||||
|
|
||||||
|
1. **Duplicate bottles (status quo).** Copy `dev.md` to `staging.md`
|
||||||
|
and edit. Zero new mechanism, but every shared field drifts: a
|
||||||
|
route added to `dev` is silently missing from `staging`. This is
|
||||||
|
the pain that prompted #88.
|
||||||
|
|
||||||
|
2. **Agent-side `bottle_config:` override (the original #88
|
||||||
|
proposal).** Let an agent file carry an inline block that merges
|
||||||
|
over its referenced bottle. Ergonomically attractive — one file,
|
||||||
|
no second bottle — but it **breaks the trust boundary**: agent
|
||||||
|
files can come from `$CWD/.bot-bottle/agents/` in a cloned repo, so
|
||||||
|
a clone could redeclare egress routes, env mappings, and git
|
||||||
|
remotes — i.e. grant itself bottle-equivalent authority over
|
||||||
|
credentials and network egress. The home-only-bottle invariant
|
||||||
|
exists precisely to stop this.
|
||||||
|
|
||||||
|
3. **Bottle-side `extends:` (chosen).** Move composition to the
|
||||||
|
bottle layer, where it inherits the home-only property for free:
|
||||||
|
only `$HOME` bottles can declare `extends:`, and only `$HOME`
|
||||||
|
bottles can be its target. Identical duplication relief to option
|
||||||
|
2, none of its trust erosion. The cost is that an override requires
|
||||||
|
a (home-owned) child bottle rather than an inline agent block —
|
||||||
|
which is the *point*: the override authority stays in `$HOME`.
|
||||||
|
|
||||||
|
`extends:` wins because it solves the duplication pain entirely on the
|
||||||
|
trusted side of the agent-vs-bottle boundary. (PRD 0027 later lifts a
|
||||||
|
deliberately narrow, non-credential field — `git.user` — to the agent
|
||||||
|
layer, on the separate reasoning that commit identity is not a
|
||||||
|
capability; egress, credentials, and remotes stay bottle-only.)
|
||||||
|
|
||||||
## Goals / Success Criteria
|
## Goals / Success Criteria
|
||||||
|
|
||||||
- Add `extends: <bottle-name>` to the bottle frontmatter schema.
|
- Add `extends: <bottle-name>` to the bottle frontmatter schema.
|
||||||
@@ -58,9 +93,9 @@ bottle-equivalent config.
|
|||||||
|
|
||||||
## Non-goals
|
## Non-goals
|
||||||
|
|
||||||
- **No agent-side `bottle_config:`.** That's the design issue #88
|
- **No agent-side `bottle_config:`.** Option 2 under "Alternatives
|
||||||
considered and weighed against; this PRD is the alternative
|
considered" — weighed and rejected on trust grounds. Don't
|
||||||
picked in the issue's design discussion. Don't reintroduce it.
|
reintroduce it.
|
||||||
- **No additive list merges** (e.g., `routes: append` keyword).
|
- **No additive list merges** (e.g., `routes: append` keyword).
|
||||||
The `extends:` design uses full-replace for list-valued fields
|
The `extends:` design uses full-replace for list-valued fields
|
||||||
(see "Merge rules"); if a use case shows up that genuinely
|
(see "Merge rules"); if a use case shows up that genuinely
|
||||||
@@ -167,7 +202,7 @@ Bottles continue to be loaded from `$HOME/.bot-bottle/bottles/`
|
|||||||
only (`Manifest.from_md_dirs` is unchanged). The `extends:` field
|
only (`Manifest.from_md_dirs` is unchanged). The `extends:` field
|
||||||
references another file in that same directory. No cwd-readable
|
references another file in that same directory. No cwd-readable
|
||||||
file gains the ability to declare or modify bottle config — the
|
file gains the ability to declare or modify bottle config — the
|
||||||
attack surface from issue #88's comment thread stays closed.
|
attack surface from option 2 ("Alternatives considered") stays closed.
|
||||||
|
|
||||||
If a future change ever introduces cwd-loaded bottles, the
|
If a future change ever introduces cwd-loaded bottles, the
|
||||||
`extends:` resolver should be gated to forbid a `$CWD` bottle
|
`extends:` resolver should be gated to forbid a `$CWD` bottle
|
||||||
|
|||||||
Reference in New Issue
Block a user