diff --git a/CHANGELOG.md b/CHANGELOG.md index e746e393..1f954033 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to the claude-plugins project will be documented in this fil The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Entries are listed newest-first; each plugin section is treated as released when merged to `main`. +### vibe v1.0.51 + +#### Added +- A Data direction readiness item in cl-execute's `planning-and-gates.md`: a new direction of data flow between surfaces (cloud to an installed client, a client into another tool's data, one service writing into another's store) needs a cited human decision or approved document traced per Decision provenance; an earlier document that restricts the direction is a conflict, and with no traced decision it is a numbered human decision. The plan-review prompt mirrors it in one DECISIONS line. +- `cl-analyze` gains Decision provenance and Data direction readiness checks that point to those cl-execute definitions, and both items in its result's Readiness list. +- cl-execute's `CL Execute Gate Result` Readiness list reports Decision provenance and Data direction, so the gate reports the items it checks. +- In vibe, the requirements worker flags a new data direction in its brief as `data direction (new)` with its source or `untraced`; the change worker builds only along directions already allowed and logs an untraced one as an `Engineering decision`, never a question for the person; the guardrails reviewer treats an untraced new direction in the diff as a blocking `engineering decision` finding. +- `test_vibe_data_direction_contract.py` and a `skill-contract.test.mjs` case pin these rules; both fail on 1.0.50. + +#### Changed +- A write into another tool's data covers its files and its API or IPC (for example a method that changes that tool's stored state). A supported interface lowers the risk but does not remove the need for a traced human decision. The guardrails reviewer's Mechanisms check (item 12) and cl-execute's Data direction item state both, the plan-review prompt names API and IPC writes as mechanisms and says a supported interface is not the decision, the change and requirements workers name API and IPC writes, and planning step 13 adds that moving such a write to a supported interface does not settle whether the write is allowed. +- `cl-analyze` counts a decision as documented for the `EXTREME` risk rule only when it traces to a human statement (who, where, which question); a ticket's or plan's Decisions section alone is a record, not a ruling. + ### vibe v1.0.50 #### Fixed diff --git a/plugins/vibe/.claude-plugin/plugin.json b/plugins/vibe/.claude-plugin/plugin.json index 8634bd65..07302ea8 100644 --- a/plugins/vibe/.claude-plugin/plugin.json +++ b/plugins/vibe/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "vibe", "description": "Vibe sessions, handoff, seed refresh, and ClosedLoop ticket workflows", - "version": "1.0.50", + "version": "1.0.51", "dependencies": ["closedloop-core"], "author": {"name": "ClosedLoop", "email": "support@closedloop.ai"} } diff --git a/plugins/vibe/.codex-plugin/plugin.json b/plugins/vibe/.codex-plugin/plugin.json index 9c6bf6ab..2b676474 100644 --- a/plugins/vibe/.codex-plugin/plugin.json +++ b/plugins/vibe/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "vibe", - "version": "1.0.50", + "version": "1.0.51", "description": "Vibe sessions, handoff, seed refresh, and ClosedLoop ticket workflows", "author": {"name": "ClosedLoop", "email": "support@closedloop.ai"}, "homepage": "https://github.com/closedloop-ai/claude-plugins", diff --git a/plugins/vibe/agents/vibe-change-worker.md b/plugins/vibe/agents/vibe-change-worker.md index 0beac1a3..9c41de96 100644 --- a/plugins/vibe/agents/vibe-change-worker.md +++ b/plugins/vibe/agents/vibe-change-worker.md @@ -115,16 +115,25 @@ requested scope. Only the outcome a ticket or PRD asks for binds the session. A mechanism it names (a poller, feed, lane, socket, route, table, cursor, or a write into -another tool's data) is a proposal held to the same test as one you invent. -If it is dominated (its cost scales with installs or idle time while an -alternative scales with activity, or a supported interface exists for a write -into another tool's data), build the better option that meets the outcome and -log the swap in the change log as `Engineering decision: ; built: -; evidence: ` for the live -ticket's Engineering checklist (`ticket-template.md`, "Engineering -decisions"). It is never `NEEDS_PERSON`. Raising and recording it is neither -instruction inflation nor manufactured ambiguity: those rules protect settled -rulings, and an unexamined mechanism is not one. +another tool's data through its files, API or IPC) is a proposal held to the +same test as one you invent. If it is dominated (its cost scales with installs +or idle time while an alternative scales with activity, or a supported +interface exists for a write into another tool's data), build the better +option that meets the outcome and log the swap in the change log as +`Engineering decision: ; built: ; evidence: +` for the live ticket's Engineering checklist +(`ticket-template.md`, "Engineering decisions"). It is never `NEEDS_PERSON`. +Raising and recording it is neither instruction inflation nor manufactured +ambiguity: those rules protect settled rulings, and an unexamined mechanism is +not one. + +Build the outcome only along data directions that are already allowed. A new +direction of data flow between surfaces +(`../skills/cl-execute/references/planning-and-gates.md`, Readiness Gate, +"Data direction") that traces to no human decision is not built; log it as +`Engineering decision: ; built: ; evidence: `. It is never +`NEEDS_PERSON`. When part of a request needs a change in a path you may never edit (`../skills/vibe/references/guardrails.md`, "What may change": the Never diff --git a/plugins/vibe/agents/vibe-guardrails-reviewer.md b/plugins/vibe/agents/vibe-guardrails-reviewer.md index 463d586d..c68739bf 100644 --- a/plugins/vibe/agents/vibe-guardrails-reviewer.md +++ b/plugins/vibe/agents/vibe-guardrails-reviewer.md @@ -158,8 +158,9 @@ closedloop-graph is required, per `../skills/vibe/references/closedloop-graph.md reported precedents tell whether a page-scoped story mirrors them. 12. Mechanisms: for each new poller, interval, background lane, socket, cross-process channel, route, table or cursor in the diff, and each write - into files another tool owns, name the existing mechanism that does or - could do the job (`closedloop-graph.md`, the row for channels that + into another tool's data (its files, or its API or IPC, such as a method + that changes that tool's stored state), name the existing mechanism that + does or could do the job (`closedloop-graph.md`, the row for channels that already connect two surfaces) and why it was not used. State what its steady-state cost scales with (installs or idle clients, connected clients, active sessions, events) at 10x and 100x, and its per-device idle @@ -167,14 +168,18 @@ closedloop-graph is required, per `../skills/vibe/references/closedloop-graph.md battery). Never argue from current fleet size. Cost that scales with idle clients when an activity-scaled design meets the outcome is blocking, and so is a write into another tool's data with no cited human decision. A - decision recorded in a ticket or plan counts only when it traces to a - human statement (who, where, which question; `quality-loop.md`, - "Communication and product questions"): a Decisions section alone is a - record, not a ruling, and an untraced one is an `engineering decision` - finding. A mechanism the ticket named is held to the same test - (`vibe-change-worker.md`, "Plan before code"). When the session's local - plan has a Cost Scaling table, check it against the diff; a row that does - not match what was built is a finding. + supported interface lowers the risk but does not remove the need for a + traced human decision. A new direction of data flow between surfaces in + the diff (`../skills/cl-execute/references/planning-and-gates.md`, + Readiness Gate, "Data direction") with no traced decision allowing it is a + blocking `engineering decision` finding. A decision recorded in a ticket + or plan counts only when it traces to a human statement (who, where, which + question; `quality-loop.md`, "Communication and product questions"): a + Decisions section alone is a record, not a ruling, and an untraced one is + an `engineering decision` finding. A mechanism the ticket named is held to + the same test (`vibe-change-worker.md`, "Plan before code"). When the + session's local plan has a Cost Scaling table, check it against the diff; + a row that does not match what was built is a finding. For publication, verify the SAME source actor's `main-sync-inputs` evidence before capture and after the committed merge. Canonical private diagnostics diff --git a/plugins/vibe/agents/vibe-requirements-worker.md b/plugins/vibe/agents/vibe-requirements-worker.md index f06d41f0..44ab7820 100644 --- a/plugins/vibe/agents/vibe-requirements-worker.md +++ b/plugins/vibe/agents/vibe-requirements-worker.md @@ -39,8 +39,13 @@ questions"), or produce an upfront summary for the person. the session's acceptance criteria list (`quality-loop.md`, "Acceptance criteria before ready"). Tag ticket text that names an implementation mechanism (a poller, feed, lane, socket, route, table, cursor, or a write - into another tool's data) `mechanism (proposal)`, never an acceptance - criterion, so the session checks the outcome and not the named mechanism. A + into another tool's data through its files, API or IPC) `mechanism + (proposal)`, never an acceptance criterion, so the session checks the + outcome and not the named mechanism. Flag a new direction of data flow + between surfaces the request needs + (`../skills/cl-execute/references/planning-and-gates.md`, Readiness Gate, + "Data direction") `data direction (new)`, with the decision that allows it + and its source, or `untraced`; it is never a question for the person. A recorded decision is settled only when it traces to a human statement (`quality-loop.md`, "Communication and product questions"); report each with its source, and an unratified or conflicting one as not settled. @@ -99,7 +104,8 @@ as our copy. End with the Graph block. `DONE` with: a two or three sentence summary in plain words, which the orchestrator keeps internal and which never names a screen to start on; the requirements as a short list quoted from their source (never -invented), each named mechanism tagged `mechanism (proposal)`; every +invented), each named mechanism tagged `mechanism (proposal)` and each new +data direction flagged `data direction (new)`; every acceptance criterion of the ticket and its PRD, quoted exactly with its source slug, or "none stated"; the route and FEATURE_MAP id where the relevant code lives, for change workers (not shown to the person); overlapping or in-flight tickets diff --git a/plugins/vibe/skills/cl-analyze/SKILL.md b/plugins/vibe/skills/cl-analyze/SKILL.md index f3039096..812ec3ae 100644 --- a/plugins/vibe/skills/cl-analyze/SKILL.md +++ b/plugins/vibe/skills/cl-analyze/SKILL.md @@ -174,6 +174,8 @@ question looks product-shaped. At minimum, this search covers linked PRDs, plans - Duplication/conflict: The request is not already done, superseded, covered by an active PR, duplicated by another ticket, or contradicted by linked plans/comments. - Validation path: There is a realistic way to test the change locally and in CI, including desktop or visual QA when relevant. For a bug ticket, name the cheap test path that can fail on current main before the fix, or say why none exists and which runtime evidence (for example a `pnpm control` capture) stands in for it. For a behavior-preserving ticket (refactor, move, rename, dependency swap), name the existing tests or captures that can pin current behavior on the base, or the gap `$cl-execute` must fill before moving structure. - Safety and risk: The work does not require automatic changes to high-risk areas such as auth, permissions, billing, data deletion, migrations, privacy/security boundaries, release automation, or broad cross-package contracts without explicit human review. +- Decision provenance: Apply `$cl-execute`'s Decision provenance readiness item (`../cl-execute/references/planning-and-gates.md`, Readiness Gate) to every decision the ticket, its PRDs, and its plans record. An unratified or conflicting decision is `BLOCKED`; use `NOT_APPLICABLE` when none of them records a decision. +- Data direction: Apply `$cl-execute`'s Data direction readiness item (`../cl-execute/references/planning-and-gates.md`, Readiness Gate) to the minimum credible implementation. A new direction of data flow between surfaces with no traced decision allowing it is `BLOCKED`, a human decision rather than an implementation detail; use `NOT_APPLICABLE` when the work introduces no new direction. - Safety fact: When the minimum credible implementation touches auth, permissions, data writes, migrations, or a shared contract, name the one fact the change is safe because of (for example, "the new route resolves the same auth context as the old one for every caller type") and the cheapest code that can prove it: a focused test, a script that calls the real code, or a `pnpm control` capture. `$cl-execute` carries the fact into the plan and proves it by running that code; a prose argument is not a proof. Use `NOT_APPLICABLE` when none of those surfaces change and `UNKNOWN` when they do but no single fact explains why the change is safe. ## Complexity And Risk @@ -183,7 +185,7 @@ Classify both complexity and risk: - `LOW`: Localized, well-scoped change with direct tests and clear acceptance criteria. - `MEDIUM`: Multiple files or modules, but ownership, contracts, and validation are clear. - `HIGH`: Cross-surface, cross-package, schema, desktop/web, migration, auth, security, release, or large refactor work; or ambiguous ownership with meaningful regression risk. -- `EXTREME`: Could cause data loss, security/privacy exposure, billing or permission errors, broad production instability, or requires product/architecture decisions that are not already documented. +- `EXTREME`: Could cause data loss, security/privacy exposure, billing or permission errors, broad production instability, or requires product/architecture decisions that are not already documented. A decision counts as documented only when it traces to a human statement (who made it, where, and which question it answered); a ticket's or plan's Decisions section alone is a record, not a ruling. Classify complexity from the minimum coherent implementation that satisfies the ticket, not from the breadth of the existing system being inspected. This is an honest complexity boundary, not a scheduling preference for smaller tickets or separate pull requests. Unchanged dependencies, existing agents/skills, current CI workflows, historical PRs, and validation context do not increase implementation complexity by themselves. A harness-activation change that only registers, links, or dispatches to one unchanged canonical implementation is normally `LOW` or `MEDIUM` even when the underlying system is broad. Multiple files under one ownership boundary with one atomic validation path can still be `MEDIUM`. @@ -317,6 +319,8 @@ Readiness: - External API/docs freshness: - - Duplication/conflict: - - Validation path: - +- Decision provenance: - +- Data direction: - - Safety/risk: - - Safety fact: - diff --git a/plugins/vibe/skills/cl-execute/references/plan-review-prompt.md b/plugins/vibe/skills/cl-execute/references/plan-review-prompt.md index 85fd9de5..49b3a74a 100644 --- a/plugins/vibe/skills/cl-execute/references/plan-review-prompt.md +++ b/plugins/vibe/skills/cl-execute/references/plan-review-prompt.md @@ -41,10 +41,11 @@ MECHANISMS (check this as hard as scope exclusions) - The requirement is the outcome the ticket asks for. A mechanism the ticket names is a proposal, held to the same test as one the plan invented. - For every new mechanism (API route, table or column, cursor, poller or - background lane, cross-process channel, writes into files another tool - owns), name the existing mechanism that already does that job, or could, - and why the plan does not use it. New is unjustified until existing is - ruled out with evidence; reuse a connection before opening one. + background lane, cross-process channel, writes into another tool's data + through its files, API or IPC), name the existing mechanism that already + does that job, or could, and why the plan does not use it. New is + unjustified until existing is ruled out with evidence; reuse a connection + before opening one. - Cost: fleet size is unknown and growing, so never argue from a device count. Judge by what steady-state cost scales with (idle installs, connected clients, active sessions, events) at 10x and 100x, and by @@ -54,7 +55,8 @@ MECHANISMS (check this as hard as scope exclusions) meets the outcome. - One-way doors (a new data direction between surfaces, a contract installed clients will depend on, a write into another tool's data) need a cited - human decision; without one, list a human decision item. + human decision; without one, list a human decision item. A supported + interface for that write lowers the risk but is not the decision. DECISIONS - A "Decisions" section in a ticket or plan is a record, not a ruling. For @@ -63,6 +65,8 @@ DECISIONS - A newer ticket does not supersede an earlier explicit ruling by naming a different mechanism; only a statement addressing that ruling does. When records disagree, report the conflict; never resolve it by recency. +- A new data direction between surfaces is allowed only by a traced human + decision or approved document; an earlier one restricting it is a conflict. - A human decision item about a mechanism, consent, or an unratified or conflicting decision is neither instruction inflation nor manufactured ambiguity: those rules protect settled rulings, and this is not settled. diff --git a/plugins/vibe/skills/cl-execute/references/planning-and-gates.md b/plugins/vibe/skills/cl-execute/references/planning-and-gates.md index 0e0fc650..32bf36ab 100644 --- a/plugins/vibe/skills/cl-execute/references/planning-and-gates.md +++ b/plugins/vibe/skills/cl-execute/references/planning-and-gates.md @@ -53,6 +53,17 @@ Before planning or execution, classify the ticket: ticket does not supersede an earlier explicit ruling unless it addresses that ruling. When records disagree, report the conflict as a human decision; never resolve it by recency or by assuming one author meant to change it. +- Data direction: does the work introduce a new direction of data flow between + surfaces (for example cloud to an installed client, a client into another + tool's data, or one service writing into another's store)? A write into + another tool's data covers its files and its API or IPC (for example a + method that changes that tool's stored state); a supported interface lowers + the risk but does not remove the need for a traced human decision. For a new + direction, cite the human decision or approved document that allows it: + who, where, and which question it answered, per Decision provenance. An + earlier document that restricts the direction is a conflict. With no traced + decision, the direction is a numbered human decision, not an implementation + detail. - Latency, staleness, and disclosure contracts: verify exact ratified PRD, decision record, or linked owner before approving a plan that promises freshness ceilings, analytics lag, stale-but-shown behavior, disclosure, or @@ -412,7 +423,10 @@ through the [Discovery Routes](../SKILL.md#discovery-routes). decision is neither instruction inflation nor manufactured ambiguity: those rules protect settled rulings, and a mechanism a ticket names is not one. Otherwise never turn the alternative into a - question for the operator. Periodic or cross-surface work also gets the + question for the operator. Moving a write into another tool's data to a + supported interface does not settle whether the write is allowed; that + stays the [Readiness Gate](#readiness-gate)'s Data direction item. + Periodic or cross-surface work also gets the [Cost Scaling](#cost-scaling) table. 14. One-way-door plans (Proposal Contract Audit `REQUIRED`, a new shared module or ownership boundary, or `High-complexity execution override: APPROVED`) diff --git a/plugins/vibe/skills/cl-execute/references/result-formats.md b/plugins/vibe/skills/cl-execute/references/result-formats.md index 73997cb5..b7d83207 100644 --- a/plugins/vibe/skills/cl-execute/references/result-formats.md +++ b/plugins/vibe/skills/cl-execute/references/result-formats.md @@ -43,6 +43,8 @@ Readiness: - Residual contract testability: - - Validation path: - - Runtime validation command proof: - +- Decision provenance: - +- Data direction: - - Safety/risk: - - Safety fact: - diff --git a/plugins/vibe/skills/cl-sweep/scripts/skill-contract.test.mjs b/plugins/vibe/skills/cl-sweep/scripts/skill-contract.test.mjs index ae40e06a..31932d08 100644 --- a/plugins/vibe/skills/cl-sweep/scripts/skill-contract.test.mjs +++ b/plugins/vibe/skills/cl-sweep/scripts/skill-contract.test.mjs @@ -1123,3 +1123,41 @@ test('PR snapshot callers load the core monitor by name', () => { assert.match(implementation, /\/closedloop-core:gh-monitor-pr/); assert.match(implementation, /`scripts\/monitor-pr\.mjs` from that loaded skill's own folder\s+and record its verdict/); }); + +test('a new data direction needs a traced decision in cl-execute and cl-analyze', () => { + const gates = read('cl-execute/references/planning-and-gates.md'); + const prompt = read('cl-execute/references/plan-review-prompt.md'); + const analyze = read('cl-analyze/SKILL.md'); + const formats = read('cl-execute/references/result-formats.md'); + const readiness = gates.slice(gates.indexOf('## Readiness Gate'), gates.indexOf('## Requirements Contract')); + + // One definition, in the Readiness Gate after Decision provenance. + assert.equal(gates.match(/^- Data direction:/gm)?.length, 1); + assert.ok(readiness.indexOf('- Decision provenance:') < readiness.indexOf('- Data direction:')); + assert.match(readiness, /- Data direction: does the work introduce a new direction of data flow between\s+surfaces \(for example cloud to an installed client, a client into another\s+tool's data, or one service writing into another's store\)\?/); + assert.match(readiness, /A write into\s+another tool's data covers its files and its API or IPC \(for example a\s+method that changes that tool's stored state\); a supported interface lowers\s+the risk but does not remove the need for a traced human decision\./); + assert.match(readiness, /cite the human decision or approved document that allows it:\s+who, where, and which question it answered, per Decision provenance\./); + assert.match(readiness, /An\s+earlier document that restricts the direction is a conflict\./); + assert.match(readiness, /With no traced\s+decision, the direction is a numbered human decision, not an implementation\s+detail\./); + assert.match(gates, /Moving a write into another tool's data to a\s+supported interface does not settle whether the write is allowed; that\s+stays the \[Readiness Gate\]\(#readiness-gate\)'s Data direction item\./); + + // The plan-review prompt mirrors it in one DECISIONS line and counts API writes as mechanisms. + const decisions = prompt.slice(prompt.indexOf('DECISIONS'), prompt.indexOf('SUBAGENTS')); + assert.match(decisions, /- A new data direction between surfaces is allowed only by a traced human\s+decision or approved document; an earlier one restricting it is a conflict\./); + assert.match(prompt, /writes into another tool's data\s+through its files, API or IPC\)/); + assert.match(prompt, /A supported\s+interface for that write lowers the risk but is not the decision\./); + assert.doesNotMatch(prompt, /writes into files another tool\s+owns/); + + // cl-analyze points at those definitions and reports both items. + assert.match(analyze, /requires product\/architecture decisions that are not already documented\. A decision counts as documented only when it traces to a human statement \(who made it, where, and which question it answered\); a ticket's or plan's Decisions section alone is a record, not a ruling\./); + assert.match(analyze, /^- Decision provenance: Apply `\$cl-execute`'s Decision provenance readiness item \(`\.\.\/cl-execute\/references\/planning-and-gates\.md`, Readiness Gate\)/m); + assert.match(analyze, /^- Data direction: Apply `\$cl-execute`'s Data direction readiness item \(`\.\.\/cl-execute\/references\/planning-and-gates\.md`, Readiness Gate\)/m); + assert.match(analyze, /with no traced decision allowing it is `BLOCKED`, a human decision rather than an implementation detail/); + assert.match(analyze, /^- Decision provenance: - - - - None: + gates = section(CL_EXECUTE_GATES.read_text(), "## Readiness Gate") + item = paragraph(CL_EXECUTE_GATES.read_text(), "- Data direction:") + assert item in gates + assert gates.count("- Data direction:") == 1 + for required in ( + "A write into another tool's data covers its files and its API or IPC", + "a supported interface lowers the risk but does not remove the need for a traced human decision.", + "cite the human decision or approved document that allows it", + "per Decision provenance.", + "An earlier document that restricts the direction is a conflict.", + "the direction is a numbered human decision, not an implementation detail.", + ): + assert required in item, required + + +def test_the_guardrails_reviewer_counts_api_writes_and_new_directions() -> None: + item = paragraph(agent("vibe-guardrails-reviewer"), "12. Mechanisms:") + for required in ( + "each write into another tool's data (its files, or its API or IPC, such as a method that changes that tool's stored state)", + "A supported interface lowers the risk but does not remove the need for a traced human decision.", + f"A new direction of data flow between surfaces in the diff {DATA_DIRECTION} with no traced decision allowing it is a blocking `engineering decision` finding.", + ): + assert required in item, required + assert "write into files another tool owns" not in flat(agent("vibe-guardrails-reviewer")) + + +def test_the_writer_builds_only_along_allowed_directions() -> None: + plan = section(agent("vibe-change-worker"), "## Plan before code") + rule = paragraph(agent("vibe-change-worker"), "Build the outcome only along data directions that are already allowed.") + assert rule in plan + for required in ( + f"A new direction of data flow between surfaces {DATA_DIRECTION} that traces to no human decision is not built", + "`Engineering decision: ; built: ; evidence: `", + "It is never `NEEDS_PERSON`.", + ): + assert required in rule, required + assert THROUGH_API in paragraph(agent("vibe-change-worker"), "Only the outcome a ticket or PRD asks for binds the session.") + + +def test_requirements_flag_a_new_data_direction_in_the_brief() -> None: + step = paragraph(agent("vibe-requirements-worker"), "1. Ticket:") + for required in ( + THROUGH_API, + f"Flag a new direction of data flow between surfaces the request needs {DATA_DIRECTION} `data direction (new)`", + "with the decision that allows it and its source, or `untraced`; it is never a question for the person.", + ): + assert required in step, required + assert "each new data direction flagged `data direction (new)`" in section(agent("vibe-requirements-worker"), "## Return") diff --git a/plugins/vibe/tools/python/test_vibe_mechanism_provenance_contract.py b/plugins/vibe/tools/python/test_vibe_mechanism_provenance_contract.py index 6bc00691..57086a06 100644 --- a/plugins/vibe/tools/python/test_vibe_mechanism_provenance_contract.py +++ b/plugins/vibe/tools/python/test_vibe_mechanism_provenance_contract.py @@ -39,7 +39,7 @@ def test_the_guardrails_reviewer_checks_each_new_mechanism() -> None: item = paragraph(agent("vibe-guardrails-reviewer"), "12. Mechanisms:") for required in ( "each new poller, interval, background lane, socket, cross-process channel, route, table or cursor in the diff", - "each write into files another tool owns", + "each write into another tool's data (its files, or its API or IPC, such as a method that changes that tool's stored state)", "name the existing mechanism that does or could do the job", "and why it was not used", "(installs or idle clients, connected clients, active sessions, events) at 10x and 100x",