fix(web): correct the preset-layer contracts review found stale
None of these change behavior; each said something that was not true. `SessionCwdConflict`'s doc block had been left stranded above the `AgentPresetConflict` inserted under it, so one class carried a comment about the other and the second carried none. The roster comment named a `.system` directory that does not exist; the shipped root is `config/agent-presets/`, and `system` is the trust its entries carry. The real-composition test attributed the disabled `api-gateway` row to "side effects outside this process" alongside the port and the exporter. It is disabled for a different reason — the api-proxy cannot mount in this layer at all — and hiding that behind the same phrase would leave a later layer unable to tell whether the line can come out. One test claimed to refuse an adoption while asserting only that the header records the preset; it now says what it checks. `PERSONA_SECTION`/`PERSONA_ORDER` existed twice, once in the registry that declares the slot and once restated in the row that replaces it — a drift that would land a preset's persona beside the deployment's instead of shadowing it. The registry exports them now. The preset conflict message read "already runs agent preset undefined" for a session that records none, which is the shape a deployment with no roster produces; it names that case instead, with the regression that reaches it through the gateway. Finally, `PresetTree.write()` drops the `loader/config-update` the inherited method emits — recorded on the override, since a future edit-while-running flow needs its own persistence path.
This commit is contained in:
@@ -22,11 +22,17 @@ const WEB_OVERLAY = join(CONFIG_DIR, 'web.cordis.yml')
|
||||
async function bootWeb(): Promise<Context> {
|
||||
const patches: PatchOptions[] = [
|
||||
...loadOverlayPatches('dsh-test', WEB_OVERLAY),
|
||||
// Host rows with side effects outside this process.
|
||||
// Host rows with side effects outside this process: a bound port, a
|
||||
// served asset tree, a telemetry exporter.
|
||||
{ id: 'webserver', disabled: true },
|
||||
{ id: 'telemetry-otel', disabled: true },
|
||||
{ id: 'modules', disabled: true },
|
||||
{ id: 'connection', disabled: true },
|
||||
// NOT a side-effect row: the api-proxy cannot mount in THIS layer at all,
|
||||
// because it injects `subagents` and the subagent registry moved into the
|
||||
// presets here. That is the breakage a later layer returns to the host
|
||||
// plane; when it does, this line comes out and the boot audit covers the
|
||||
// whole host-plane injection graph again.
|
||||
{ id: 'api-gateway', disabled: true },
|
||||
{ id: 'directory-picker', disabled: true },
|
||||
// The roster AppCLIEntry would patch in; only the shipped root, so a
|
||||
@@ -134,6 +140,11 @@ describe('the shipped Web composition', () => {
|
||||
setup: agentCtx => ctx.agentPresets.mount(agentCtx, 'standard').then(() => undefined),
|
||||
})
|
||||
await handle.dispose()
|
||||
// Slack, not a race the number has to win. The write is driven by the
|
||||
// Loader's fiber-unload listener, which fires as the subtree's fibers
|
||||
// settle rather than when `dispose()` resolves, and the Loader exposes no
|
||||
// flush to await. A regression writes synchronously inside that listener,
|
||||
// so any wait past settlement fails; a longer one only slows the test.
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
|
||||
expect(await readFile(path, 'utf8')).toBe(before)
|
||||
@@ -185,7 +196,7 @@ describe('a forked session', () => {
|
||||
})
|
||||
|
||||
describe('a session keeps the preset it was created with', () => {
|
||||
it('refuses to adopt a live session under a different preset', async () => {
|
||||
it('records the preset the gateway guard reads', async () => {
|
||||
const handle = await ctx.agents.create({
|
||||
sessionId: SessionId('preset-locked'),
|
||||
meta: { agentPreset: 'core-web' },
|
||||
|
||||
Reference in New Issue
Block a user