Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions .github/workflows/contract-c-non-deciding-shadow-rc0.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Contract C Non-Deciding Shadow RC0

on:
push:
branches:
- research/contract-c-non-deciding-shadow-rc0-20260910
workflow_dispatch:

permissions:
contents: read

jobs:
shadow-contract-pressure:
runs-on: ubuntu-24.04
steps:
- name: Checkout research branch
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Verify exact base and research-only mutation surface
shell: bash
run: |
set -euo pipefail
git merge-base --is-ancestor c3563cff66d2c85dcbf575c693056e2d8e4563d4 HEAD
test "$(git hash-object validators/contract_c.py)" = "9c75ccfbf2223578a8d1a7bf0c39673b394fbea4"
test "$(git hash-object schema/contract-c/1.0.0/schema.json)" = "b0369de9b5c156322d6787261bbc7658a3b33781"
changed="$(git diff --name-only c3563cff66d2c85dcbf575c693056e2d8e4563d4...HEAD)"
printf '%s\n' "$changed"
if printf '%s\n' "$changed" | grep -Ev '^(research/contract_c_non_deciding_shadow_rc0/|\.github/workflows/contract-c-non-deciding-shadow-rc0\.yml$)' | grep -q .; then
echo 'mutation escaped preregistered research-only surface' >&2
exit 1
fi

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install exact repository dependencies
run: python -m pip install -e '.[dev]'

- name: Compile shadow apparatus
run: python -m compileall -q research/contract_c_non_deciding_shadow_rc0

- name: Execute preregistered shadow pressure test
run: |
python -m research.contract_c_non_deciding_shadow_rc0.evaluate \
--repo-root . \
--out build/contract-c-non-deciding-shadow-rc0

- name: Qualify exact committed handoff bytes
shell: bash
run: |
python - <<'PY'
import hashlib
import json
from pathlib import Path
from research.contract_c_non_deciding_shadow_rc0.shadow import validate_shadow_bytes
from validators import contract_c as released

root = Path('research/contract_c_non_deciding_shadow_rc0/handoff')
raw = (root / 'valid-shadow.json').read_bytes()
index = json.loads((root / 'contract-b-index.json').read_text())
delta = json.loads((root / 'schema-delta.json').read_text())

assert hashlib.sha256(raw).hexdigest() == '325962ebcdbf6af836bb6193a451524ccd40b4d10f2394ff9f703fbfce1ec1e3'
obj = released.parse_json_bytes(raw)
assert obj['result_set_id'] == 'result-set:4483272c4f6fbd9cb2362be7e3174bbd00aff3cf761d6c374897f3478818c9f0'
assert validate_shadow_bytes(raw, expected_sha256='325962ebcdbf6af836bb6193a451524ccd40b4d10f2394ff9f703fbfce1ec1e3', contract_b_index=index) == []
assert released.validate_contract_c_bytes(raw, contract_b_index=index)
assert delta['base_schema_blob'] == 'b0369de9b5c156322d6787261bbc7658a3b33781'
assert delta['changes'] == [
{'path': 'properties.contract_c_version.const', 'value': 'research-non-deciding-rc0'},
{'path': '$defs.contribution.properties.channel.enum', 'value': ['support', 'counterevidence', 'non_deciding']},
]
p = obj['propositions'][0]
assert p['conclusion']['causal_form'] == 'independent_sufficient_alternatives'
assert [c['evidence_ref']['passage_id'] for c in p['contributions']] == ['u-a', 'u-b']
assert all(c['channel'] == 'non_deciding' for c in p['contributions'])
assert {b['id'] for b in p['conclusion']['basis_members']} == {c['contribution_id'] for c in p['contributions']}
print(json.dumps({
'handoff_sha256': 'sha256:' + hashlib.sha256(raw).hexdigest(),
'result_set_id': obj['result_set_id'],
'passages': ['u-a', 'u-b'],
'causal_form': p['conclusion']['causal_form'],
}, sort_keys=True))
PY

- name: Re-run released Contract C regression
run: pytest -q tests/test_contract_c_v1.py tests/test_verify_contract_integrity.py

- name: Verify terminal disposition
shell: bash
run: |
python - <<'PY'
import json
from pathlib import Path
p = Path('build/contract-c-non-deciding-shadow-rc0/EVALUATION.json')
data = json.loads(p.read_text())
assert data['research_disposition'] == 'SUPPORTED_BOUNDED_TWO_LEAF_SHADOW_DELTA'
assert data['semantic_schema_delta'] == [
'$defs.contribution.properties.channel.enum',
'properties.contract_c_version.const',
]
assert data['checks']['released_1_0_rejects_shadow'] is True
assert data['checks']['two_neutral_basis_members_preserved'] is True
assert data['interpretation']['released_contract_c_1_0_mutated'] is False
assert data['interpretation']['production_promotion_authorized'] is False
print(json.dumps({
'research_disposition': data['research_disposition'],
'shadow_sha256': data['shadow_sha256'],
'shadow_result_set_id': data['shadow_result_set_id'],
}, sort_keys=True))
PY

