Skip to content

Shadow Score Spec v2.0.0 — Level 4: Adversarial Independence - #30

Merged
DUBSOpenHub merged 2 commits into
mainfrom
feat/v2-adversarial-independence
Jul 28, 2026
Merged

Shadow Score Spec v2.0.0 — Level 4: Adversarial Independence#30
DUBSOpenHub merged 2 commits into
mainfrom
feat/v2-adversarial-independence

Conversation

@DUBSOpenHub

Copy link
Copy Markdown
Owner

The hole this closes

Levels 1–3 progressively harden information isolation. They answer "can the Implementer see the sealed tests?" — and they answer it well.

None of them answer "does the Implementer think like the Seal Author?"

All three are silently defeated by a single configuration choice: pointing the Seal Author and the Implementer at the same model. Same-family agents share training data, reasoning priors, and therefore failure modes. If the family doesn't think to test a scenario, it also doesn't think to handle it. The sealed test is never written, the implementation is never hardened, the score reads 0%, and the defect ships green.

The bias is directional. It always pushes toward 0%. A perfectly isolated, fully Level 3 conformant pipeline built on one model family systematically overclaims quality — and does so most confidently on exactly the requirements neither side considered.

This was not hypothetical. The reference implementation had qa_sealed and lead_eng both set to claude-sonnet-4.6: same family on both sides of a test designed to measure independence.

What's new

Section Adds
§3.6 Authorship Independence — strong/weak classes + bias-direction table
§4.2.1 Independence enforced pre-dispatch, not audited afterwards
§4.4.1 Progressive disclosure — bounded escalation that never reveals test source
§4.4.2 Escalation may not move the Implementer into a Seal Author's family
§4.6 Seal Plurality — contradiction vs divergence, and Spec Ambiguity
§5.4 Advisory Reports — when a score MUST be marked non-authoritative
§6 Level 4 — Adversarial Independence

The bias-direction table is the interesting part

A blanket "all roles must differ" rule is wrong — it imposes cost where there's no risk. What matters is which way the bias moves:

Role pair Effect Verdict
Seal Author == Implementer Too low — overclaims quality ❌ MUST NOT
Specifier == Implementer Too low — infers unstated assumptions ❌ MUST NOT
Specifier == Seal Author Too high — conservative ⚠️ MAY, must disclose
Validator == anyone None — it executes, doesn't author ✅ MAY

Upward bias penalises the Implementer for requirements never stated: visible and correctable. Downward bias hides defects. Only the second kind is forbidden.

Seal plurality grades your spec, not your code

One sealed suite tells you whether the implementation is right.
Two independent sealed suites tell you whether the specification is right.

Two authors testing different things is divergence — the expected coverage dividend. Two authors asserting incompatibly on the same behaviour is a contradiction: proof the spec supports two different systems. spec_ambiguity measures that, and it's catchable before any code exists.

Corrections to v1.0.0

§4.3 — sealed tests no longer enter the implementation workspace. v1.0.0 step 1 said to copy them in. That's safe only when validation is terminal. Hardening (§4.4) re-invokes the Implementer after validation, so by cycle 2 the sealed tests sit in a directory it can grep. Agents with unscoped shell tools are bounded by what they can do, not by what the prompt asked them not to. v2.0 validates in a disposable workspace built from the Implementer's commit. Single-shot validators keep the old behaviour via workspace_isolation: "legacy".

§3.5 / §4.4 — Hardening Velocity was uncomputable. Level 3 required tracking it, but nothing required storing initial_shadow_score, and only the final score was persisted. Now has a formula and a recording requirement.

§4.2 — isolation ranking. Topological isolation now ranks above context isolation, with an explicit note that context isolation is insufficient for agents holding unscoped filesystem tools.

Repair: the conformance suite was 0/18

The gap-scoreshadow-score rename had been applied to filenames but to nothing that referenced them. run_conformance.py defaulted to validators/gap-score.py, which doesn't exist — every fixture died with exit code 2. fixtures.json still expected gap_score fields the validators stopped emitting. CONTRIBUTING.md and SECURITY.md pointed at files that aren't there.

CI never ran the suite, so nobody found out.

before:  Results: 0/18 passed (18 failed)
after:   Results: 18/18 passed ✅ All conformant

CI additions, so it can't happen again

  • run the conformance suite
  • assert SPEC.md version matches all three validators
  • fail the build on stale gap-score naming
  • verify every relative markdown link resolves
  • check the schema is well-formed Draft-07

Verification

✅ conformance suite      18/18
✅ Python unit tests      39/39
✅ Go validator           builds + smoke tests pass
✅ JSON schema            valid Draft-07; conditional rules verified
✅ section cross-refs     no dangling § references
✅ markdown links         all resolve
✅ version consistency    SPEC.md == py == sh == go == 2.0.0

Schema conditionals were tested directly — Level 4 without provenance is rejected, advisory: true without advisory_reason is rejected, Level 2 without provenance is allowed.

Reference implementation

