From f15c25867dc07db3d52f77fd413960f55d69119c Mon Sep 17 00:00:00 2001 From: "Alex V." <119082209+Retengart@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:41:31 +0300 Subject: [PATCH] docs(#1578): rebase B2+B3 agent prompt changes --- .changeset/clever-cats-roar.md | 5 + .changeset/patient-geese-howl.md | 5 + agents/gsd-doc-classifier.md | 105 ++++++++++++++++++ agents/gsd-doc-synthesizer.md | 61 ++++++++++ agents/gsd-ui-checker.md | 28 +++++ docs/AGENTS.md | 5 + tests/agent-size-baseline.json | 6 +- ...extraction-discipline-consistency.test.cjs | 51 +++++++++ .../golden-install-parity/antigravity.json | 6 +- .../golden-install-parity/augment.json | 6 +- .../golden-install-parity/claude.json | 6 +- .../fixtures/golden-install-parity/cline.json | 6 +- .../golden-install-parity/codebuddy.json | 6 +- .../fixtures/golden-install-parity/codex.json | 12 +- .../golden-install-parity/copilot.json | 6 +- .../golden-install-parity/cursor.json | 6 +- .../golden-install-parity/hermes.json | 6 +- .../fixtures/golden-install-parity/kilo.json | 6 +- .../fixtures/golden-install-parity/kimi.json | 6 +- .../golden-install-parity/opencode.json | 6 +- .../fixtures/golden-install-parity/qwen.json | 6 +- .../fixtures/golden-install-parity/trae.json | 6 +- .../golden-install-parity/windsurf.json | 6 +- .../fixtures/golden-install-parity/zcode.json | 6 +- tests/ui-checker-adversarial-stance.test.cjs | 34 ++++++ 25 files changed, 348 insertions(+), 54 deletions(-) create mode 100644 .changeset/clever-cats-roar.md create mode 100644 .changeset/patient-geese-howl.md create mode 100644 tests/extraction-discipline-consistency.test.cjs create mode 100644 tests/ui-checker-adversarial-stance.test.cjs diff --git a/.changeset/clever-cats-roar.md b/.changeset/clever-cats-roar.md new file mode 100644 index 000000000..d625246b2 --- /dev/null +++ b/.changeset/clever-cats-roar.md @@ -0,0 +1,5 @@ +--- +type: Changed +pr: 1584 +--- +**gsd-ui-checker gains an adversarial FORCE stance (LLM-playbook principle 16)** — the only verdict-producing critic that lacked one now resists rubber-stamping UI-SPEC contracts, with BLOCK/FLAG/PASS classification. Based on arXiv 2505.23840 (third-person objective persona), 2506.04975 (objective-not-hostile persona). diff --git a/.changeset/patient-geese-howl.md b/.changeset/patient-geese-howl.md new file mode 100644 index 000000000..8a1bb8eb3 --- /dev/null +++ b/.changeset/patient-geese-howl.md @@ -0,0 +1,5 @@ +--- +type: Changed +pr: 1584 +--- +**Extraction discipline for strict-format agents (LLM-playbook principle 8)** — gsd-doc-classifier and gsd-doc-synthesizer apply taxonomy/precedence rules directly without inventing content, reducing reasoning-induced format drift. Based on arXiv 2504.05081 (few-shot beats CoT for pattern tasks), 2506.00069 (terminal instruction placement), 2505.14810, 2505.11423. diff --git a/agents/gsd-doc-classifier.md b/agents/gsd-doc-classifier.md index ba4d0c250..53561559f 100644 --- a/agents/gsd-doc-classifier.md +++ b/agents/gsd-doc-classifier.md @@ -20,6 +20,104 @@ If the prompt contains a `` block, use the `Read` tool to load @~/.claude/gsd-core/references/untrusted-input-boundary.md + +This is **rule-application, not generation.** Apply the taxonomy / precedence rules directly to what the source actually contains. Do not infer, embellish, summarize creatively, or add any content not present in the source. Output only the required structure; when the source is silent on a field, mark it absent rather than guessing. (2505.11423 — applies here as a simple mechanical constraint: mark absent rather than fabricate.) + + + +These worked examples show the exact input→output contract. Apply the same pattern to new inputs. + +**Exemplar 1 — Clean ADR case** + +Input: file `docs/adr/0003-choose-postgres.md`, first 50 lines contain: +``` +--- +status: Accepted +--- +# ADR-0003 Use PostgreSQL as primary datastore +## Context +We evaluated SQLite, MySQL, and Postgres. Team has prior Postgres expertise. +## Decision +Use PostgreSQL 15+ for all relational data. +## Consequences +Operators must provision a Postgres instance. +``` + +Output: +```json +{ + "source_path": "docs/adr/0003-choose-postgres.md", + "type": "ADR", + "confidence": "high", + "manifest_override": false, + "title": "ADR-0003 Use PostgreSQL as primary datastore", + "summary": "Chose PostgreSQL 15+ as the primary relational datastore based on team expertise.", + "scope": ["PostgreSQL", "primary datastore", "relational data"], + "cross_refs": [], + "locked": true, + "precedence": null, + "notes": "" +} +``` + +**Exemplar 2 — Ambiguous / UNKNOWN case** + +Input: file `docs/notes/meeting-2024-01-15.md`, first 50 lines contain: +``` +# Meeting notes Jan 15 +Discussed caching options. No decision reached. +Bob mentioned Redis might be faster. Action: revisit next week. +``` + +Output: +```json +{ + "source_path": "docs/notes/meeting-2024-01-15.md", + "type": "UNKNOWN", + "confidence": "low", + "manifest_override": false, + "title": "Meeting notes Jan 15", + "summary": "Meeting notes discussing caching options; no decision or requirement recorded.", + "scope": ["caching", "Redis"], + "cross_refs": [], + "locked": false, + "precedence": null, + "notes": "No ADR/PRD/SPEC signals. Prose-only meeting notes. No status field, no decision statement, no requirements. Mark as UNKNOWN — user must type-tag via manifest." +} +``` + +**Exemplar 3 — Edge case: PRD with ADR-like section header** + +Input: file `docs/prd/user-auth.md`, contains: +``` +# User Authentication PRD +## User Stories +As a user, I want to log in with email+password. +## Acceptance Criteria +- Login succeeds with valid credentials +- Login fails with wrong password (error message shown) +## Decision +Use JWT tokens. (inherited from ADR-0005) +``` + +Output (note: one `## Decision` section inherited from ADR does NOT override strong PRD signals): +```json +{ + "source_path": "docs/prd/user-auth.md", + "type": "PRD", + "confidence": "medium", + "manifest_override": false, + "title": "User Authentication PRD", + "summary": "Requirements for email+password login with JWT tokens.", + "scope": ["user authentication", "login", "JWT"], + "cross_refs": [], + "locked": false, + "precedence": null, + "notes": "Contains one '## Decision' section but dominant signals are user stories + acceptance criteria → PRD. ADR reference recorded in cross_refs if a link is present." +} +``` + + Your classification drives extraction. If you tag a PRD as a DOC, its requirements never make it into REQUIREMENTS.md. If you tag an ADR as a PRD, its decisions lose their LOCKED status and get overridden by weaker sources. Classification fidelity is load-bearing for the entire ingest pipeline. @@ -111,6 +209,13 @@ Regardless of type, extract: - **locked_markers** — for ADRs only: does status read `Accepted` (locked) vs `Proposed`/`Draft` (not locked)? Set `locked: true|false`. + +**Output contract reminder (2506.00069 — restate schema immediately before writing):** +You MUST write exactly one JSON object matching this schema — no extra fields, no omissions: +`{ source_path, type (ADR|PRD|SPEC|DOC|UNKNOWN), confidence (high|medium|low), manifest_override (bool), title (string), summary (≤30 words), scope (string[]), cross_refs (string[]), locked (bool), precedence (int|null), notes (string, omit if high confidence) }` +`locked: true` only for ADR with `Accepted` status. `manifest_override: true` only if MANIFEST_TYPE was provided. Fields absent in source → mark absent (empty array / empty string / false), never fabricate. + + Write to `{OUTPUT_DIR}/{slug}-{source_hash}.json` where `slug` is the filename without extension (replace non-alphanumerics with `-`), and `source_hash` is the first 8 hex chars of SHA-256 of the **full source file path** (POSIX-style) so parallel classifiers never collide on sibling `README.md` files. diff --git a/agents/gsd-doc-synthesizer.md b/agents/gsd-doc-synthesizer.md index 548b14398..7b392dec6 100644 --- a/agents/gsd-doc-synthesizer.md +++ b/agents/gsd-doc-synthesizer.md @@ -22,6 +22,56 @@ If the prompt contains a `` block, load every file listed ther @~/.claude/gsd-core/references/untrusted-input-boundary.md + +This is **rule-application, not generation.** Apply the taxonomy / precedence rules directly to what the source actually contains. Do not infer, embellish, summarize creatively, or add any content not present in the source. Output only the required structure; when the source is silent on a field, mark it absent rather than guessing. (2505.11423 — applies here as a simple mechanical constraint: mark absent rather than fabricate.) + + + +These worked examples show the exact input→output contract for per-type extraction. Apply the same pattern. + +**Exemplar 1 — Clean ADR extraction** + +Input: classified ADR `docs/adr/0003-choose-postgres.md` with `locked: true`, decision statement: "Use PostgreSQL 15+ for all relational data." + +Output entry for `INTEL_DIR/decisions.md`: +``` +## ADR-0003: Use PostgreSQL as primary datastore +- source: docs/adr/0003-choose-postgres.md +- status: locked (Accepted) +- decision: Use PostgreSQL 15+ for all relational data. +- scope: primary datastore, relational data +``` + +**Exemplar 2 — UNKNOWN / low-confidence doc (conflict surfacing)** + +Input: classified doc `docs/notes/meeting-2024-01-15.md` with `type: UNKNOWN`, `confidence: low`. + +Output: do NOT extract to any intel file. Instead, add to `unresolved-blockers` in `CONFLICTS_PATH`: +``` +[BLOCKER] UNKNOWN classification — user must type-tag + Found: docs/notes/meeting-2024-01-15.md classified UNKNOWN (low confidence) + Signals observed: prose-only meeting notes, no ADR/PRD/SPEC markers + → Re-tag via --manifest before re-running ingest +``` +Mark absent fields as absent in the entry — do not infer a type. + +**Exemplar 3 — Edge case: competing PRD acceptance criteria** + +Input: two PRD classifications for the same scope "user-auth": +- `docs/prd/auth-v1.md` → requirement: "login via email+password" +- `docs/prd/auth-v2.md` → requirement: "login via SSO only" + +Output: do NOT pick one. Write both to `competing-variants` bucket in `CONFLICTS_PATH`: +``` +[WARNING] Competing acceptance variants for REQ-user-auth + Found: docs/prd/auth-v1.md requires "email+password" + Found: docs/prd/auth-v2.md requires "SSO only" — same scope "user authentication" + Impact: Synthesis cannot pick without losing intent + → Choose one variant or split into two requirements before routing +``` +Emit both variants verbatim to `INTEL_DIR/requirements.md` under separate IDs (REQ-user-auth-v1, REQ-user-auth-v2). + + You are the precedence-enforcing layer. Silent merges, lost locked decisions, or naive dedupes here corrupt every downstream plan. When in doubt, surface the conflict rather than pick. @@ -111,6 +161,17 @@ Apply the `doc-conflict-engine` severity semantics: - `auto-resolved` maps to [INFO] — recorded for transparency + +**Output contract reminder (2506.00069 — restate schema immediately before writing):** +Per-type intel files must use these exact formats — no omissions, no extra fields: +- `decisions.md`: each entry has `## {title}`, `- source:`, `- status: locked|proposed`, `- decision:`, `- scope:` +- `requirements.md`: each entry has `## REQ-{slug}`, `- source:`, `- description:`, `- acceptance:`, `- scope:` +- `constraints.md`: each entry has `## {title}`, `- source:`, `- type: api-contract|schema|nfr|protocol`, `- content:` +- `context.md`: topic-keyed entries with `- source:` attribution +Absent fields → mark absent (empty / omit), never fabricate. LOCKED-vs-LOCKED → always BLOCKER, never auto-resolve. +`CONFLICTS_PATH` must have exactly three sections: `### BLOCKERS`, `### WARNINGS`, `### INFO`. + + Write `CONFLICTS_PATH` using the format from `references/doc-conflict-engine.md`. Three buckets, plain text, no tables. diff --git a/agents/gsd-ui-checker.md b/agents/gsd-ui-checker.md index 69c77bd50..9f2962487 100644 --- a/agents/gsd-ui-checker.md +++ b/agents/gsd-ui-checker.md @@ -24,6 +24,34 @@ If the prompt contains a `` block, you MUST use the `Read` too You are read-only — never modify UI-SPEC.md. Report findings, let the researcher fix. + +**FORCE stance:** Assume every UI-SPEC.md contains design debt until the contract proves otherwise. Your starting hypothesis: generic CTAs, missing states, and grid-breaking values are present — find them. + +**Common failure modes — how UI checkers go soft:** +- Passing a spec because all sections are filled in, without checking the *content* quality of CTA labels, empty/error states, and copy +- Treating "accent color defined" as sufficient without checking it is reserved (not applied to all interactive elements) +- Accepting more than 4 font sizes or non-4-multiple spacing because "it's close enough" +- Letting a polished-looking spec bias the verdict toward PASS before each dimension is checked +- Softening a BLOCK to FLAG to avoid sending the researcher back + +**Required verdict classification:** every dimension must resolve to: +- **BLOCK** — contract is incomplete/inconsistent/unimplementable; planning must not begin +- **FLAG** — works but degrades design quality; researcher should fix +- **PASS** — dimension meets the contract + + + +**The Auditor** is an independent design reviewer known for objective, uncompromising spec review. The Auditor applies the six dimensions without deference to effort, polish, or seniority. The Auditor's verdict is grounded in the contract criteria alone — not in whether the spec looks good or whether the researcher worked hard. + +When producing a verdict, ask: *What is The Auditor's verdict on this dimension?* The Auditor's verdict must be derived from evidence in the spec, not from impressions. + +The Auditor is skeptical and exacting, but NOT hostile or contemptuous. The Auditor does not express anger or frustration — the Auditor simply applies the criteria and states what is there and what is missing. (Sources: 2505.23840 — third-person objective persona as sycophancy mitigation; 2506.04975 — objective persona, not hostile, to avoid toxicity escalation.) + +This persona is **not a standalone accuracy guarantee**. It is a stance for applying the evidence contract consistently; if the persona framing and the written criteria/evidence conflict, the criteria and evidence win. + +**Anti-capitulation rule (re-verification turns):** If the researcher disagrees with a BLOCK verdict or submits a revised spec, The Auditor re-examines the revised content against the criteria. Researcher disagreement alone is never grounds to downgrade a BLOCK. A BLOCK may be downgraded only when the spec contains a concrete fix that resolves the exact deficiency that triggered the BLOCK, or when re-examination shows the prior dimension application was mistaken. Self-correction is allowed when the criteria and evidence support it; capitulation to pressure is not. "We'll handle it in implementation" or "it's implied" are not concrete fixes. + + Before verifying, discover project context: diff --git a/docs/AGENTS.md b/docs/AGENTS.md index cfde01630..62f12c955 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -277,6 +277,9 @@ GSD uses a multi-agent architecture where thin orchestrators (workflow files) sp | **Color** | Cyan | | **Produces** | BLOCK/FLAG/PASS verdict | +**Key behaviors:** +- **Adversarial stance / "The Auditor" (#1578):** applies explicit BLOCK/FLAG/PASS tiers and an anti-capitulation rule that resists author-framing pressure while still allowing self-correction when the prior dimension application was mistaken. Persona effects are strongest on Sonnet-class reasoning and unvalidated on budget/Haiku-class routing; the criteria and evidence remain authoritative. + --- ### gsd-verifier @@ -711,6 +714,7 @@ Twelve additional agents ship under `agents/gsd-*.md` and are used by specialty **Key behaviors:** - Single-doc scope — never synthesizes or resolves conflicts (that is the synthesizer's job) - Heuristic-first classification; returns UNKNOWN when the doc lacks type signals rather than guessing +- **Extraction discipline (#1578):** few-shot input→output exemplars plus a terminal schema restatement; marks a field absent rather than fabricating a value when the doc lacks the signal. --- @@ -730,6 +734,7 @@ Twelve additional agents ship under `agents/gsd-*.md` and are used by specialty **Key behaviors:** - Hard-blocks on LOCKED-vs-LOCKED ADR contradictions instead of silently picking a winner - Follows the `references/doc-conflict-engine.md` contract so `/gsd-import` and `/gsd-ingest-docs` produce consistent conflict reports +- **Extraction discipline (#1578):** few-shot exemplars plus a terminal schema restatement and a mark-absent (no-fabrication) rule for missing fields. --- diff --git a/tests/agent-size-baseline.json b/tests/agent-size-baseline.json index 81abeeb01..08166ac12 100644 --- a/tests/agent-size-baseline.json +++ b/tests/agent-size-baseline.json @@ -7,8 +7,8 @@ "gsd-codebase-mapper.md": 21485, "gsd-debug-session-manager.md": 14203, "gsd-debugger.md": 51354, - "gsd-doc-classifier.md": 7689, - "gsd-doc-synthesizer.md": 9782, + "gsd-doc-classifier.md": 11717, + "gsd-doc-synthesizer.md": 13154, "gsd-doc-verifier.md": 12403, "gsd-doc-writer.md": 38924, "gsd-domain-researcher.md": 7032, @@ -29,7 +29,7 @@ "gsd-roadmapper.md": 22273, "gsd-security-auditor.md": 8981, "gsd-ui-auditor.md": 17249, - "gsd-ui-checker.md": 11178, + "gsd-ui-checker.md": 14060, "gsd-ui-researcher.md": 19500, "gsd-user-profiler.md": 8516, "gsd-verifier.md": 49147 diff --git a/tests/extraction-discipline-consistency.test.cjs b/tests/extraction-discipline-consistency.test.cjs new file mode 100644 index 000000000..f3ad51cc9 --- /dev/null +++ b/tests/extraction-discipline-consistency.test.cjs @@ -0,0 +1,51 @@ +'use strict'; +const { test, describe } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); + +const EXTRACTORS = ['gsd-doc-classifier', 'gsd-doc-synthesizer']; + +describe('extraction discipline (#8)', () => { + for (const name of EXTRACTORS) { + test(`${name} instructs rule-application, not generation`, () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', `${name}.md`), 'utf8'); + assert.match(src, //, `${name} missing `); + assert.match(src, /rule-application, not generation/i, `${name} missing rule-application framing`); + assert.match(src, /do not (infer|embellish)/i, `${name} missing no-infer/embellish rule`); + }); + + test(`${name} contains no-fabrication "mark absent" guidance`, () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', `${name}.md`), 'utf8'); + // Must instruct marking absent fields rather than guessing/fabricating + assert.match(src, /mark.{0,30}absent/i, `${name} missing "mark absent" no-fabrication guidance`); + }); + + test(`${name} does NOT contain the anti-JSON-reasoning overclaim`, () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', `${name}.md`), 'utf8'); + // The overclaim: "do not reason your way to a ... answer" or "extended deliberation breaks structure" + assert.doesNotMatch(src, /do not reason your way/i, `${name} still contains anti-JSON-reasoning overclaim`); + assert.doesNotMatch(src, /extended deliberation.{0,30}breaks/i, `${name} still contains anti-reasoning overclaim`); + }); + + test(`${name} contains few-shot input->output exemplars`, () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', `${name}.md`), 'utf8'); + // Must have at least one worked Input: / Output: pair (or Input -> Output arrow pattern) + const hasInputOutput = /Input:/i.test(src) && /Output:/i.test(src); + const hasArrow = /Input\s*→/.test(src) || /Input\s*->/.test(src); + assert.ok(hasInputOutput || hasArrow, `${name} missing few-shot Input->Output exemplars`); + // Must have at least 2 exemplar pairs (clean + ambiguous/UNKNOWN) + const inputMatches = (src.match(/\bInput:/gi) || []).length; + const arrowMatches = (src.match(/\bInput\s*[→-]/g) || []).length; + const exemplarCount = inputMatches || arrowMatches; + assert.ok(exemplarCount >= 2, `${name} needs at least 2 exemplars (clean + UNKNOWN/ambiguous), found ${exemplarCount}`); + }); + + test(`${name} contains a terminal schema restatement before write/output step`, () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', `${name}.md`), 'utf8'); + // Must have a terminal schema restatement marker immediately before the write/output step + assert.match(src, /terminal.{0,60}schema|schema.{0,60}restatement|output.{0,40}contract.{0,40}reminder|final.{0,40}output.{0,40}schema/i, + `${name} missing terminal schema restatement before write step`); + }); + } +}); diff --git a/tests/fixtures/golden-install-parity/antigravity.json b/tests/fixtures/golden-install-parity/antigravity.json index e7e4e189d..4615ba8ec 100644 --- a/tests/fixtures/golden-install-parity/antigravity.json +++ b/tests/fixtures/golden-install-parity/antigravity.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "afdae82284cb21b4", "agents/gsd-debug-session-manager.md": "5ea82765fc041ad7", "agents/gsd-debugger.md": "7439166a1770521c", - "agents/gsd-doc-classifier.md": "6dde566846b268b0", - "agents/gsd-doc-synthesizer.md": "6286afdbd9a74fe0", + "agents/gsd-doc-classifier.md": "fca19595590391df", + "agents/gsd-doc-synthesizer.md": "0e5184bbcf0dca02", "agents/gsd-doc-verifier.md": "888c6ac870cb91a6", "agents/gsd-doc-writer.md": "d4400c8dab4a9efc", "agents/gsd-domain-researcher.md": "1db46cac3f4d9889", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "7a8465ac6d4dd29e", "agents/gsd-security-auditor.md": "2ce13af25179dd10", "agents/gsd-ui-auditor.md": "f777f9c7bf62788c", - "agents/gsd-ui-checker.md": "9c113a9c6b63385c", + "agents/gsd-ui-checker.md": "dbb50fc8324471b5", "agents/gsd-ui-researcher.md": "5d74011a96e5b67f", "agents/gsd-user-profiler.md": "25d65f6458454764", "agents/gsd-verifier.md": "224e8df2d8fd1d95", diff --git a/tests/fixtures/golden-install-parity/augment.json b/tests/fixtures/golden-install-parity/augment.json index 9ced83650..a39d82e99 100644 --- a/tests/fixtures/golden-install-parity/augment.json +++ b/tests/fixtures/golden-install-parity/augment.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "85ea778ad9cf7e66", "agents/gsd-debug-session-manager.md": "0d388fcee3eba770", "agents/gsd-debugger.md": "2c8234c76c5d15c1", - "agents/gsd-doc-classifier.md": "f61cb0fad0d4f243", - "agents/gsd-doc-synthesizer.md": "043847ebefbb9b7c", + "agents/gsd-doc-classifier.md": "262a94b947a4e2aa", + "agents/gsd-doc-synthesizer.md": "01f90ea9b0d05d7d", "agents/gsd-doc-verifier.md": "b3433e0db51e1c60", "agents/gsd-doc-writer.md": "376011bd99026bf7", "agents/gsd-domain-researcher.md": "671c9ea949889c4a", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "bb2f57695dbab32c", "agents/gsd-security-auditor.md": "f22374cc1db28dca", "agents/gsd-ui-auditor.md": "dcd5712e6b160a53", - "agents/gsd-ui-checker.md": "8a20715a400435f9", + "agents/gsd-ui-checker.md": "286b934b411079f8", "agents/gsd-ui-researcher.md": "184d1c3edca694df", "agents/gsd-user-profiler.md": "622220df0654b6bf", "agents/gsd-verifier.md": "f5c00a9b08fc1a7e", diff --git a/tests/fixtures/golden-install-parity/claude.json b/tests/fixtures/golden-install-parity/claude.json index 2fb838fa0..b96c3ccec 100644 --- a/tests/fixtures/golden-install-parity/claude.json +++ b/tests/fixtures/golden-install-parity/claude.json @@ -8,8 +8,8 @@ "agents/gsd-codebase-mapper.md": "8c2e9f2ce3aedf78", "agents/gsd-debug-session-manager.md": "767c0f43d47e89ad", "agents/gsd-debugger.md": "4d8a618121c8056a", - "agents/gsd-doc-classifier.md": "4740eb4c4f6ac294", - "agents/gsd-doc-synthesizer.md": "135bbdfb9053cbd8", + "agents/gsd-doc-classifier.md": "a636ae9594b25770", + "agents/gsd-doc-synthesizer.md": "dfb95eedfb3789bf", "agents/gsd-doc-verifier.md": "4232dcf9076e3566", "agents/gsd-doc-writer.md": "8cb62907c6458111", "agents/gsd-domain-researcher.md": "5f7d366251b957fe", @@ -30,7 +30,7 @@ "agents/gsd-roadmapper.md": "8a7f1f1256a6aed5", "agents/gsd-security-auditor.md": "4f9fc3f654af4944", "agents/gsd-ui-auditor.md": "40c0dcc15bcfb9fb", - "agents/gsd-ui-checker.md": "6e94b43fd459e10e", + "agents/gsd-ui-checker.md": "dae43a7eef4f2041", "agents/gsd-ui-researcher.md": "5e561130434efdb2", "agents/gsd-user-profiler.md": "003276f85792cfda", "agents/gsd-verifier.md": "2271174b5aa20e31", diff --git a/tests/fixtures/golden-install-parity/cline.json b/tests/fixtures/golden-install-parity/cline.json index 2851df9ba..cc82e4925 100644 --- a/tests/fixtures/golden-install-parity/cline.json +++ b/tests/fixtures/golden-install-parity/cline.json @@ -12,8 +12,8 @@ "agents/gsd-codebase-mapper.md": "e5b7941bdda53c91", "agents/gsd-debug-session-manager.md": "a9d4e43e4d2e327a", "agents/gsd-debugger.md": "b1f3af91f0e651c8", - "agents/gsd-doc-classifier.md": "f7c361b91cc71a15", - "agents/gsd-doc-synthesizer.md": "f4e6ca19363e4b0f", + "agents/gsd-doc-classifier.md": "5011d7358d2b2848", + "agents/gsd-doc-synthesizer.md": "e59cdd669876582d", "agents/gsd-doc-verifier.md": "b60290c9d9f6d8d2", "agents/gsd-doc-writer.md": "27655a8cfdeb97ee", "agents/gsd-domain-researcher.md": "0fecdaea86466a56", @@ -34,7 +34,7 @@ "agents/gsd-roadmapper.md": "bbb23d3097911516", "agents/gsd-security-auditor.md": "c35c8ec2f85b331f", "agents/gsd-ui-auditor.md": "9338efa31b9b7b99", - "agents/gsd-ui-checker.md": "6ed8cd036613da1c", + "agents/gsd-ui-checker.md": "548c820528c95e39", "agents/gsd-ui-researcher.md": "eea2dfddf30aec9d", "agents/gsd-user-profiler.md": "622220df0654b6bf", "agents/gsd-verifier.md": "75912e9cadd83eb3", diff --git a/tests/fixtures/golden-install-parity/codebuddy.json b/tests/fixtures/golden-install-parity/codebuddy.json index 5ea53f832..b47dbf1de 100644 --- a/tests/fixtures/golden-install-parity/codebuddy.json +++ b/tests/fixtures/golden-install-parity/codebuddy.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "b995bf01af0193d2", "agents/gsd-debug-session-manager.md": "a5649998f68812d5", "agents/gsd-debugger.md": "a63306f54bdc63bf", - "agents/gsd-doc-classifier.md": "095e804a82f4a47f", - "agents/gsd-doc-synthesizer.md": "2a78fe239d00389c", + "agents/gsd-doc-classifier.md": "c2bf59af9467810b", + "agents/gsd-doc-synthesizer.md": "b2a179bf3c9bd636", "agents/gsd-doc-verifier.md": "e74d930905a782ea", "agents/gsd-doc-writer.md": "ed5678dd38c83716", "agents/gsd-domain-researcher.md": "1c1a800108a2b225", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "20b69eff61a7a9fa", "agents/gsd-security-auditor.md": "d3b8f44034a76c9d", "agents/gsd-ui-auditor.md": "a26bbc733817959b", - "agents/gsd-ui-checker.md": "30aa8e8efa880bd0", + "agents/gsd-ui-checker.md": "c114c86b5aee38ee", "agents/gsd-ui-researcher.md": "5b2d98efecd3ca11", "agents/gsd-user-profiler.md": "622220df0654b6bf", "agents/gsd-verifier.md": "c8a8c73a277a512f", diff --git a/tests/fixtures/golden-install-parity/codex.json b/tests/fixtures/golden-install-parity/codex.json index 4d07225df..a1a0bb73c 100644 --- a/tests/fixtures/golden-install-parity/codex.json +++ b/tests/fixtures/golden-install-parity/codex.json @@ -17,10 +17,10 @@ "agents/gsd-debug-session-manager.toml": "c8d894c734e97256", "agents/gsd-debugger.md": "cb8a103ed221ca7c", "agents/gsd-debugger.toml": "b31333b83a8fed0a", - "agents/gsd-doc-classifier.md": "0ee2bcb95b247ef8", - "agents/gsd-doc-classifier.toml": "8b94b5c8b02c133a", - "agents/gsd-doc-synthesizer.md": "2a3fbfce6cf5e671", - "agents/gsd-doc-synthesizer.toml": "823930fa132ce21b", + "agents/gsd-doc-classifier.md": "2745bc04d7b93666", + "agents/gsd-doc-classifier.toml": "3fe5ec83f62b586e", + "agents/gsd-doc-synthesizer.md": "4f545f2e916458ad", + "agents/gsd-doc-synthesizer.toml": "5b3b3badcc1e3219", "agents/gsd-doc-verifier.md": "42d07e55a2e571ce", "agents/gsd-doc-verifier.toml": "c0b7ac150730b954", "agents/gsd-doc-writer.md": "0a3557268f169722", @@ -61,8 +61,8 @@ "agents/gsd-security-auditor.toml": "42f529475bd28c22", "agents/gsd-ui-auditor.md": "abbf560bc8d5069c", "agents/gsd-ui-auditor.toml": "5e9dd62a12a16a1e", - "agents/gsd-ui-checker.md": "bf7bf8cc301c65a1", - "agents/gsd-ui-checker.toml": "d0a084e82a9ae52d", + "agents/gsd-ui-checker.md": "c5afa8df782f338c", + "agents/gsd-ui-checker.toml": "b5ca67cf1a0dd9fe", "agents/gsd-ui-researcher.md": "2befca69af55e44a", "agents/gsd-ui-researcher.toml": "b55270666066e501", "agents/gsd-user-profiler.md": "1bf5033c929181c1", diff --git a/tests/fixtures/golden-install-parity/copilot.json b/tests/fixtures/golden-install-parity/copilot.json index 68c1c364d..23cd30d93 100644 --- a/tests/fixtures/golden-install-parity/copilot.json +++ b/tests/fixtures/golden-install-parity/copilot.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.agent.md": "949bc73f2a7ea44d", "agents/gsd-debug-session-manager.agent.md": "558683230ba311ba", "agents/gsd-debugger.agent.md": "d31e32f73cd1e0dc", - "agents/gsd-doc-classifier.agent.md": "c5025847cf6f968a", - "agents/gsd-doc-synthesizer.agent.md": "16cebf04d8998356", + "agents/gsd-doc-classifier.agent.md": "aea81c0ba00e06cf", + "agents/gsd-doc-synthesizer.agent.md": "6ae32e4db005696d", "agents/gsd-doc-verifier.agent.md": "0230208ae7ab1a08", "agents/gsd-doc-writer.agent.md": "37ea4932a4b80355", "agents/gsd-domain-researcher.agent.md": "d603239b3e9fe428", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.agent.md": "322048cf8ddcb4e5", "agents/gsd-security-auditor.agent.md": "6f6a88b35dc2a24b", "agents/gsd-ui-auditor.agent.md": "92f50549e84ef482", - "agents/gsd-ui-checker.agent.md": "c9958f2587b24156", + "agents/gsd-ui-checker.agent.md": "a28c41265b4b01c7", "agents/gsd-ui-researcher.agent.md": "d24301cc182be33e", "agents/gsd-user-profiler.agent.md": "ae16a248e18dd42b", "agents/gsd-verifier.agent.md": "87a8e3238e838a39", diff --git a/tests/fixtures/golden-install-parity/cursor.json b/tests/fixtures/golden-install-parity/cursor.json index 4ed920084..62441d144 100644 --- a/tests/fixtures/golden-install-parity/cursor.json +++ b/tests/fixtures/golden-install-parity/cursor.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "d49c91fdab4efc70", "agents/gsd-debug-session-manager.md": "d6e799fdeb1fadde", "agents/gsd-debugger.md": "79bccf33fa2b4272", - "agents/gsd-doc-classifier.md": "5807f1f7cfa40c42", - "agents/gsd-doc-synthesizer.md": "0897098024c17ccd", + "agents/gsd-doc-classifier.md": "a6ab02b8f45f9d0b", + "agents/gsd-doc-synthesizer.md": "fd3c18addbc8265d", "agents/gsd-doc-verifier.md": "9934ec11845d41c3", "agents/gsd-doc-writer.md": "73b55c50c0a6bd61", "agents/gsd-domain-researcher.md": "56395dbdabf076f6", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "d28e7d4bac46dde2", "agents/gsd-security-auditor.md": "5ff44ee432387d93", "agents/gsd-ui-auditor.md": "d824acc3b2a18c53", - "agents/gsd-ui-checker.md": "9f0a288ad2c6f56f", + "agents/gsd-ui-checker.md": "783daaed264d1dbc", "agents/gsd-ui-researcher.md": "1b4d93bd032ebfde", "agents/gsd-user-profiler.md": "622220df0654b6bf", "agents/gsd-verifier.md": "dea8e61123848fb4", diff --git a/tests/fixtures/golden-install-parity/hermes.json b/tests/fixtures/golden-install-parity/hermes.json index dd711e18b..6757b3c2c 100644 --- a/tests/fixtures/golden-install-parity/hermes.json +++ b/tests/fixtures/golden-install-parity/hermes.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "feccaeeacd05e34b", "agents/gsd-debug-session-manager.md": "e0bdc1947db579c4", "agents/gsd-debugger.md": "ec4f796f5c39504a", - "agents/gsd-doc-classifier.md": "5de2a66c751b2d58", - "agents/gsd-doc-synthesizer.md": "8e6fb8220f777022", + "agents/gsd-doc-classifier.md": "29b563a146c9d22c", + "agents/gsd-doc-synthesizer.md": "652beb928e93fa1d", "agents/gsd-doc-verifier.md": "d3d8457bdd44bf10", "agents/gsd-doc-writer.md": "2858a8335170e85c", "agents/gsd-domain-researcher.md": "412cdbb05ba252ea", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "64dce5d5f9fa5654", "agents/gsd-security-auditor.md": "e4d35ada4ea67d7f", "agents/gsd-ui-auditor.md": "86797e85f718dfac", - "agents/gsd-ui-checker.md": "c56fa63fb94ded5f", + "agents/gsd-ui-checker.md": "b3161cc5fbb7fd61", "agents/gsd-ui-researcher.md": "25ffa7fa83c32a69", "agents/gsd-user-profiler.md": "ca3bf75581f211a0", "agents/gsd-verifier.md": "82d3e9015ed04017", diff --git a/tests/fixtures/golden-install-parity/kilo.json b/tests/fixtures/golden-install-parity/kilo.json index 501c826ac..21a1560ca 100644 --- a/tests/fixtures/golden-install-parity/kilo.json +++ b/tests/fixtures/golden-install-parity/kilo.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "0ccbf6a685804979", "agents/gsd-debug-session-manager.md": "828335b15a46b324", "agents/gsd-debugger.md": "b59cda547363e617", - "agents/gsd-doc-classifier.md": "dd7670f4fb345994", - "agents/gsd-doc-synthesizer.md": "1e987faef95a8c71", + "agents/gsd-doc-classifier.md": "6256bbc0b887f60f", + "agents/gsd-doc-synthesizer.md": "212aaf89a34b51d7", "agents/gsd-doc-verifier.md": "8016f792d0766b77", "agents/gsd-doc-writer.md": "72a21cf92542f6c0", "agents/gsd-domain-researcher.md": "a3874d80bcbc7380", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "277e0a3252553ab7", "agents/gsd-security-auditor.md": "0113435969e869c4", "agents/gsd-ui-auditor.md": "9b988b95d28e56ed", - "agents/gsd-ui-checker.md": "e27fd54c34ce79b8", + "agents/gsd-ui-checker.md": "35afd6eaf5588659", "agents/gsd-ui-researcher.md": "68b046253268aa64", "agents/gsd-user-profiler.md": "b8cb09319c517701", "agents/gsd-verifier.md": "af609b1959cde3f3", diff --git a/tests/fixtures/golden-install-parity/kimi.json b/tests/fixtures/golden-install-parity/kimi.json index 65d63af8a..81d6a4c32 100644 --- a/tests/fixtures/golden-install-parity/kimi.json +++ b/tests/fixtures/golden-install-parity/kimi.json @@ -19,9 +19,9 @@ "agents/subagents/gsd-debug-session-manager.yaml": "aab147717b5082e7", "agents/subagents/gsd-debugger.md": "528ad732ccff4485", "agents/subagents/gsd-debugger.yaml": "6d02d7feb90cad43", - "agents/subagents/gsd-doc-classifier.md": "7810ff57b2dba86b", + "agents/subagents/gsd-doc-classifier.md": "632dc6c61bafa63e", "agents/subagents/gsd-doc-classifier.yaml": "a4e9cf7025b57503", - "agents/subagents/gsd-doc-synthesizer.md": "50cf72bc816460fd", + "agents/subagents/gsd-doc-synthesizer.md": "5ab76355a13557be", "agents/subagents/gsd-doc-synthesizer.yaml": "b4cfc60e11571632", "agents/subagents/gsd-doc-verifier.md": "6b6eb3998d2167c8", "agents/subagents/gsd-doc-verifier.yaml": "7200c09cefcd7667", @@ -63,7 +63,7 @@ "agents/subagents/gsd-security-auditor.yaml": "fe8a4345cc13571d", "agents/subagents/gsd-ui-auditor.md": "e4a319070959ebbc", "agents/subagents/gsd-ui-auditor.yaml": "3fc98c1d9e8f10fd", - "agents/subagents/gsd-ui-checker.md": "271da1ad4fe7a102", + "agents/subagents/gsd-ui-checker.md": "df6ba7c57f18ce52", "agents/subagents/gsd-ui-checker.yaml": "c42316006654fae3", "agents/subagents/gsd-ui-researcher.md": "678f035c1fdd0603", "agents/subagents/gsd-ui-researcher.yaml": "15e215874bc2c37d", diff --git a/tests/fixtures/golden-install-parity/opencode.json b/tests/fixtures/golden-install-parity/opencode.json index 83a7124d5..87e595d16 100644 --- a/tests/fixtures/golden-install-parity/opencode.json +++ b/tests/fixtures/golden-install-parity/opencode.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "948612acd505e87f", "agents/gsd-debug-session-manager.md": "0a0483c6470df4d1", "agents/gsd-debugger.md": "a83427bd5a0406fc", - "agents/gsd-doc-classifier.md": "cd4169adec56c26f", - "agents/gsd-doc-synthesizer.md": "47a8b52fe974a810", + "agents/gsd-doc-classifier.md": "fb776cfbb7e991b0", + "agents/gsd-doc-synthesizer.md": "2389f388d291c2eb", "agents/gsd-doc-verifier.md": "65bbc2ae6b9ace29", "agents/gsd-doc-writer.md": "0696a8cdc0028917", "agents/gsd-domain-researcher.md": "71250e759ca9e723", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "1658a40b20d8b575", "agents/gsd-security-auditor.md": "e36e436c0d5c26d5", "agents/gsd-ui-auditor.md": "e810012e685b2466", - "agents/gsd-ui-checker.md": "5fd0ed65262dc194", + "agents/gsd-ui-checker.md": "909bdad2067d5028", "agents/gsd-ui-researcher.md": "d2e1ed5af2df4a7d", "agents/gsd-user-profiler.md": "d825b4c0a6431f8b", "agents/gsd-verifier.md": "b9f2e801f9395a35", diff --git a/tests/fixtures/golden-install-parity/qwen.json b/tests/fixtures/golden-install-parity/qwen.json index 71a9ad563..40444eb7b 100644 --- a/tests/fixtures/golden-install-parity/qwen.json +++ b/tests/fixtures/golden-install-parity/qwen.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "b2885ffa8bb75d47", "agents/gsd-debug-session-manager.md": "0b23e9c20c77f55c", "agents/gsd-debugger.md": "7411b2f67a801c3e", - "agents/gsd-doc-classifier.md": "5de2a66c751b2d58", - "agents/gsd-doc-synthesizer.md": "8e6fb8220f777022", + "agents/gsd-doc-classifier.md": "29b563a146c9d22c", + "agents/gsd-doc-synthesizer.md": "652beb928e93fa1d", "agents/gsd-doc-verifier.md": "3767850df78f4a36", "agents/gsd-doc-writer.md": "10962b6bd4212379", "agents/gsd-domain-researcher.md": "412cdbb05ba252ea", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "604b25c6687811f4", "agents/gsd-security-auditor.md": "f85447e5b5300feb", "agents/gsd-ui-auditor.md": "cc46d104cbc49079", - "agents/gsd-ui-checker.md": "8f140c80fc193e13", + "agents/gsd-ui-checker.md": "fa0b9c2510ee40c0", "agents/gsd-ui-researcher.md": "623cb59aa6dbe146", "agents/gsd-user-profiler.md": "ca3bf75581f211a0", "agents/gsd-verifier.md": "45c450b6d7cc5f0d", diff --git a/tests/fixtures/golden-install-parity/trae.json b/tests/fixtures/golden-install-parity/trae.json index 8342ab964..00087a04b 100644 --- a/tests/fixtures/golden-install-parity/trae.json +++ b/tests/fixtures/golden-install-parity/trae.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "8529d8a1ede8bbfb", "agents/gsd-debug-session-manager.md": "69aa7eae3a23f6a9", "agents/gsd-debugger.md": "704eb4e94b4d1212", - "agents/gsd-doc-classifier.md": "5807f1f7cfa40c42", - "agents/gsd-doc-synthesizer.md": "0897098024c17ccd", + "agents/gsd-doc-classifier.md": "a6ab02b8f45f9d0b", + "agents/gsd-doc-synthesizer.md": "fd3c18addbc8265d", "agents/gsd-doc-verifier.md": "e51e50892963ccc7", "agents/gsd-doc-writer.md": "b0c3ad805b789226", "agents/gsd-domain-researcher.md": "b80f76874c04e515", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "493ef92b42b12cf4", "agents/gsd-security-auditor.md": "fbd3798eec23651b", "agents/gsd-ui-auditor.md": "771ae08260534d5c", - "agents/gsd-ui-checker.md": "8573715bebbd4782", + "agents/gsd-ui-checker.md": "f97d16ad56f4b15b", "agents/gsd-ui-researcher.md": "3e737e761bc67073", "agents/gsd-user-profiler.md": "622220df0654b6bf", "agents/gsd-verifier.md": "99e95e235aacffbf", diff --git a/tests/fixtures/golden-install-parity/windsurf.json b/tests/fixtures/golden-install-parity/windsurf.json index a2d03a845..a4a2eba24 100644 --- a/tests/fixtures/golden-install-parity/windsurf.json +++ b/tests/fixtures/golden-install-parity/windsurf.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "cfa2bbfaf264e1fd", "agents/gsd-debug-session-manager.md": "793d9a80778d1080", "agents/gsd-debugger.md": "6b28c99a37402200", - "agents/gsd-doc-classifier.md": "5807f1f7cfa40c42", - "agents/gsd-doc-synthesizer.md": "0897098024c17ccd", + "agents/gsd-doc-classifier.md": "a6ab02b8f45f9d0b", + "agents/gsd-doc-synthesizer.md": "fd3c18addbc8265d", "agents/gsd-doc-verifier.md": "ede2f297b73b5a86", "agents/gsd-doc-writer.md": "0109294817e475a8", "agents/gsd-domain-researcher.md": "56395dbdabf076f6", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "fb62e1e3de84b5f9", "agents/gsd-security-auditor.md": "13b660e2d336ed8e", "agents/gsd-ui-auditor.md": "20cc99872e9b998b", - "agents/gsd-ui-checker.md": "b9c38249bff35478", + "agents/gsd-ui-checker.md": "73412297c27be10a", "agents/gsd-ui-researcher.md": "f830742b9493601c", "agents/gsd-user-profiler.md": "622220df0654b6bf", "agents/gsd-verifier.md": "a07b00b9c5b7b338", diff --git a/tests/fixtures/golden-install-parity/zcode.json b/tests/fixtures/golden-install-parity/zcode.json index ed40c52c3..3d05f6e97 100644 --- a/tests/fixtures/golden-install-parity/zcode.json +++ b/tests/fixtures/golden-install-parity/zcode.json @@ -9,8 +9,8 @@ "agents/gsd-codebase-mapper.md": "7cc9d387f29c46e1", "agents/gsd-debug-session-manager.md": "30651d0b4a465263", "agents/gsd-debugger.md": "fc76a617817be610", - "agents/gsd-doc-classifier.md": "6c33418bf370ec44", - "agents/gsd-doc-synthesizer.md": "c2cd65ae13aa33fa", + "agents/gsd-doc-classifier.md": "146acf4d176134b5", + "agents/gsd-doc-synthesizer.md": "b1f5e2eb28fa3659", "agents/gsd-doc-verifier.md": "7ed4d9611f678a95", "agents/gsd-doc-writer.md": "3ed3dc255d7eca8d", "agents/gsd-domain-researcher.md": "049f588663814fa2", @@ -31,7 +31,7 @@ "agents/gsd-roadmapper.md": "840ac933e3b094f9", "agents/gsd-security-auditor.md": "b7202c44366697dd", "agents/gsd-ui-auditor.md": "76f446c50edf81f8", - "agents/gsd-ui-checker.md": "63e5c862bf7bd8ba", + "agents/gsd-ui-checker.md": "2104071d60d917d0", "agents/gsd-ui-researcher.md": "2a1dda374b1958aa", "agents/gsd-user-profiler.md": "ca3bf75581f211a0", "agents/gsd-verifier.md": "8282761ba471c022", diff --git a/tests/ui-checker-adversarial-stance.test.cjs b/tests/ui-checker-adversarial-stance.test.cjs new file mode 100644 index 000000000..36b35e9db --- /dev/null +++ b/tests/ui-checker-adversarial-stance.test.cjs @@ -0,0 +1,34 @@ +'use strict'; +const { test } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); + +test('gsd-ui-checker has an adversarial_stance with FORCE + BLOCK/FLAG/PASS (#16)', () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', 'gsd-ui-checker.md'), 'utf8'); + assert.match(src, //, 'missing '); + assert.match(src, /FORCE stance/, 'missing FORCE stance line'); + assert.match(src, /go soft/i, 'missing go-soft failure list'); + assert.match(src, /BLOCK\b/, 'missing BLOCK tier'); + assert.match(src, /FLAG\b/, 'missing FLAG tier'); +}); + +test('gsd-ui-checker has a third-person named-persona block (#16, 2505.23840)', () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', 'gsd-ui-checker.md'), 'utf8'); + // Named reviewer referred to in third person + assert.match(src, /The Auditor/i, 'missing named third-person reviewer "The Auditor"'); + // Third-person verdict phrasing + assert.match(src, /The Auditor['']s verdict/i, "missing third-person verdict phrasing \"The Auditor's verdict\""); + // Objective (not hostile) framing per 2506.04975 + assert.match(src, /independent/i, 'missing independent/objective framing'); + assert.match(src, /not\s+a\s+standalone\s+accuracy\s+guarantee/i, 'missing limitation on persona efficacy claim'); +}); + +test('gsd-ui-checker has an anti-capitulation rule (#16)', () => { + const src = fs.readFileSync(path.join(__dirname, '..', 'agents', 'gsd-ui-checker.md'), 'utf8'); + assert.match(src, /anti.?capitulat/i, 'missing anti-capitulation rule'); + // Disagreement alone is not grounds to downgrade a BLOCK + assert.match(src, /concrete fix/i, 'missing "concrete fix" requirement for BLOCK downgrade'); + assert.match(src, /Self-correction is allowed/i, 'missing carve-out for evidence-backed self-correction'); + assert.match(src, /prior dimension application was mistaken/i, 'missing mistaken-prior-application carve-out'); +});