mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-07 22:58:42 -10:00
feat(review): mark unauthored mini-requirements as non-compliant in the plan section
Stage-3 Lever C (Stage-1): the composer already returns plan.concise.text === null iff the mini-requirements are not authored. The SliceReviewTab plan section now names that non-compliance honestly — a static, non-interactive attention marker (testid plan-mini-reqs-noncompliant, copy "Not compliant · mini-requirements not authored", the existing amber attention styling) — in place of the terse "— not planned yet" dash, in the SAME text===null branch. Presentation-only: renders in every phase (no phase gate), suppresses no sibling (media / locked set / plan-lock all render as before), adds no state/fetch/control/ abstraction, and changes no composer or data contract. "Visible does not block." Tests (flagship-review-polish.test.tsx): the marker renders for post-intent and intent-phase null-text (the no-phase-gate pin), stays absent for authored text (Markdown renders), and — with media + locked siblings — renders alongside both while the marker element itself carries no interactive descendants (scoped to the marker; locked-set EvidenceOpeners remain valid controls). Carried caveat (pre-existing, unrelated, NOT touched): the mission-status-reconcile "named RED at base" failure (partitionProjectMissions bucketing) is independent of this review-plan-section change. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
1 parent
c42c587914
commit
1a8e56edbe
2 files changed
+68
-1
No files matched your search
@@ -297,7 +297,13 @@ export function SliceReviewTab({
|
||||
{data.plan.concise.text ? (
|
||||
<MarkdownViewer content={data.plan.concise.text} hideFrontmatter hideRawToggle />
|
||||
) : (
|
||||
<p className="font-mono text-[11px] text-on-surface-variant">— not planned yet</p>
|
||||
// Stage-3 Lever C (Stage-1): the composer already returned text===null iff the
|
||||
// mini-requirements are not authored — name that non-compliance honestly (a
|
||||
// static, non-interactive attention marker) instead of the terse dash. Renders
|
||||
// in every phase; presentation-only, suppresses no sibling.
|
||||
<p data-testid="plan-mini-reqs-noncompliant" className="font-mono text-[11px] text-amber-700 dark:text-amber-400">
|
||||
Not compliant · mini-requirements not authored
|
||||
</p>
|
||||
)}
|
||||
{data.plan.concise.media.length > 0 ? (
|
||||
<div className="flex flex-wrap gap-3">
|
||||
|
||||
@@ -274,4 +274,65 @@ describe("flagship attempt-0003 Review polish", () => {
|
||||
expect(header.textContent).toContain("completion ledger");
|
||||
expect(within(header).getByTestId("cut-complete").textContent).toContain("cut-gating COMPLETE");
|
||||
});
|
||||
|
||||
// ===================================================================
|
||||
// STAGE-3 LEVER C (Stage-1) — "not compliant: mini-reqs" render marker.
|
||||
// REV3 d9fa8a2e §5. TEST-ONLY: RED-1/RED-2/RED-3 fail because the marker
|
||||
// element (testid plan-mini-reqs-noncompliant) does not exist yet; the
|
||||
// compliant companion is GREEN today. The marker renders whenever
|
||||
// data.plan.concise.text === null, in EVERY phase (D1: NO phase gate),
|
||||
// presentation-only; copy is FROZEN (D2). They become regression pins when
|
||||
// the marker lands (a SEPARATE Guard-gated GREEN dispatch on SliceReviewTab).
|
||||
// ===================================================================
|
||||
const MARKER_TID = "plan-mini-reqs-noncompliant";
|
||||
const MARKER_COPY = "Not compliant · mini-requirements not authored";
|
||||
const planNull = { concise: { text: null, media: [] }, lockedArtifacts: [], lock: null, ssotPath: null };
|
||||
const renderSlice = () => render(withQuery(<SliceReviewTab sliceName="04-review-tab-observability" slicePath={null} />));
|
||||
|
||||
it("LeverC RED-1 (post-intent non-compliance): phase=spec + plan.concise.text===null renders the frozen marker with exact copy", () => {
|
||||
sliceState.data = sliceReview({ phase: "spec", plan: planNull } as Partial<ComposedSliceReview>);
|
||||
renderSlice();
|
||||
const marker = screen.getByTestId(MARKER_TID); // <-- RED: marker element absent (writer unbuilt)
|
||||
expect(marker.textContent).toBe(MARKER_COPY);
|
||||
});
|
||||
|
||||
it("LeverC RED-2 (intent no-gate PIN, D1): phase=intent + text===null renders the SAME marker — no phase gate suppresses it", () => {
|
||||
sliceState.data = sliceReview({ phase: "intent", plan: planNull } as Partial<ComposedSliceReview>);
|
||||
renderSlice();
|
||||
const marker = screen.getByTestId(MARKER_TID); // <-- RED: marker element absent
|
||||
expect(marker.textContent).toBe(MARKER_COPY);
|
||||
});
|
||||
|
||||
it("LeverC GREEN companion (compliant): authored plan text renders Markdown and NO marker", () => {
|
||||
sliceState.data = sliceReview({
|
||||
phase: "spec",
|
||||
plan: { concise: { text: "1. Author the mini-requirements", media: [] }, lockedArtifacts: [], lock: null, ssotPath: null },
|
||||
} as Partial<ComposedSliceReview>);
|
||||
renderSlice();
|
||||
const planSection = screen.getByTestId("plan-section");
|
||||
expect(within(planSection).queryByTestId(MARKER_TID)).toBeNull(); // compliant -> no marker
|
||||
expect(within(planSection).getByTestId("markdown-viewer")).toBeTruthy(); // the authored plan renders
|
||||
});
|
||||
|
||||
it("LeverC RED-3 (preservation + MARKER-SCOPED non-interactive): text===null WITH media + locked siblings renders the marker AND both siblings; the marker element itself is non-interactive", () => {
|
||||
sliceState.data = sliceReview({
|
||||
plan: {
|
||||
concise: { text: null, media: [{ kind: "video", src: "data:video/mp4;base64,AAAA", caption: "plan clip" }] },
|
||||
lockedArtifacts: [{ name: "Implementation PRD", path: "IMPLEMENTATION-PRD.md", kind: "spec" }],
|
||||
lock: null,
|
||||
ssotPath: null,
|
||||
},
|
||||
} as Partial<ComposedSliceReview>);
|
||||
renderSlice();
|
||||
const marker = screen.getByTestId(MARKER_TID); // <-- RED: marker element absent
|
||||
expect(marker.textContent).toBe(MARKER_COPY);
|
||||
// both plan-section siblings still render (the marker suppresses nothing).
|
||||
expect(screen.getByTestId("review-inline-video")).toBeTruthy(); // media sibling
|
||||
expect(screen.getByTestId("plan-locked-set")).toBeTruthy(); // locked-set sibling
|
||||
// non-interactive oracle SCOPED TO THE MARKER ELEMENT ONLY (locked-set EvidenceOpeners are valid controls).
|
||||
expect(["A", "BUTTON"]).not.toContain(marker.tagName);
|
||||
expect(marker.getAttribute("role")).not.toBe("button");
|
||||
expect(marker.getAttribute("role")).not.toBe("link");
|
||||
expect(marker.querySelectorAll("a, button, input, select, textarea, [role='button'], [role='link']").length).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user