DUBSOpenHub/dark-factory#27 implements Level 4 and ships green: implementer anthropic, seal authors openai + google, independence strong, enforced at Phase 0 with abort-on-violation and re-checked in CI.


Breaking: major version bump. Level 3 implementations remain conformant at Level 3; §4.3 changes behaviour for anyone who hardens, with legacy as the opt-out.

Gregg Cochran and others added 2 commits July 28, 2026 10:40
Levels 1-3 progressively harden *information* isolation: they stop the
Implementer from SEEING the sealed tests. All three are silently defeated
by a single configuration choice — pointing the Seal Author and the
Implementer at the same model.

Same-family agents share training data, reasoning priors, and therefore
failure modes. If the family doesn't think to test a scenario, it also
doesn't think to handle it: the sealed test is never written, the score
reads 0%, and the defect ships unflagged. The bias is directional — it
always pushes toward 0%, so a same-family pipeline systematically
overclaims quality.

Spec additions
- 3.6 Authorship Independence: strong/weak classes, and a bias-direction
  table so the rule targets the pairings that actually hide defects
  rather than imposing a blanket "all roles must differ"
- 4.2.1 Independence enforced pre-dispatch, not audited after the fact
- 4.4.1 Progressive disclosure: bounded escalation that never reveals
  test source
- 4.4.2 Escalation may not move the Implementer into a Seal Author family
- 4.6 Seal Plurality: contradiction vs divergence, and Spec Ambiguity —
  two independent suites grade the *specification*, not the code
- 5.4 Advisory Reports: when a score MUST be marked non-authoritative
- Level 4 conformance tier

Corrections to v1.0.0
- 4.3 now validates in a disposable workspace. v1.0.0 said to copy sealed
  tests into the implementation workspace, which is safe only when
  validation is terminal; hardening re-invokes the Implementer afterwards,
  so by cycle 2 the tests sit somewhere it can read. Retained as
  workspace_isolation: "legacy" for single-shot validators.
- 3.5 Hardening Velocity now has a formula, and 4.4 requires recording
  initial_shadow_score before cycle 1 — Level 3 required the metric but
  left it uncomputable
- 4.2 ranks topological isolation above context isolation, which is
  insufficient for agents holding unscoped filesystem tools

Repair: the conformance suite was 0/18
The gap-score -> shadow-score rename had been applied to filenames but not
to anything referencing them. run_conformance.py defaulted to
validators/gap-score.py, which does not exist, so every fixture failed with
exit code 2 and CI never ran the suite to notice. Completed the rename
across fixtures, runner, docs, and go.mod. Now 18/18.

CI additions to prevent recurrence
- run the conformance suite
- assert SPEC.md version matches all three validators
- fail on stale gap-score naming
- verify every relative markdown link resolves
- check the schema is well-formed Draft-07

Schema: provenance fields (independence, implementer_family,
seal_author_families, workspace_isolation, spec_ambiguity, advisory,
seal_broken, hardening_velocity, max_reveal) with conditional rules
requiring provenance at Level 4 and a reason on every advisory report.

Reference implementation: DUBSOpenHub/dark-factory#27

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9cb0b232-bb14-47a5-a150-00e71bdddcae
Integrating v2.0.0 into the reference implementation surfaced a defect in
this spec, not in the implementation.

Section 5.2 mixed dotted paths (sealed_tests.total) with bare names
(shadow_score, independence, conformance_level). Nothing said whether a
bare name lived at the document root or under report. The reference
implementation guessed wrong on conformance_level and shipped
seal_families instead of seal_author_families — and the report still
validated.

That is the failure worth preventing. The Level 4 conditional keys off
report.conformance_level; a value at the root is invisible to it, so the
provenance requirement never fires. The misspelled family field was simply
ignored as an unknown property. Net result: a report asserting Level 4
that the validator never checked, passing green. A conformance framework
that reports success for an unperformed check is worse than one with no
schema at all.

Spec
- section 5.2 field names are now full JSON paths from the document root,
  with an explicit statement that a field at the wrong depth is absent
- added report.seal_author_models and report.implementer_model as
  RECOMMENDED: family is what independence turns on, but the specific model
  is what makes a run reproducible
- implementations MAY add fields, MUST NOT rename listed ones

Schema
- rejects misplaced root-level shadow_score, conformance_level,
  independence, implementer_family, seal_author_families, advisory, each
  naming the correct path in its error
- rejects the superseded seal_families spelling by name rather than
  ignoring it
- machine-enforces section 5.4: independence "weak" and seal_broken true now
  require advisory with a reason, which was prose-only before

Tests
- validators/test_schema.py, 29 cases, wired into CI. Covers the exact
  regression, both drift guards, Level 4 provenance, the advisory rules,
  and value constraints. Includes a case asserting v1.0.0-era reports still
  validate, since v2.0.0 must add fields without invalidating conforming
  v1.0.0 output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9cb0b232-bb14-47a5-a150-00e71bdddcae
@DUBSOpenHub
DUBSOpenHub merged commit 9095472 into main Jul 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant