fix: a delegated session inherits the facet it was spawned under
Release / release (push) Successful in 6s
Release / release (push) Successful in 6s
The user's declaration is keyed by session id, and a session spawned or forked from a scoped one has none of its own — so its facet was its own working directory, one level above its parent's. Delegation was therefore a way around the scope rather than work inside it: the parent could not read the file itself and could have a subagent read it. A session now inherits the root resolved for the session named by its `parentSession` header, which the harness already records durably for both a spawned child and a fork. The inherited root is the parent's *effective* root, so it already includes any narrowing the parent made for itself: delegating is not a way back out of a self-imposed focus either. Because each session records its own root as it resolves a scope, and a scope is resolved for every model request and every tool call, inheritance holds at any depth of delegation rather than for one hop. Two boundaries are deliberate. A declaration the user made *for the child* is a more specific statement about that session and stands — inheritance only answers the case where they made none. And a parent's recorded root outlives its session while any child that inherited it is still running, because disposing a parent must not quietly widen a subagent that is still working.
This commit is contained in:
1 parent
a9a25490db
commit
8ab3299694
4 files changed
+245
-11
No files matched your search
@@ -154,6 +154,15 @@ and your root otherwise. So an agent that goes wrong cannot widen its own scope,
|
||||
and `facet action=reset` returns it to what you declared rather than to the
|
||||
session directory — landing on the directory would have made `reset` a widening.
|
||||
|
||||
**A session spawned or forked from a scoped one inherits its root.** Your
|
||||
declaration is keyed by session id, and a subagent or a fork has none of its own,
|
||||
so without this its facet would be its own working directory — one level up, and
|
||||
a way to delegate around the scope rather than work inside it. The inherited root
|
||||
already includes the parent's own narrowing, so delegating is not a way back out
|
||||
of a focus the agent set for itself either, and it is recorded per level, so it
|
||||
holds at any depth of delegation. It applies only where you made no statement:
|
||||
a declaration for the child session is the more specific answer and stands.
|
||||
|
||||
You set the declaration from the **crosshair button on the composer tool row**,
|
||||
which appears only in sessions running the `facet` preset. It shows the focus and
|
||||
the allowed paths, adds and removes them, and carries the mode details and usage
|
||||
@@ -237,7 +246,7 @@ Honest boundaries, because each one is a decision rather than an oversight:
|
||||
|
||||
Verified:
|
||||
|
||||
- 81 tests (`npm test`) over the scope algebra, the policy state, the guard, and
|
||||
- 88 tests (`npm test`) over the scope algebra, the policy state, the guard, and
|
||||
the browser half — including that containment is decided on canonical targets
|
||||
(a symlink inside the facet pointing outside it is refused), that a prefix is
|
||||
not a parent (`/a/room` does not contain `/a/roommate`), that a malformed tool
|
||||
@@ -245,8 +254,10 @@ Verified:
|
||||
without the guard being remounted, that an agent narrowing the user has since
|
||||
narrowed past is dropped rather than honoured, that `reset` lands on the
|
||||
declared scope rather than the session directory, that a search naming no path
|
||||
is refused when the directory it defaults to is outside the facet, and that
|
||||
every `facet` result satisfies the tool's own declared output schema.
|
||||
is refused when the directory it defaults to is outside the facet, that a
|
||||
delegated session inherits its parent's root at any depth and is not a way back
|
||||
out of a self-narrowing, and that every `facet` result satisfies the tool's own
|
||||
declared output schema.
|
||||
- The bundle's patch layers parse, merge and land correctly against the real
|
||||
profile: `dsh --profile web --patch ./cordis.patch.yml --patch
|
||||
./presets/facet.patch.yml --dump-config` shows `facet-policy`, `preset-facet`,
|
||||
@@ -324,7 +335,7 @@ lib/scope.js the pure half — argument extraction, text, reason
|
||||
lib/guard.js preset row: rule, binding, tool, pre-execute guard
|
||||
presets/facet.patch.yml the `facet` agent preset
|
||||
presets/standard-compaction.patch.yml optional: the same budget for `standard`
|
||||
test/ 81 tests
|
||||
test/ 88 tests
|
||||
```
|
||||
|
||||
`client/client.js` is a browser half rather than a module the host imports, and
|
||||
|
||||
Reference in new issue
Block a user