Affiche les annonces d'agent en direct au-dessus des cellules, sur la base develop : - announcements: nouveau feature module — store réactif, provider d'abonnement aux événements, overlay par cible et aperçu, avec tests (announcementsStore + provider). - App.tsx: montage du provider dans l'arbre applicatif. - domain/index.ts: types partagés de l'événement d'annonce côté front. - layout: composition de l'overlay dans LayoutGrid + règle d'exclusion couverte par overlayExclusion.test.ts. - AgentsPanel: intègre l'aperçu des annonces dans la surface existante. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
2.4 KiB
TypeScript
59 lines
2.4 KiB
TypeScript
/**
|
|
* Ticket #4 — mutual exclusion of the two full-cell veils in a `LeafView`
|
|
* (Architect arbitrage `ticket4-overlay-composition-leafview`).
|
|
*
|
|
* `shouldShowWritePortalVeil` is the exact predicate the JSX uses to gate the
|
|
* write-portal veil; the F3 target overlay self-gates on the *same* `busyActive`
|
|
* source (`useTargetAnnouncements(agentId).active`). Testing this predicate
|
|
* therefore proves the on-screen invariant: exactly one veil at a time, F3 first.
|
|
*/
|
|
|
|
import { describe, it, expect } from "vitest";
|
|
|
|
import { shouldShowWritePortalVeil } from "./LayoutGrid";
|
|
|
|
/** Mirrors the F3 overlay's own render guard (`active` ⇔ busy). */
|
|
const showsF3 = (agentPinned: boolean, busyActive: boolean) =>
|
|
agentPinned && busyActive;
|
|
|
|
describe("shouldShowWritePortalVeil — veil exclusion", () => {
|
|
it("hides the write-portal veil while F3 is active (busy), whatever the portal says", () => {
|
|
// The nominal inter-agent injection path: overlay AND busy rise together.
|
|
expect(shouldShowWritePortalVeil(true, true, true)).toBe(false);
|
|
// Busy without a portal request: still no write-portal veil.
|
|
expect(shouldShowWritePortalVeil(true, false, true)).toBe(false);
|
|
});
|
|
|
|
it("shows the write-portal veil as the fallback when busy is not (yet) set", () => {
|
|
expect(shouldShowWritePortalVeil(true, true, false)).toBe(true);
|
|
});
|
|
|
|
it("shows no write-portal veil when the portal is idle", () => {
|
|
expect(shouldShowWritePortalVeil(true, false, false)).toBe(false);
|
|
});
|
|
|
|
it("never shows the write-portal veil for a plain (agent-less) cell", () => {
|
|
expect(shouldShowWritePortalVeil(false, true, true)).toBe(false);
|
|
expect(shouldShowWritePortalVeil(false, true, false)).toBe(false);
|
|
});
|
|
|
|
it("NEVER renders both veils simultaneously (exhaustive truth table)", () => {
|
|
for (const agentPinned of [false, true]) {
|
|
for (const overlay of [false, true]) {
|
|
for (const busyActive of [false, true]) {
|
|
const writePortal = shouldShowWritePortalVeil(
|
|
agentPinned,
|
|
overlay,
|
|
busyActive,
|
|
);
|
|
const f3 = showsF3(agentPinned, busyActive);
|
|
// The safety invariant: the two full-cell veils are mutually exclusive.
|
|
expect(writePortal && f3).toBe(false);
|
|
// And F3 has priority: whenever it is up, the write-portal veil is down.
|
|
if (f3) expect(writePortal).toBe(false);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|