- name: Package shadow evidence and handoff
shell: bash
run: |
set -euo pipefail
cp research/contract_c_non_deciding_shadow_rc0/PREREGISTRATION.md build/contract-c-non-deciding-shadow-rc0/
cp -R research/contract_c_non_deciding_shadow_rc0/handoff build/contract-c-non-deciding-shadow-rc0/HANDOFF
tar -czf contract-c-non-deciding-shadow-rc0-${GITHUB_RUN_ID}.tar.gz -C build contract-c-non-deciding-shadow-rc0

- name: Upload shadow evidence
uses: actions/upload-artifact@v4
with:
name: contract-c-non-deciding-shadow-rc0-${{ github.run_id }}
path: contract-c-non-deciding-shadow-rc0-${{ github.run_id }}.tar.gz
if-no-files-found: error
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"artifact_digest":"sha256:7af02c2230be29b893f3480ef25b82a0caf0ce334d3967997ac713ebb659170b","artifact_id":10172768614,"base_sha":"c3563cff66d2c85dcbf575c693056e2d8e4563d4","causal_form":"independent_sufficient_alternatives","handoff_sha256":"sha256:325962ebcdbf6af836bb6193a451524ccd40b4d10f2394ff9f703fbfce1ec1e3","head_sha":"beb195c61e7a85bdb0cb350d85c03ca48177e23d","passage_ids":["u-a","u-b"],"released_contract_c_regression":{"passed":17,"skipped":8},"released_v1_rejects_shadow":true,"research_disposition":"SUPPORTED_BOUNDED_TWO_LEAF_SHADOW_DELTA","result_set_id":"result-set:4483272c4f6fbd9cb2362be7e3174bbd00aff3cf761d6c374897f3478818c9f0","run_id":34529151133,"shadow_channel":"non_deciding"}
86 changes: 86 additions & 0 deletions research/contract_c_non_deciding_shadow_rc0/PREREGISTRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Contract C non-deciding shadow RC0

**Classification:** Draft Research Infrastructure experiment. No production Contract C mutation, version assignment, release, merge, promotion, Decision Engine production change, Contract E, or authorization.

## Exact base

- Apparatus Contracts `main`: `c3563cff66d2c85dcbf575c693056e2d8e4563d4`
- Released Contract C validator blob: `9c75ccfbf2223578a8d1a7bf0c39673b394fbea4`
- Released Contract C schema blob: `b0369de9b5c156322d6787261bbc7658a3b33781`
- CAL repair-comparison PR #100 terminal pressure-test head: `aa5f0f1313e65e6d31493095214c76d743ca6d89`
- Frozen CAL repair-candidate implementation blob: `a7934b3c242dcf1c33a28121b3b141c9c6adc203`
- CAL multiplicity run: `34506201889`
- CAL multiplicity artifact: `10163899726`
- CAL multiplicity artifact digest: `sha256:23ba4cb13870f0b2c5f213d3279faede9d17f19e638dea49444249328a0efb19`

## Question

Can the exact surviving representation family from CAL PR #100 be expressed as a research-only Apparatus shadow contract by adding only one contribution-channel value, `non_deciding`, while preserving the released Contract C 1.0 structural, canonicalization, reference-integrity, Contract-B-binding, causal-multiplicity, and whole-object-identity rules?

## Frozen shadow delta

The shadow wire value is deliberately non-canonical: `research-non-deciding-rc0`.

Relative to released Contract C 1.0.0, the shadow schema may change only:

1. top-level `contract_c_version.const` from `1.0.0` to `research-non-deciding-rc0`;
2. `$defs.contribution.properties.channel.enum` from `[support, counterevidence]` to `[support, counterevidence, non_deciding]`.

No other schema leaf, required field, namespace, causal-form value, assessment state, measurement shape, proposition binding, evidence reference, producer binding, Contract-B binding, or result identity rule may change.

## Validation strategy

The research validator must not fork Contract C semantics wholesale. It must:

- verify the exact two-leaf schema delta above;
- validate shadow whole-object identity with the released canonicalization/result identity algorithm;
- project only the wire sentinel and `non_deciding` channel values to a compatibility copy accepted by the released 1.0 validator;
- run the released validator over that compatibility copy with the exact Contract-B index;
- preserve the actual shadow object for all provenance/multiplicity assertions;
- require at least one `non_deciding` contribution so an unchanged 1.0 object cannot accidentally satisfy the shadow test.

## Preregistered positives

P1. One causal `non_deciding` contribution can be referenced as a normal contribution basis member for a completed `not_checkable` proposition.

P2. Two causal `non_deciding` contributions can be represented as two distinct basis members with `causal_form=independent_sufficient_alternatives`.

P3. Every shadow evidence reference must bind exactly to the supplied Contract-B index.

P4. A `non_deciding` contribution can remain residual without being forced into causal basis.

P5. Existing `support` and `counterevidence` values remain structurally valid in the shadow validator.

P6. The released Contract C 1.0 validator rejects the shadow artifact rather than silently accepting the widened channel or wire sentinel.

P7. Canonical bytes and `result_set_id` remain deterministic under the released algorithm.

## Preregistered falsifiers

F1. The shadow validator must reject a non-deciding basis member whose contribution is absent.

F2. It must reject a contribution reference absent from or mismatched against Contract B.

F3. It must reject `single_necessary` with two basis members and `independent_sufficient_alternatives` with fewer than two.

F4. It must reject a contribution classified simultaneously as causal and residual.

F5. It must reject any retained contribution left unclassified by basis or residual state.

F6. It must reject whole-object/result-set identity tampering.

F7. It must reject arbitrary additional fields.

F8. It must reject unknown channel values other than the exact three frozen values.

F9. The released 1.0 validator accepting a shadow object is a version-boundary failure.

F10. Any implementation requirement to weaken an unrelated released invariant falsifies the minimal-delta claim.

## Allowed outcomes

- `SUPPORTED_BOUNDED_TWO_LEAF_SHADOW_DELTA`
- `FALSIFIED_MINIMAL_SHADOW_DELTA`
- `INCONCLUSIVE_SHADOW_VALIDATOR_INVALID`

A supported result means only that the representation survives this Apparatus research boundary. It does not select a canonical Contract C version or authorize production change.
62 changes: 62 additions & 0 deletions research/contract_c_non_deciding_shadow_rc0/TERMINAL_RECORD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Contract C non-deciding shadow RC0 terminal record

## Disposition

`SUPPORTED_BOUNDED_TWO_LEAF_SHADOW_DELTA`

This is a research-only structural/conformance result. It does not authorize a Contract C version, production schema/validator change, merge, release, tag, promotion, Decision Engine change, Contract E, or authorization.

## Exact execution

- exact tested head: `361f962fb8b0a43b208d739fd57e9aa1f1b364a0`
- exact production base: `c3563cff66d2c85dcbf575c693056e2d8e4563d4`
- run: `34528850394`
- artifact: `10172655148`
- artifact digest: `sha256:94b5edd27cc2515ce9af3c460d88a821c1d59d477c18c97d832a543df2479f24`
- shadow object SHA-256: `sha256:34e3b84357e4424fb69c41fc228c2feda81d73d12bd103ee46132a9bb832f017`
- shadow result-set identity: `result-set:b6c9a7aa7ab0f627fb4cb4d29eb7638a03e8e21f9f5c7aa360f42e99b357ee2b`

## Exact released authority held fixed

- released Contract C validator blob: `9c75ccfbf2223578a8d1a7bf0c39673b394fbea4`
- released Contract C schema blob: `b0369de9b5c156322d6787261bbc7658a3b33781`
- released Contract C 1.0 files were not modified.

## Observed results

The shadow schema differed semantically from released 1.0 at exactly two leaves:

1. `properties.contract_c_version.const`
2. `$defs.contribution.properties.channel.enum`

The only new contribution channel was `non_deciding`.

All preregistered structural controls passed, including:

- one causal non-deciding contribution;
- two causal non-deciding contributions preserving `independent_sufficient_alternatives`;
- residual non-deciding contribution classification;
- legacy support and counterevidence compatibility inside the shadow;
- exact Contract-B evidence-reference checking;
- causal/residual disjointness;
- complete retained-contribution classification;
- causal-form cardinality;
- unknown-field rejection;
- unknown-channel rejection;
- deterministic canonical bytes and result-set identity;
- whole-object hash tamper rejection;
- detection of unrelated schema relaxation.

Released Contract C 1.0 rejected the shadow object specifically because the research wire sentinel is not `1.0.0` and `non_deciding` is not a released 1.0 channel. This is the intended version-boundary negative control.

Released Contract C regression on the same job: `17 passed, 8 skipped`.

## Bounded inference

Within this frozen Apparatus pressure test, the CAL PR #100 survivor can be represented without widening unrelated Contract C semantics. The smallest tested semantic schema delta is one new contribution-channel value plus an explicit research-only wire-version sentinel.

This supports preparing an independent consumer handoff. It does not establish a canonical versioning strategy or production compatibility policy.

## Next falsifier

Freeze only the shadow spec/schema/valid fixture/Contract-B index and their exact hashes. Give those artifacts to a separate consumer without the shadow implementation or evaluator. Require that consumer to reconstruct exact non-deciding provenance and causal multiplicity, reject malformed references/cardinality/version mutations, and demonstrate that destination policy behavior does not reinterpret `non_deciding` as support or counterevidence.
1 change: 1 addition & 0 deletions research/contract_c_non_deciding_shadow_rc0/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Research-only Contract C non-deciding shadow RC0."""
Loading
Loading