Condition benchmark claims on the run that produced them
A bundle's verification flags were assertions about methodology that
nothing checked. This makes them conditional on machine-readable
declarations of what the run actually did, and fixes five cases where the
emitter stated something it had not established.
bench/result-schema.json gains a required run_conditions block of ten
closed enumerations -- initialization and mutation path, checkpoint and
index state, index-run ceiling, receipt reconciliation, objects_new
source, commit-id uniqueness, build profile, environment fidelity. It is
not disclosure beside the claims; it is what the claims are conditioned
on, so a harness can only assert what its declaration permits. A prose
caveat field was rejected: free text is not a condition a consumer can
check, and a bundle whose caveats live only in a report reads as
unconditional to everyone who receives it.
The branch conditional forbids the three newly earnable claims on the
journal-drive path and pins its four provenance declarations to the only
values that seam can make. Forbidding the claims alone left the hole one
field over -- a drive bundle could otherwise declare exact receipt
reconciliation it has no receipts to perform.
Emitter defects, each found by reading the schema against the code:
- Setup traffic was inside the measured interval. Both counter baselines
were read only at the end, so repository creation -- which goes through
submit, and therefore fences and signs -- was counted as measured work
while the bundle asserted setup_traffic_excluded. A false exclusion
claim is worse than a wrong number: a wrong number invites scrutiny
and this deflects it.
- A zero-work run produced a schema-valid bundle asserting uniqueness
over zero ids and three-objects-per-commit over zero commits. Both are
vacuously true, which is why they must not be earnable that way: the
result is indistinguishable from a measured run by the consumer the
schema exists to serve. Refused by name at two altitudes.
- An ACK-journal write failure ended the run quietly. It set a stop flag
without recording a refusal, so neither the fatal guard nor the
zero-work guard saw it, and the bundle omitted a committed transaction
while still counting its fence and its signature -- one counted
transaction against two fences and two signings. It is now a fatal
incomplete-accounting refusal carrying the original errno, because the
commit happened: folding it into the refused count would report a
transaction the store committed as one it declined.
- Widening that class to "a failure that produces a value nobody read"
found three more. A shard with no counters summed to zero fences,
silently shrinking the total that bounds every durability claim. A
digest of an unreadable file returned the digest of empty input -- a
well-formed 64-hex value indistinguishable from a real one, feeding
five attested fields. An unreadable /proc/meminfo published one byte
of RAM. All three refuse now.
- Index steady state was inferred from any directory entry, so one stray
file declared the index sealed. Entries are parsed back as index runs
against the root's own uuid; an unparseable entry is reported as
unvalidatable rather than lowering a count, and a backlog is refused
because neither named value describes sealing that did not keep up.
deployment.tmpfs, persistent_data_mount, and hardware.filesystem were
constants -- the emitter could assert deployment facts it had never
checked. They are read from /proc/mounts now. Both deployment fields relax
to booleans so a diagnostic run is representable at all: it was previously
not disqualified but unencodable, and a schema that can only express
successful runs is not a record of what was measured. outcome=pass
requires reference fidelity at every gate, and a diagnostic run may never
carry a pass verdict.
Hardware profiles are derived, never accepted. store-bench parses the
whole frozen profile tables and names a profile only by exact comparison,
iterating every pinned fact rather than every supplied one -- so a fact
the emitter does not model eliminates the profile instead of being
invisible. That took the honest unobserved list on this host from 7 facts
to 24, which is the inversion working. A deployed-node harness supplies
privileged facts as evidence to compare, never as a label. The outcome
derivation now also requires the checkpoint and index conditions, because
fidelity was the only thing preventing a pass and would have stopped being
so the moment profile recognition started working, at which point the
emitter would have produced a pass its own validator rejects.
operation_receipts_reconciled is expressible and deliberately not emitted:
the bench accepts any Committed status without comparing the payload, and
the digest it records is of the operation id rather than the receipt.
Contract review 2026-07-28-C records the amendment and the ceiling it does
not close: run_conditions is self-reported, and only the index-run ceiling
is cross-checked against an independent value. Scope 5.1 records why a
full filesystem is indistinguishable from a concurrency flake by symptom,
and that an I/O error must reach a report with its errno intact -- the
same requirement as the incomplete-accounting refusal above.
scripts/check-phase1.sh GATE_EXIT=0; verify-store-recovery.sh reports
bundle=schema-valid on both paths, zero_work_run=refused, and
unaccounted_ack_run=refused.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cd40e2c892
commit
062797d4b8
|
|
@ -14,6 +14,7 @@
|
|||
"workload",
|
||||
"hardware",
|
||||
"deployment",
|
||||
"run_conditions",
|
||||
"measurement",
|
||||
"counts",
|
||||
"bytes",
|
||||
|
|
@ -65,6 +66,9 @@
|
|||
"deployment": {
|
||||
"$ref": "#/$defs/deployment"
|
||||
},
|
||||
"run_conditions": {
|
||||
"$ref": "#/$defs/run_conditions"
|
||||
},
|
||||
"measurement": {
|
||||
"$ref": "#/$defs/measurement"
|
||||
},
|
||||
|
|
@ -465,10 +469,12 @@
|
|||
],
|
||||
"properties": {
|
||||
"persistent_data_mount": {
|
||||
"const": true
|
||||
"type": "boolean",
|
||||
"description": "Re-pinned to true by the \"reference_profile\" rule in allOf, and a passing run must declare that fidelity. Relaxed from an unconditional const so a diagnostic run on a non-persistent mount is representable-and-disqualified rather than unrepresentable (contract review 2026-07-28-C)."
|
||||
},
|
||||
"tmpfs": {
|
||||
"const": false
|
||||
"type": "boolean",
|
||||
"description": "Re-pinned to false by the \"reference_profile\" rule in allOf. A tmpfs run can never be a pass, because outcome \"pass\" requires reference_profile fidelity, which requires tmpfs false."
|
||||
},
|
||||
"overlay": {
|
||||
"const": false
|
||||
|
|
@ -502,6 +508,103 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"run_conditions": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "The conditions the run was obtained under, as values a consumer can check. Contract review 2026-07-28-C: a bundle whose caveats live only in a human report reads as unconditional to everyone who receives it, and a free-text caveat field is not a condition anything can check. Every field is a closed enumeration or a boolean; there is no prose member and no catch-all value. The verification claims in $defs.verification are conditioned on these declarations, so a run that did not perform a check has no way to assert the claim that names it.",
|
||||
"required": [
|
||||
"initialization_path",
|
||||
"mutation_path",
|
||||
"checkpointing",
|
||||
"index_maintenance",
|
||||
"index_run_ceiling",
|
||||
"receipt_reconciliation",
|
||||
"objects_new_source",
|
||||
"commit_id_uniqueness",
|
||||
"build_profile",
|
||||
"environment_fidelity"
|
||||
],
|
||||
"properties": {
|
||||
"initialization_path": {
|
||||
"enum": [
|
||||
"store_engine_open",
|
||||
"segment_initialize_root",
|
||||
"shard_drive_create"
|
||||
],
|
||||
"description": "How the store root the run measured was created. Only \"store_engine_open\" is the production entry point, and a passing storage_primitive run must declare it. B1 landed startup state 1, so the submit path now builds its root that way and the earlier segment::initialize_root seeding is retired; \"segment_initialize_root\" is retained because a bundle emitted before that change must still be readable and must still be readable as what it was. The journal seam declares \"shard_drive_create\", which is its own creation path and not a weakening."
|
||||
},
|
||||
"mutation_path": {
|
||||
"enum": [
|
||||
"store_engine_submit",
|
||||
"journal_drive"
|
||||
],
|
||||
"description": "The entry point the measured transactions actually went through. This is the branch discriminator for the storage_primitive verification rules in allOf: \"journal_drive\" is the Wave A journal seam below engine.rs, which has no sequencer, no receipts, and no index, and may not assert what it cannot observe."
|
||||
},
|
||||
"checkpointing": {
|
||||
"enum": [
|
||||
"exercised",
|
||||
"enabled_not_reached",
|
||||
"unimplemented",
|
||||
"disabled_by_configuration"
|
||||
],
|
||||
"description": "Scope §7 requires that the P2 runs not have been achieved with checkpointing disabled. That clause lived only in prose until this review; it is now mechanical, because a passing storage_primitive run must declare \"exercised\". \"unimplemented\" is today's honest value: StoreEngine::checkpoint returns NotImplemented, so no checkpoint is taken."
|
||||
},
|
||||
"index_maintenance": {
|
||||
"enum": [
|
||||
"runs_sealed",
|
||||
"deltas_retained_in_memory",
|
||||
"no_index_in_path"
|
||||
],
|
||||
"description": "Whether the index reached a steady state. \"deltas_retained_in_memory\" is a run that holds every delta layer it published and whose lookup fan-out grows for its whole duration, which is not the steady state a P2 measurement is of; a passing storage_primitive run must declare \"runs_sealed\". \"no_index_in_path\" is the journal seam, where nothing below engine.rs touches an index at all."
|
||||
},
|
||||
"index_run_ceiling": {
|
||||
"enum": [
|
||||
"store_default",
|
||||
"raised_because_index_sealing_unimplemented"
|
||||
],
|
||||
"description": "Whether StoreOptions::max_index_runs was left at the store default (64) or raised so the run could reach its measured seconds despite unimplemented index-delta sealing. Cross-checked against resources.configured_ceilings.max_index_runs by the two \"index run ceiling\" rules in allOf: \"store_default\" bounds the recorded value at 64 and the raised value floors it at 65, so a bundle that declares one and records the other is invalid. The recorded value must be the value the run configured, never a constant restated here."
|
||||
},
|
||||
"receipt_reconciliation": {
|
||||
"enum": [
|
||||
"exact_receipts_reconciled",
|
||||
"canonical_receipt_digest_reconciled",
|
||||
"acceptance_of_any_committed_status",
|
||||
"no_receipts_in_path"
|
||||
],
|
||||
"description": "What the run reconciled each acknowledged operation against. verification.operation_receipts_reconciled is required exactly when this is one of the first two values and forbidden under the last two. Today's harness reads back TransactionStatus and accepts any Committed(_) payload, and the receipt_digest it journals is a digest of the operation id rather than of the receipt, so it must declare \"acceptance_of_any_committed_status\" and consequently may not assert the claim. \"no_receipts_in_path\" is the journal seam, which produces no receipts to reconcile."
|
||||
},
|
||||
"objects_new_source": {
|
||||
"enum": [
|
||||
"summed_from_receipts",
|
||||
"derived_from_transaction_count"
|
||||
],
|
||||
"description": "Where counts.objects_new came from. verification.objects_new_equals_three_per_commit is forbidden under \"derived_from_transaction_count\": a harness that computes objects_new as transactions * 3 and then asserts the flag has written a tautology, not a check, and that is what the claim was originally excluded for. \"summed_from_receipts\" means each committed receipt's own objects_new was summed independently and compared against a separately counted 3 * counts.counted_commits."
|
||||
},
|
||||
"commit_id_uniqueness": {
|
||||
"enum": [
|
||||
"checked_globally_across_ack_records",
|
||||
"inferred_from_seed_domains",
|
||||
"not_checked"
|
||||
],
|
||||
"description": "How blob, tree, and commit identifier uniqueness was established. verification.unique_blob_tree_commit_ids is forbidden under the last two values. Per-record uniqueness is not uniqueness: two acknowledgment records may each be internally distinct and still share a commit id. Distinct generator seed domains make a collision unlikely rather than absent, which is an argument and not a check, so \"inferred_from_seed_domains\" is named here rather than folded into the passing value."
|
||||
},
|
||||
"build_profile": {
|
||||
"enum": [
|
||||
"debug",
|
||||
"release",
|
||||
"release_with_debug_assertions"
|
||||
],
|
||||
"description": "The cargo profile the measured binary was built with. \"reference_profile\" environment fidelity requires \"release\"; a debug run is recordable, and is thereby disqualified from a pass rather than silently comparable to a release number."
|
||||
},
|
||||
"environment_fidelity": {
|
||||
"enum": [
|
||||
"reference_profile",
|
||||
"diagnostic"
|
||||
],
|
||||
"description": "Whether the run met the frozen environment. \"reference_profile\" re-pins deployment.persistent_data_mount true, deployment.tmpfs false, build_profile \"release\", and a named hardware profile. \"diagnostic\" admits a non-persistent mount or a debug build and is mechanically disqualified: outcome may only be \"fail\" or \"preliminary\" and no verdict may be \"pass\". outcome \"pass\" requires \"reference_profile\" at every gate, so nothing about this relaxes what a claim costs."
|
||||
}
|
||||
}
|
||||
},
|
||||
"measurement": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
|
@ -672,6 +775,16 @@
|
|||
"configured_ceilings": {
|
||||
"type": "object",
|
||||
"minProperties": 1,
|
||||
"required": [
|
||||
"max_index_runs"
|
||||
],
|
||||
"properties": {
|
||||
"max_index_runs": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "The StoreOptions::max_index_runs the run actually configured, read back from the options the store opened with — never the store default restated here, and never omitted. Bounded against run_conditions.index_run_ceiling by the two \"index run ceiling\" rules in allOf, so a defaulted or contradicted value is invalid rather than merely unverified. It is a ceiling this workload genuinely reaches: index-delta sealing being unimplemented makes it the limit submit refuses at."
|
||||
}
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
|
|
@ -752,11 +865,11 @@
|
|||
},
|
||||
"unique_blob_tree_commit_ids": {
|
||||
"const": true,
|
||||
"description": "Not applicable at storage_primitive, where no object graph exists; omitted there rather than falsified, since false would claim the check was applicable and failed."
|
||||
"description": "Every blob, tree, and commit identifier the run acknowledged is distinct, checked globally across every recovered acknowledgment record rather than within each record and never inferred from distinct generator seed domains. Earnable at storage_primitive only through StoreEngine::submit, where the transactions carry real objects; forbidden on the journal seam, which has none. Gated on run_conditions.commit_id_uniqueness (contract review 2026-07-28-C)."
|
||||
},
|
||||
"objects_new_equals_three_per_commit": {
|
||||
"const": true,
|
||||
"description": "Counted independently of the transaction total, not derived from it. A harness that computes objects_new as transactions * 3 and then asserts this flag has written a tautology, not a check. Absent at storage_primitive, which creates no objects."
|
||||
"description": "Receipt-reported objects_new, summed independently across every committed receipt, equals a separately counted 3 * counts.counted_commits. Both sides must be counted; deriving either from the transaction total makes the assertion unfailable, which is what this claim was originally excluded for. Earnable at storage_primitive only through StoreEngine::submit, where the store stages the canonical three objects per commit and reports them on the receipt. Gated on run_conditions.objects_new_source (contract review 2026-07-28-C)."
|
||||
},
|
||||
"blobs_recomputed": {
|
||||
"const": true,
|
||||
|
|
@ -768,7 +881,7 @@
|
|||
},
|
||||
"operation_receipts_reconciled": {
|
||||
"const": true,
|
||||
"description": "Not applicable at storage_primitive, where no object graph exists; omitted there rather than falsified, since false would claim the check was applicable and failed."
|
||||
"description": "Every acknowledged operation was read back and its receipt reconciled against the receipt the run recorded when it acknowledged, either exactly or through a frozen canonical receipt digest. Approved in principle for the StoreEngine::submit path and NOT EARNED by the emitter as it stands: store-bench accepts any TransactionStatus::Committed(_) payload without comparing it, and the receipt_digest it journals is a digest of the operation id rather than of the receipt, so it must declare run_conditions.receipt_reconciliation = \"acceptance_of_any_committed_status\" and is thereby forbidden from asserting this. Expressible now so that landing the reconciliation is an emitter change and not a second schema amendment (contract review 2026-07-28-C)."
|
||||
},
|
||||
"metadata_complete": {
|
||||
"const": true,
|
||||
|
|
@ -1018,26 +1131,11 @@
|
|||
"verification": {
|
||||
"not": {
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"unique_blob_tree_commit_ids"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"objects_new_equals_three_per_commit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"blobs_recomputed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"operation_receipts_reconciled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"metadata_complete"
|
||||
|
|
@ -1054,13 +1152,33 @@
|
|||
"commits_in_recovered_closure"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "The claims forbidden at this gate on every path, whichever entry point was measured. blobs_recomputed and metadata_complete require an object graph the store is forbidden to traverse (plan §5.1), and commits_in_recovered_closure requires the ref closure that traversal would produce, so neither path can earn them and this is not branch-conditional. The three claims that became earnable through StoreEngine::submit are ruled on by the two mutation-path rules below."
|
||||
},
|
||||
"else": {
|
||||
"properties": {
|
||||
"promotable": {
|
||||
"const": true
|
||||
},
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"initialization_path": {
|
||||
"const": "store_engine_open"
|
||||
},
|
||||
"mutation_path": {
|
||||
"const": "store_engine_submit"
|
||||
},
|
||||
"checkpointing": {
|
||||
"enum": [
|
||||
"exercised",
|
||||
"enabled_not_reached"
|
||||
]
|
||||
},
|
||||
"index_maintenance": {
|
||||
"const": "runs_sealed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"workload": {
|
||||
"properties": {
|
||||
"validation_flags": {
|
||||
|
|
@ -1142,6 +1260,501 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "the journal-drive seam may not assert what it cannot observe",
|
||||
"description": "Contract review 2026-07-28-C. The three claims that became earnable through StoreEngine::submit stay forbidden here, and the provenance declarations are pinned to the only values the seam can truthfully make. Forbidding the claims alone would not be enough: a drive-path bundle could otherwise declare exact receipt reconciliation or a global uniqueness check it has no receipts and no objects to perform, and the pins are what make that combination invalid rather than merely unverified.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"gate": {
|
||||
"const": "storage_primitive"
|
||||
},
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"mutation_path": {
|
||||
"const": "journal_drive"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mutation_path"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"gate",
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"verification": {
|
||||
"not": {
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"unique_blob_tree_commit_ids"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"objects_new_equals_three_per_commit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"operation_receipts_reconciled"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"index_maintenance": {
|
||||
"const": "no_index_in_path"
|
||||
},
|
||||
"receipt_reconciliation": {
|
||||
"const": "no_receipts_in_path"
|
||||
},
|
||||
"objects_new_source": {
|
||||
"const": "derived_from_transaction_count"
|
||||
},
|
||||
"commit_id_uniqueness": {
|
||||
"const": "not_checked"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "the production submit path at storage_primitive earns two claims and must state them",
|
||||
"description": "Contract review 2026-07-28-C. StoreEngine::submit stages the canonical three objects per commit and reports them on its own receipt, and the transactions carry real blob, tree, and commit identifiers, so these two claims are no longer inapplicable — they are required, with the provenance that makes each a check rather than a restatement. operation_receipts_reconciled is deliberately absent from this list: it is approved in principle and not yet earned, and the receipt-reconciliation rule below is what decides it.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"gate": {
|
||||
"const": "storage_primitive"
|
||||
},
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"mutation_path": {
|
||||
"const": "store_engine_submit"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mutation_path"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"gate",
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"verification": {
|
||||
"properties": {
|
||||
"unique_blob_tree_commit_ids": {
|
||||
"const": true
|
||||
},
|
||||
"objects_new_equals_three_per_commit": {
|
||||
"const": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"unique_blob_tree_commit_ids",
|
||||
"objects_new_equals_three_per_commit"
|
||||
]
|
||||
},
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"initialization_path": {
|
||||
"enum": [
|
||||
"store_engine_open",
|
||||
"segment_initialize_root"
|
||||
]
|
||||
},
|
||||
"index_maintenance": {
|
||||
"enum": [
|
||||
"runs_sealed",
|
||||
"deltas_retained_in_memory"
|
||||
]
|
||||
},
|
||||
"receipt_reconciliation": {
|
||||
"enum": [
|
||||
"exact_receipts_reconciled",
|
||||
"canonical_receipt_digest_reconciled",
|
||||
"acceptance_of_any_committed_status"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "objects_new_equals_three_per_commit requires an independently summed objects_new",
|
||||
"description": "Applies at every gate, not only storage_primitive. A count derived from the transaction total makes the claim unfailable wherever it is asserted.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"objects_new_source": {
|
||||
"const": "derived_from_transaction_count"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"objects_new_source"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"verification": {
|
||||
"not": {
|
||||
"required": [
|
||||
"objects_new_equals_three_per_commit"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "unique_blob_tree_commit_ids requires a global uniqueness check",
|
||||
"description": "Applies at every gate. Per-record uniqueness and distinct seed domains are both weaker than the claim: the first cannot see a collision between two records, and the second is an argument about likelihood rather than an observation.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"commit_id_uniqueness": {
|
||||
"enum": [
|
||||
"inferred_from_seed_domains",
|
||||
"not_checked"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"commit_id_uniqueness"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"verification": {
|
||||
"not": {
|
||||
"required": [
|
||||
"unique_blob_tree_commit_ids"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "operation_receipts_reconciled is forbidden where no receipt was reconciled",
|
||||
"description": "Contract review 2026-07-28-C, and the reason the claim can be landed before it is earned. Accepting any Committed status is not reconciling a receipt; it reports that something committed, which acknowledged_sequences_reconciled already says. The journal seam declares no_receipts_in_path and is covered by the same clause. Both values are named here and both earning values are named in the companion rule below, so neither rule has an else branch that would fire on a bundle with no declaration at all.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"receipt_reconciliation": {
|
||||
"enum": [
|
||||
"acceptance_of_any_committed_status",
|
||||
"no_receipts_in_path"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"receipt_reconciliation"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"verification": {
|
||||
"not": {
|
||||
"required": [
|
||||
"operation_receipts_reconciled"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "operation_receipts_reconciled is required where a receipt was reconciled",
|
||||
"description": "A run that reconciled exact receipts, or a frozen canonical receipt digest, must assert the claim rather than leave it optional: the check was performed and its result is a required part of the record. On the journal-drive path this rule and the mutation-path rule combine to make an exact-receipt declaration unsatisfiable, which is the intended reading — a seam with no receipts cannot have reconciled any. Stated as its own rule rather than as the else of the rule above so that neither fires on a bundle carrying no declaration at all: absence of run_conditions is refused by the top-level required list, and one refusal reported once is worth more than the same defect reported under a claim the run never mentioned.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"receipt_reconciliation": {
|
||||
"enum": [
|
||||
"exact_receipts_reconciled",
|
||||
"canonical_receipt_digest_reconciled"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"receipt_reconciliation"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"verification": {
|
||||
"properties": {
|
||||
"operation_receipts_reconciled": {
|
||||
"const": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation_receipts_reconciled"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "index run ceiling: a declared store default bounds the recorded value",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"index_run_ceiling": {
|
||||
"const": "store_default"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index_run_ceiling"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"resources": {
|
||||
"properties": {
|
||||
"configured_ceilings": {
|
||||
"properties": {
|
||||
"max_index_runs": {
|
||||
"maximum": 64
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "index run ceiling: a declared raise must record a raised value",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"index_run_ceiling": {
|
||||
"const": "raised_because_index_sealing_unimplemented"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index_run_ceiling"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"resources": {
|
||||
"properties": {
|
||||
"configured_ceilings": {
|
||||
"properties": {
|
||||
"max_index_runs": {
|
||||
"minimum": 65
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "reference-profile fidelity re-pins the environment the deployment schema used to pin outright",
|
||||
"description": "Contract review 2026-07-28-C. deployment.persistent_data_mount and deployment.tmpfs were unconditional consts, which made a diagnostic tmpfs run unrepresentable rather than disqualified. They are re-pinned here, and outcome \"pass\" requires this fidelity at every gate, so nothing a claim used to cost has changed.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"environment_fidelity": {
|
||||
"const": "reference_profile"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"environment_fidelity"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"deployment": {
|
||||
"properties": {
|
||||
"persistent_data_mount": {
|
||||
"const": true
|
||||
},
|
||||
"tmpfs": {
|
||||
"const": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"build_profile": {
|
||||
"const": "release"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hardware": {
|
||||
"properties": {
|
||||
"profile": {
|
||||
"enum": [
|
||||
"minimum-30k",
|
||||
"release-60k"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "a diagnostic run is representable and mechanically disqualified",
|
||||
"description": "Contract review 2026-07-28-C. The alternative was what stood before it: a debug, tmpfs diagnostic run could not be encoded at all, so its number lived on a console and in prose. Recording it is worth nothing unless the record also refuses to let it be read as a result, so the outcome is bounded and no verdict may be pass.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"environment_fidelity": {
|
||||
"const": "diagnostic"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"environment_fidelity"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"run_conditions"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"outcome": {
|
||||
"enum": [
|
||||
"fail",
|
||||
"preliminary"
|
||||
]
|
||||
},
|
||||
"verdicts": {
|
||||
"additionalProperties": {
|
||||
"enum": [
|
||||
"fail",
|
||||
"not-applicable"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "a passing run at any gate must have met the reference environment",
|
||||
"if": {
|
||||
"properties": {
|
||||
"outcome": {
|
||||
"const": "pass"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"outcome"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"environment_fidelity": {
|
||||
"const": "reference_profile"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "a passing storage_primitive run must have measured the production path in a steady state",
|
||||
"description": "Scope §7 requires the P2 runs not to have been achieved with checkpointing disabled, and a run holding every index delta in memory for its whole duration is not the steady state a P2 number describes. Both were prose until contract review 2026-07-28-C; here they are conditions a consumer checks. A root seeded outside StoreEngine::open is disclosed rather than forbidden — but it cannot ride into a pass.",
|
||||
"if": {
|
||||
"properties": {
|
||||
"gate": {
|
||||
"const": "storage_primitive"
|
||||
},
|
||||
"outcome": {
|
||||
"const": "pass"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"gate",
|
||||
"outcome"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"run_conditions": {
|
||||
"properties": {
|
||||
"initialization_path": {
|
||||
"const": "store_engine_open"
|
||||
},
|
||||
"mutation_path": {
|
||||
"const": "store_engine_submit"
|
||||
},
|
||||
"checkpointing": {
|
||||
"const": "exercised"
|
||||
},
|
||||
"index_maintenance": {
|
||||
"const": "runs_sealed"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "a passing run must meet the section 3 one-minute-window rule",
|
||||
"if": {
|
||||
|
|
|
|||
|
|
@ -157,9 +157,14 @@ fn result_schema_requires_integrity_durability_and_all_independent_verdicts() {
|
|||
schema["$defs"]["workload"]["properties"]["writer_group_limit"]["maximum"].as_u64(),
|
||||
Some(512)
|
||||
);
|
||||
// `tmpfs` and `persistent_data_mount` stopped being unconditional consts in
|
||||
// contract review 2026-07-28-C so a diagnostic run is representable. They
|
||||
// are re-pinned under `reference_profile` fidelity, which a passing run
|
||||
// must declare — asserted in full by
|
||||
// `a_diagnostic_environment_is_representable_but_can_never_pass`.
|
||||
assert_eq!(
|
||||
schema["$defs"]["deployment"]["properties"]["tmpfs"]["const"].as_bool(),
|
||||
Some(false)
|
||||
schema["$defs"]["deployment"]["properties"]["tmpfs"]["type"].as_str(),
|
||||
Some("boolean")
|
||||
);
|
||||
assert_eq!(
|
||||
schema["$defs"]["deployment"]["properties"]["remote_storage"]["const"].as_bool(),
|
||||
|
|
@ -225,11 +230,13 @@ fn result_schema_requires_integrity_durability_and_all_independent_verdicts() {
|
|||
.iter()
|
||||
.find(|rule| {
|
||||
// The per-gate latency ceilings became `outcome`-conditional too,
|
||||
// so `outcome == "pass"` alone now matches four other rules. The
|
||||
// window rule is the one that applies to every gate: it keys on
|
||||
// `outcome` and nothing else.
|
||||
// so `outcome == "pass"` alone now matches four other rules, and
|
||||
// since contract review 2026-07-28-C the environment-fidelity rule
|
||||
// keys on `outcome` and nothing else as well. The window rule is the
|
||||
// gate-independent one that constrains `measurement`.
|
||||
rule["if"]["properties"]["outcome"]["const"] == "pass"
|
||||
&& rule["if"]["properties"]["gate"].is_null()
|
||||
&& !rule["then"]["properties"]["measurement"].is_null()
|
||||
})
|
||||
.expect("missing the outcome-conditional window rule");
|
||||
assert_eq!(
|
||||
|
|
@ -455,10 +462,17 @@ fn verification_claims_are_pinned_per_gate_like_validation_flags() {
|
|||
"every instance gate must still re-pin closure to true"
|
||||
);
|
||||
|
||||
// The five object-graph claims are *forbidden* at storage_primitive, not
|
||||
// merely optional. There is no object graph at this layer, so `false`
|
||||
// would be its own untrue statement: it claims the check applied and did
|
||||
// not pass. Absence is the only honest encoding.
|
||||
// Two of the five object-graph claims are forbidden at storage_primitive on
|
||||
// *every* path, not merely optional: no path below the instance can
|
||||
// recompute a blob or complete object metadata, so `false` would be its own
|
||||
// untrue statement — it claims the check applied and did not pass. Absence
|
||||
// is the only honest encoding.
|
||||
//
|
||||
// The other three moved to the mutation-path rules in contract review
|
||||
// 2026-07-28-C, because `StoreEngine::submit` genuinely earns two of them
|
||||
// and can express the third. They are still forbidden on the journal-drive
|
||||
// seam, which is pinned by
|
||||
// `the_drive_path_may_not_assert_the_claims_the_submit_path_earns`.
|
||||
const GRAPH_CLAIMS: &[&str] = &[
|
||||
"unique_blob_tree_commit_ids",
|
||||
"objects_new_equals_three_per_commit",
|
||||
|
|
@ -466,15 +480,22 @@ fn verification_claims_are_pinned_per_gate_like_validation_flags() {
|
|||
"operation_receipts_reconciled",
|
||||
"metadata_complete",
|
||||
];
|
||||
const FORBIDDEN_ON_EVERY_PATH: &[&str] = &["blobs_recomputed", "metadata_complete"];
|
||||
let forbidden = rule["then"]["properties"]["verification"]["not"]["anyOf"]
|
||||
.as_array()
|
||||
.expect("storage_primitive must forbid the object-graph claims outright");
|
||||
for claim in GRAPH_CLAIMS {
|
||||
.expect("storage_primitive must forbid the unearnable claims outright");
|
||||
assert_eq!(
|
||||
forbidden.len(),
|
||||
FORBIDDEN_ON_EVERY_PATH.len(),
|
||||
"the gate-wide forbidden set must be exactly the claims no path can earn; \
|
||||
anything else belongs in a mutation-path rule where the path is named"
|
||||
);
|
||||
for claim in FORBIDDEN_ON_EVERY_PATH {
|
||||
assert!(
|
||||
forbidden
|
||||
.iter()
|
||||
.any(|clause| clause["required"][0] == serde_json::json!(claim)),
|
||||
"{claim} must be forbidden at storage_primitive, not left optional"
|
||||
"{claim} must be forbidden at storage_primitive on every path"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -738,3 +759,757 @@ fn federation_workload_freezes_projection_rtt_partition_and_digest_gates() {
|
|||
Some(true)
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Contract review 2026-07-28-C: the run-conditions block and the two
|
||||
// mutation-path branches
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// Scope §6.6 requires contract tests for both the submit and journal-drive
|
||||
// branches. The tests above assert the *shape* of the schema — which rule
|
||||
// exists, what it pins — which is necessary and is not sufficient: a
|
||||
// conditional can be structurally present and still admit the document it was
|
||||
// written to reject. Everything below validates whole bundles through the same
|
||||
// validator `scripts/verify-store-recovery.sh` and `store-bench`'s own tests
|
||||
// use, so the gate, the emitter, and this file cannot disagree about what valid
|
||||
// means.
|
||||
//
|
||||
// There is no JSON Schema crate in the workspace and adding one is a
|
||||
// `Cargo.toml` change; validation therefore shells out to `python3` with
|
||||
// `jsonschema`. A missing interpreter or module is a test *failure*, never a
|
||||
// skip. A validation that silently does not run reads as a passing suite, which
|
||||
// is exactly how a schema stops being a contract.
|
||||
|
||||
/// Exit 0 clean, exit 1 with one error per line on stdout, exit 2 if the
|
||||
/// validator itself is unavailable.
|
||||
const VALIDATE_PY: &str = "\
|
||||
import json, sys
|
||||
try:
|
||||
import jsonschema
|
||||
except ImportError:
|
||||
sys.stderr.write('jsonschema is not installed\\n')
|
||||
sys.exit(2)
|
||||
schema = json.load(open(sys.argv[1]))
|
||||
instance = json.load(open(sys.argv[2]))
|
||||
validator = jsonschema.Draft202012Validator(
|
||||
schema, format_checker=jsonschema.FormatChecker()
|
||||
)
|
||||
errors = sorted(validator.iter_errors(instance), key=lambda e: list(e.path))
|
||||
for error in errors:
|
||||
sys.stdout.write(f'{list(error.path)}: {error.message}\\n')
|
||||
sys.exit(1 if errors else 0)
|
||||
";
|
||||
|
||||
/// Every validator error for `bundle`, or an empty vector.
|
||||
fn schema_errors(bundle: &serde_json::Value) -> Vec<String> {
|
||||
let directory = tempfile::tempdir().expect("tempdir");
|
||||
let instance = directory.path().join("bundle.json");
|
||||
std::fs::write(
|
||||
&instance,
|
||||
serde_json::to_vec_pretty(bundle).expect("encode"),
|
||||
)
|
||||
.expect("write");
|
||||
let schema = repository_root().join("bench/result-schema.json");
|
||||
|
||||
let output = std::process::Command::new("python3")
|
||||
.arg("-c")
|
||||
.arg(VALIDATE_PY)
|
||||
.arg(&schema)
|
||||
.arg(&instance)
|
||||
.output()
|
||||
.expect(
|
||||
"python3 must be available: these tests validate bundles against \
|
||||
bench/result-schema.json, and a validation that cannot run is not a \
|
||||
passing test",
|
||||
);
|
||||
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
|
||||
match output.status.code() {
|
||||
Some(0) => Vec::new(),
|
||||
Some(1) => stdout.lines().map(str::to_string).collect(),
|
||||
other => panic!(
|
||||
"the schema validator could not run (exit {other:?}). jsonschema must be \
|
||||
installed; a skipped validation would let the schema and the emitter \
|
||||
drift with nothing to notice.\nstdout: {stdout}\nstderr: {stderr}"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_valid(bundle: &serde_json::Value, why: &str) {
|
||||
let errors = schema_errors(bundle);
|
||||
assert!(errors.is_empty(), "{why}\n{}", errors.join("\n"));
|
||||
}
|
||||
|
||||
fn assert_invalid(bundle: &serde_json::Value, why: &str) {
|
||||
assert!(!schema_errors(bundle).is_empty(), "{why}");
|
||||
}
|
||||
|
||||
const HEX64: &str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
||||
|
||||
/// A bundle that a `--path submit` run can honestly emit *today*, and the exact
|
||||
/// shape §6.6's emitter follow-up must produce.
|
||||
///
|
||||
/// Every declaration in `run_conditions` is the truthful value for the emitter
|
||||
/// as it stands at `store-bench.rs`: the root is seeded by
|
||||
/// `segment::initialize_root`, `StoreEngine::checkpoint` is unimplemented, the
|
||||
/// index-run ceiling is raised to 1,000,000 because delta sealing is
|
||||
/// unimplemented, and the reconciliation accepts any `Committed(_)` status. So
|
||||
/// the fixture is not a hypothetical: if this validates and the emitter's output
|
||||
/// does not, the difference is the emitter's to close.
|
||||
fn submit_path_bundle() -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"schema_version": 1,
|
||||
"gate": "storage_primitive",
|
||||
"run_id": "engine-wave-b-0123456789abcdef",
|
||||
"attestation": {
|
||||
"signer": format!("ed25519:{HEX64}"),
|
||||
"key_epoch": 0,
|
||||
"content_digest": HEX64,
|
||||
"signature": format!("{HEX64}{HEX64}")
|
||||
},
|
||||
"source": {
|
||||
"revision": "e050b6de050b6de050b6de050b6de050b6de050b",
|
||||
"dirty_tree_digest": HEX64,
|
||||
"cargo_lock_digest": HEX64,
|
||||
"rustc": "rustc 1.90.0",
|
||||
"rustflags": ""
|
||||
},
|
||||
"artifacts": {
|
||||
"binary_digest": HEX64,
|
||||
"config_digest": HEX64,
|
||||
"workload_digest": HEX64,
|
||||
"corpus_digest": HEX64,
|
||||
"raw_metrics_digest": HEX64,
|
||||
"telemetry_versions": { "store-bench": "0.1.0" }
|
||||
},
|
||||
"workload": {
|
||||
"name": "canonical-small-commit",
|
||||
"seed": 126_394_451_485_337i64,
|
||||
"topology": "many-repo",
|
||||
"selection": "uniform",
|
||||
"client_batch_commits": 1,
|
||||
"writer_group_limit": 512,
|
||||
"persistent_clients": 64,
|
||||
"validation_flags": {
|
||||
"request_signature": false,
|
||||
"replay": false,
|
||||
"pack_hash_and_framing": false,
|
||||
"outer_embedded_type_match": false,
|
||||
"complete_graph": false,
|
||||
"authority_and_role": false,
|
||||
"instance_policy": false,
|
||||
"repository_policy": false,
|
||||
"typed_ref_cas": true,
|
||||
"fast_forward": false,
|
||||
"durability_fence_before_response": true
|
||||
},
|
||||
"generator": "blake3-xof(seed || repo_ordinal_le || ref_ordinal_le || commit_ordinal_le)"
|
||||
},
|
||||
"hardware": {
|
||||
"profile": "diagnostic",
|
||||
"cpu": "AMD Ryzen 7 9800X3D",
|
||||
"numa": "nodes=1",
|
||||
"governor": "performance",
|
||||
"microcode": "0x0b404023",
|
||||
"ram_bytes": 68_719_476_736i64,
|
||||
"swap_events": 0,
|
||||
"filesystem": "btrfs",
|
||||
"mount_options": ["nodatacow"],
|
||||
"nvme": "Samsung SSD 990 PRO 1TB",
|
||||
"firmware": "4B2QJXD7",
|
||||
"write_cache": "enabled",
|
||||
"barriers": "enabled",
|
||||
"scheduler": "none",
|
||||
"temperature_celsius": 41.0,
|
||||
"nic": "none (in-process P2)",
|
||||
"driver": "none (in-process P2)",
|
||||
"link_mbps": 1,
|
||||
"mtu": 1500,
|
||||
"kernel": "Linux 6.18.30-p1-gentoo-dist"
|
||||
},
|
||||
"deployment": {
|
||||
"persistent_data_mount": true,
|
||||
"tmpfs": false,
|
||||
"overlay": false,
|
||||
"remote_storage": false,
|
||||
"durability_enabled": true,
|
||||
"systemd": "none (in-process P2)",
|
||||
"cgroup": "none (in-process P2)",
|
||||
"proxy": "none (in-process P2)",
|
||||
"tls": "none (in-process P2)",
|
||||
"store_directory_attributes": "nodatacow"
|
||||
},
|
||||
"run_conditions": {
|
||||
"initialization_path": "segment_initialize_root",
|
||||
"mutation_path": "store_engine_submit",
|
||||
"checkpointing": "unimplemented",
|
||||
"index_maintenance": "deltas_retained_in_memory",
|
||||
"index_run_ceiling": "raised_because_index_sealing_unimplemented",
|
||||
"receipt_reconciliation": "acceptance_of_any_committed_status",
|
||||
"objects_new_source": "summed_from_receipts",
|
||||
"commit_id_uniqueness": "checked_globally_across_ack_records",
|
||||
"build_profile": "debug",
|
||||
"environment_fidelity": "diagnostic"
|
||||
},
|
||||
"measurement": {
|
||||
"warmup_seconds": 0,
|
||||
"measured_seconds": 2,
|
||||
"repetition": 1,
|
||||
"started_at": "2026-07-28T00:00:00Z",
|
||||
"ended_at": "2026-07-28T00:00:02Z",
|
||||
"one_minute_windows": [8052.0],
|
||||
"histogram_format": "ascending-micros-csv/blake3",
|
||||
"coordinated_omission_corrected": false,
|
||||
"windows_meeting_target_percent": 100.0,
|
||||
"windows_below_floor_count": 0
|
||||
},
|
||||
"counts": {
|
||||
"offered_requests": 16104,
|
||||
"accepted_requests": 16104,
|
||||
"rejected_requests": 0,
|
||||
"duplicate_requests": 0,
|
||||
"acknowledged_requests": 16104,
|
||||
"counted_commits": 16104,
|
||||
"objects_new": 48312
|
||||
},
|
||||
"bytes": { "raw": 21_004_800, "pack_compressed": 0, "application": 21_004_800, "wire": 0 },
|
||||
"latency_micros": {
|
||||
"p50": 900, "p95": 3000, "p99": 7000, "max": 40000,
|
||||
"histogram_digest": HEX64
|
||||
},
|
||||
"resources": {
|
||||
"configured_ceilings": {
|
||||
"max_index_runs": 1_000_000,
|
||||
"writer_group_transactions": 512.0,
|
||||
"journal_preallocate_bytes": 67_108_864.0,
|
||||
"free_space_required_bytes": 1_073_741_824.0,
|
||||
"latency_p99_ceiling_micros": 50_000.0
|
||||
},
|
||||
"observed_peaks": { "free_space_available_bytes": 1_099_511_627_776.0 },
|
||||
"time_series_digest": HEX64,
|
||||
"cpu_percent": 0.0,
|
||||
"storage_utilization_percent": 0.0,
|
||||
"memory_current_bytes": 0,
|
||||
"open_fds": 0,
|
||||
"compaction_debt_returned_low": true,
|
||||
"no_growth_passed": true
|
||||
},
|
||||
"durability": {
|
||||
"external_ack_journal_digest": HEX64,
|
||||
"ack_journal_fenced_before_count": true,
|
||||
"recovery_reconciled": true,
|
||||
"acknowledged_loss": 0,
|
||||
"torn_transactions": 0
|
||||
},
|
||||
"verification": {
|
||||
"setup_traffic_excluded": true,
|
||||
"commits_in_recovered_closure": false,
|
||||
"acknowledged_sequences_reconciled": true,
|
||||
"unique_blob_tree_commit_ids": true,
|
||||
"objects_new_equals_three_per_commit": true
|
||||
},
|
||||
"verdicts": {
|
||||
"storage_primitive": "not-applicable",
|
||||
"in_process_protocol": "not-applicable",
|
||||
"deployed_30k": "not-applicable",
|
||||
"deployed_60k": "not-applicable",
|
||||
"recovery": "not-applicable",
|
||||
"overload": "not-applicable",
|
||||
"compaction": "not-applicable",
|
||||
"federation": "not-applicable",
|
||||
"release": "not-applicable"
|
||||
},
|
||||
"promotable": false,
|
||||
"outcome": "preliminary",
|
||||
"storage": {
|
||||
"index_bytes_per_object": 47.0,
|
||||
"checkpoint_lookup_fanout": 1.0,
|
||||
"evidence_signing_micros_p50": 12.0,
|
||||
"fences": 1007,
|
||||
"transactions": 16104,
|
||||
"trim_settle_seconds": 0.0,
|
||||
"store_directory_attributes_verified": true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// The Wave A journal seam. The same bundle with every declaration reduced to
|
||||
/// what a path below `engine.rs` can observe, and the three claims gone.
|
||||
fn drive_path_bundle() -> serde_json::Value {
|
||||
let mut bundle = submit_path_bundle();
|
||||
bundle["run_id"] = serde_json::json!("skeleton-wave-a-0123456789abcdef");
|
||||
bundle["run_conditions"] = serde_json::json!({
|
||||
"initialization_path": "shard_drive_create",
|
||||
"mutation_path": "journal_drive",
|
||||
"checkpointing": "unimplemented",
|
||||
"index_maintenance": "no_index_in_path",
|
||||
"index_run_ceiling": "store_default",
|
||||
"receipt_reconciliation": "no_receipts_in_path",
|
||||
"objects_new_source": "derived_from_transaction_count",
|
||||
"commit_id_uniqueness": "not_checked",
|
||||
"build_profile": "debug",
|
||||
"environment_fidelity": "diagnostic"
|
||||
});
|
||||
bundle["resources"]["configured_ceilings"]["max_index_runs"] = serde_json::json!(64);
|
||||
bundle["storage"]["evidence_signing_micros_p50"] = serde_json::json!(0.0);
|
||||
bundle["verification"] = serde_json::json!({
|
||||
"setup_traffic_excluded": true,
|
||||
"commits_in_recovered_closure": false,
|
||||
"acknowledged_sequences_reconciled": true
|
||||
});
|
||||
bundle
|
||||
}
|
||||
|
||||
/// The negative control for every test below it.
|
||||
///
|
||||
/// Without it, a `schema_errors` that returns empty for all input — a validator
|
||||
/// that never ran, a schema that failed to load — reads as a green suite. The
|
||||
/// substring version of the emitter's own tests stayed green against a bundle
|
||||
/// with four validator errors for exactly this reason.
|
||||
#[test]
|
||||
fn both_reference_bundles_validate_and_the_validator_can_still_fail() {
|
||||
assert_valid(
|
||||
&submit_path_bundle(),
|
||||
"the submit-path reference bundle must validate; it is the shape the \
|
||||
emitter follow-up has to produce",
|
||||
);
|
||||
assert_valid(
|
||||
&drive_path_bundle(),
|
||||
"the journal-seam reference bundle must validate; the drive path stays \
|
||||
emittable after the amendment",
|
||||
);
|
||||
|
||||
let mut broken = submit_path_bundle();
|
||||
broken["storage"] = serde_json::Value::Null;
|
||||
assert_invalid(
|
||||
&broken,
|
||||
"the validator must reject something, or every assertion below is vacuous",
|
||||
);
|
||||
}
|
||||
|
||||
/// Amendment 1. The run conditions are required and enumerated, never prose.
|
||||
#[test]
|
||||
fn a_bundle_without_machine_readable_run_conditions_is_not_a_bundle() {
|
||||
let text = std::fs::read_to_string(repository_root().join("bench/result-schema.json")).unwrap();
|
||||
let schema: serde_json::Value = serde_json::from_str(&text).unwrap();
|
||||
|
||||
assert!(
|
||||
schema["required"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|v| v == "run_conditions"),
|
||||
"run_conditions must be required at every gate: a bundle whose caveats \
|
||||
live only in a human report reads as unconditional to everyone who \
|
||||
receives it"
|
||||
);
|
||||
assert_required_names(
|
||||
&schema,
|
||||
&["$defs", "run_conditions"],
|
||||
&[
|
||||
"initialization_path",
|
||||
"mutation_path",
|
||||
"checkpointing",
|
||||
"index_maintenance",
|
||||
"index_run_ceiling",
|
||||
"receipt_reconciliation",
|
||||
"objects_new_source",
|
||||
"commit_id_uniqueness",
|
||||
"build_profile",
|
||||
"environment_fidelity",
|
||||
],
|
||||
);
|
||||
|
||||
// Charter item 6: every value named, no catch-all, and no free-text member
|
||||
// a consumer would have to read rather than check.
|
||||
let properties = schema["$defs"]["run_conditions"]["properties"]
|
||||
.as_object()
|
||||
.expect("run_conditions must declare its properties");
|
||||
for (name, spec) in properties {
|
||||
assert!(
|
||||
spec.get("enum").is_some() || spec["type"] == "boolean",
|
||||
"run_conditions.{name} must be a closed enumeration or a boolean; a \
|
||||
free-text caveat is not a condition anything can check"
|
||||
);
|
||||
if let Some(values) = spec["enum"].as_array() {
|
||||
for value in values {
|
||||
let value = value.as_str().unwrap_or_default();
|
||||
assert!(
|
||||
!value.is_empty() && value != "other" && value != "unknown",
|
||||
"run_conditions.{name} must not carry a catch-all value"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Every field is enforced, not merely recorded: a bundle missing any one of
|
||||
// them is invalid.
|
||||
for field in properties.keys() {
|
||||
let mut bundle = submit_path_bundle();
|
||||
bundle["run_conditions"]
|
||||
.as_object_mut()
|
||||
.unwrap()
|
||||
.remove(field.as_str());
|
||||
assert_invalid(
|
||||
&bundle,
|
||||
&format!("a bundle omitting run_conditions.{field} must be rejected"),
|
||||
);
|
||||
}
|
||||
|
||||
let mut absent = submit_path_bundle();
|
||||
absent.as_object_mut().unwrap().remove("run_conditions");
|
||||
assert_invalid(
|
||||
&absent,
|
||||
"a bundle with no run_conditions block must be rejected",
|
||||
);
|
||||
}
|
||||
|
||||
/// Amendments 2 and 4, and the half of amendment 3 that is landable.
|
||||
///
|
||||
/// The submit path earns `unique_blob_tree_commit_ids` and
|
||||
/// `objects_new_equals_three_per_commit` and must state them. It does not earn
|
||||
/// `operation_receipts_reconciled` — and the schema says so mechanically rather
|
||||
/// than in a comment, because the emitter can only declare the reconciliation
|
||||
/// it performed and that declaration forbids the claim.
|
||||
#[test]
|
||||
fn the_submit_path_must_state_the_claims_it_now_earns() {
|
||||
for claim in [
|
||||
"unique_blob_tree_commit_ids",
|
||||
"objects_new_equals_three_per_commit",
|
||||
] {
|
||||
let mut bundle = submit_path_bundle();
|
||||
bundle["verification"]
|
||||
.as_object_mut()
|
||||
.unwrap()
|
||||
.remove(claim);
|
||||
assert_invalid(
|
||||
&bundle,
|
||||
&format!(
|
||||
"a submit-path bundle omitting {claim} must be rejected: the claim \
|
||||
is earnable through StoreEngine::submit, so silence about it is a \
|
||||
missing result and not an inapplicable one"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Amendment 2's condition. `objects_new` summed from the transaction count
|
||||
// makes the claim unfailable, so the declaration that says so forbids it —
|
||||
// at this gate and at every other.
|
||||
let mut tautology = submit_path_bundle();
|
||||
tautology["run_conditions"]["objects_new_source"] =
|
||||
serde_json::json!("derived_from_transaction_count");
|
||||
assert_invalid(
|
||||
&tautology,
|
||||
"objects_new_equals_three_per_commit may not be asserted over a count \
|
||||
derived from the transaction total: both sides would come from the same \
|
||||
number and the check could not fail",
|
||||
);
|
||||
|
||||
// Amendment 4's condition. Per-record uniqueness and distinct seed domains
|
||||
// are both named, and both refuse the claim.
|
||||
for weaker in ["inferred_from_seed_domains", "not_checked"] {
|
||||
let mut bundle = submit_path_bundle();
|
||||
bundle["run_conditions"]["commit_id_uniqueness"] = serde_json::json!(weaker);
|
||||
assert_invalid(
|
||||
&bundle,
|
||||
&format!(
|
||||
"unique_blob_tree_commit_ids may not be asserted with \
|
||||
commit_id_uniqueness={weaker}: uniqueness must be checked globally \
|
||||
across every recovered ACK record"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Amendment 3. Expressible, correctly constrained, and not earned today.
|
||||
let mut unearned = submit_path_bundle();
|
||||
unearned["verification"]["operation_receipts_reconciled"] = serde_json::json!(true);
|
||||
assert_invalid(
|
||||
&unearned,
|
||||
"operation_receipts_reconciled may not be asserted while the run declares \
|
||||
that it accepted any Committed status: store-bench.rs compares no receipt \
|
||||
and journals a digest of the operation id, not of the receipt",
|
||||
);
|
||||
|
||||
let mut earned = submit_path_bundle();
|
||||
earned["run_conditions"]["receipt_reconciliation"] =
|
||||
serde_json::json!("exact_receipts_reconciled");
|
||||
assert_invalid(
|
||||
&earned,
|
||||
"a run that declares exact receipt reconciliation must assert the claim \
|
||||
rather than leave it optional",
|
||||
);
|
||||
earned["verification"]["operation_receipts_reconciled"] = serde_json::json!(true);
|
||||
assert_valid(
|
||||
&earned,
|
||||
"the claim must be expressible once the reconciliation is real, so landing \
|
||||
it is an emitter change and not a second schema amendment",
|
||||
);
|
||||
|
||||
// The two that stay unavailable to this workload at either path.
|
||||
for claim in [
|
||||
"blobs_recomputed",
|
||||
"metadata_complete",
|
||||
"commits_in_recovered_closure",
|
||||
] {
|
||||
let mut bundle = submit_path_bundle();
|
||||
bundle["verification"][claim] = serde_json::json!(true);
|
||||
assert_invalid(
|
||||
&bundle,
|
||||
&format!("{claim} must stay unavailable at storage_primitive"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The branch-conditional half. A schema that merely *permitted* the three
|
||||
/// claims on both paths would hand the journal seam a way to assert what it
|
||||
/// cannot observe, which is a worse defect than the one being fixed.
|
||||
#[test]
|
||||
fn the_drive_path_may_not_assert_the_claims_the_submit_path_earns() {
|
||||
for claim in [
|
||||
"unique_blob_tree_commit_ids",
|
||||
"objects_new_equals_three_per_commit",
|
||||
"operation_receipts_reconciled",
|
||||
] {
|
||||
let mut bundle = drive_path_bundle();
|
||||
bundle["verification"][claim] = serde_json::json!(true);
|
||||
assert_invalid(
|
||||
&bundle,
|
||||
&format!(
|
||||
"a journal-drive bundle asserting {claim} must be rejected: there \
|
||||
are no objects, no receipts, and no index below engine.rs"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// And it may not reach the claims by lying about provenance either: the
|
||||
// seam's declarations are pinned to the only values it can make.
|
||||
for (field, value) in [
|
||||
("objects_new_source", "summed_from_receipts"),
|
||||
(
|
||||
"commit_id_uniqueness",
|
||||
"checked_globally_across_ack_records",
|
||||
),
|
||||
("receipt_reconciliation", "exact_receipts_reconciled"),
|
||||
("index_maintenance", "runs_sealed"),
|
||||
] {
|
||||
let mut bundle = drive_path_bundle();
|
||||
bundle["run_conditions"][field] = serde_json::json!(value);
|
||||
assert_invalid(
|
||||
&bundle,
|
||||
&format!(
|
||||
"a journal-drive bundle declaring {field}={value} must be rejected: \
|
||||
forbidding the claim while permitting the declaration that earns it \
|
||||
leaves the same hole one field over"
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// `max_index_runs` must be the value the run configured. Absent is invalid,
|
||||
/// and a declaration that contradicts the recorded value is invalid in both
|
||||
/// directions — which is as close to "not a default" as a schema can get
|
||||
/// without reading the process's options.
|
||||
#[test]
|
||||
fn the_configured_index_run_ceiling_must_be_recorded_and_consistent() {
|
||||
let mut absent = submit_path_bundle();
|
||||
absent["resources"]["configured_ceilings"]
|
||||
.as_object_mut()
|
||||
.unwrap()
|
||||
.remove("max_index_runs");
|
||||
assert_invalid(
|
||||
&absent,
|
||||
"a bundle that does not record max_index_runs must be rejected: the ceiling \
|
||||
is the limit this workload actually reaches",
|
||||
);
|
||||
|
||||
// Declared raised, recorded as the default.
|
||||
let mut defaulted = submit_path_bundle();
|
||||
defaulted["resources"]["configured_ceilings"]["max_index_runs"] = serde_json::json!(64);
|
||||
assert_invalid(
|
||||
&defaulted,
|
||||
"a run that raised the ceiling may not record the store default",
|
||||
);
|
||||
|
||||
// Declared default, recorded as the raise the emitter actually configures.
|
||||
let mut mislabelled = drive_path_bundle();
|
||||
mislabelled["resources"]["configured_ceilings"]["max_index_runs"] =
|
||||
serde_json::json!(1_000_000);
|
||||
assert_invalid(
|
||||
&mislabelled,
|
||||
"a run that declares the store default may not record a raised ceiling",
|
||||
);
|
||||
|
||||
// The store default the schema bounds `store_default` at must still be the
|
||||
// library's default, or the two have drifted and the bound means nothing.
|
||||
let options =
|
||||
std::fs::read_to_string(repository_root().join("crates/levcs-store/src/options.rs"))
|
||||
.unwrap();
|
||||
assert!(
|
||||
options.contains("max_index_runs: 64,"),
|
||||
"bench/result-schema.json bounds a declared store_default at 64; if \
|
||||
StoreOptions::default changes, that bound must change with it"
|
||||
);
|
||||
}
|
||||
|
||||
/// The truthful-environment ruling. B4's debug/tmpfs diagnostic run was
|
||||
/// unrepresentable — `persistent_data_mount` and `tmpfs` were unconditional
|
||||
/// consts — so its number lived on a console and in prose. It is representable
|
||||
/// now, and mechanically disqualified: recording a diagnostic run is worth
|
||||
/// nothing unless the record also refuses to let it be read as a result.
|
||||
#[test]
|
||||
fn a_diagnostic_environment_is_representable_but_can_never_pass() {
|
||||
let mut diagnostic = submit_path_bundle();
|
||||
diagnostic["deployment"]["persistent_data_mount"] = serde_json::json!(false);
|
||||
diagnostic["deployment"]["tmpfs"] = serde_json::json!(true);
|
||||
assert_valid(
|
||||
&diagnostic,
|
||||
"a tmpfs debug diagnostic run must be recordable as itself rather than \
|
||||
being unrepresentable and therefore console-only",
|
||||
);
|
||||
|
||||
// Disqualified, not merely labelled.
|
||||
let mut passing = diagnostic.clone();
|
||||
passing["outcome"] = serde_json::json!("pass");
|
||||
assert_invalid(&passing, "a diagnostic run may never be a pass at any gate");
|
||||
|
||||
let mut verdict = diagnostic.clone();
|
||||
verdict["verdicts"]["storage_primitive"] = serde_json::json!("pass");
|
||||
assert_invalid(
|
||||
&verdict,
|
||||
"a diagnostic run may not pronounce a passing verdict on any gate",
|
||||
);
|
||||
|
||||
// And the reference environment is unchanged for anything claiming it.
|
||||
for (field, value) in [
|
||||
("persistent_data_mount", serde_json::json!(false)),
|
||||
("tmpfs", serde_json::json!(true)),
|
||||
] {
|
||||
let mut reference = submit_path_bundle();
|
||||
reference["run_conditions"]["environment_fidelity"] =
|
||||
serde_json::json!("reference_profile");
|
||||
reference["run_conditions"]["build_profile"] = serde_json::json!("release");
|
||||
reference["hardware"]["profile"] = serde_json::json!("minimum-30k");
|
||||
reference["deployment"][field] = value.clone();
|
||||
assert_invalid(
|
||||
&reference,
|
||||
&format!(
|
||||
"reference_profile fidelity must re-pin deployment.{field}: relaxing \
|
||||
the unconditional const without re-pinning it here would let a \
|
||||
promotable bundle be measured on tmpfs"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
let mut debug_reference = submit_path_bundle();
|
||||
debug_reference["run_conditions"]["environment_fidelity"] =
|
||||
serde_json::json!("reference_profile");
|
||||
assert_invalid(
|
||||
&debug_reference,
|
||||
"reference_profile fidelity requires a release build and a named hardware \
|
||||
profile; a debug diagnostic-profile run may not claim it",
|
||||
);
|
||||
}
|
||||
|
||||
/// Scope §7's two prose clauses, made mechanical: the P2 runs must not have
|
||||
/// been achieved with checkpointing disabled, and a run holding every index
|
||||
/// delta in memory for its whole duration is not the steady state a P2 number
|
||||
/// describes. Neither could be checked from a bundle before this review.
|
||||
#[test]
|
||||
fn a_passing_storage_primitive_run_must_declare_a_production_steady_state() {
|
||||
// The honest values today make a pass impossible, which is the point.
|
||||
let mut passing = submit_path_bundle();
|
||||
passing["outcome"] = serde_json::json!("pass");
|
||||
passing["verdicts"]["storage_primitive"] = serde_json::json!("pass");
|
||||
passing["run_conditions"]["environment_fidelity"] = serde_json::json!("reference_profile");
|
||||
passing["run_conditions"]["build_profile"] = serde_json::json!("release");
|
||||
passing["hardware"]["profile"] = serde_json::json!("minimum-30k");
|
||||
assert_invalid(
|
||||
&passing,
|
||||
"today's harness may not emit a passing P2 bundle: checkpointing is \
|
||||
unimplemented and the index holds every delta in memory",
|
||||
);
|
||||
|
||||
passing["run_conditions"]["checkpointing"] = serde_json::json!("exercised");
|
||||
passing["run_conditions"]["index_maintenance"] = serde_json::json!("runs_sealed");
|
||||
passing["run_conditions"]["index_run_ceiling"] = serde_json::json!("store_default");
|
||||
passing["resources"]["configured_ceilings"]["max_index_runs"] = serde_json::json!(64);
|
||||
assert_invalid(
|
||||
&passing,
|
||||
"a P2 pass must have been measured against a root the production entry \
|
||||
point created; ROOT_SEEDED_BY_NON_PRODUCTION_PATH is disclosable but not \
|
||||
promotable",
|
||||
);
|
||||
|
||||
passing["run_conditions"]["initialization_path"] = serde_json::json!("store_engine_open");
|
||||
assert_valid(
|
||||
&passing,
|
||||
"a run that met every condition must still be able to pass, or the rule is \
|
||||
a prohibition rather than a gate",
|
||||
);
|
||||
|
||||
// The journal seam can never reach a P2 pass, whatever it declares.
|
||||
let mut seam = drive_path_bundle();
|
||||
seam["outcome"] = serde_json::json!("pass");
|
||||
seam["run_conditions"]["environment_fidelity"] = serde_json::json!("reference_profile");
|
||||
seam["run_conditions"]["build_profile"] = serde_json::json!("release");
|
||||
seam["hardware"]["profile"] = serde_json::json!("minimum-30k");
|
||||
seam["run_conditions"]["checkpointing"] = serde_json::json!("exercised");
|
||||
assert_invalid(
|
||||
&seam,
|
||||
"a journal-drive measurement may never be a passing storage_primitive run",
|
||||
);
|
||||
}
|
||||
|
||||
/// The half of every per-gate split that is easy to lose: relaxing something
|
||||
/// for one branch must never un-pin it for the others. It has been lost once
|
||||
/// already, by the edit that introduced the assertion saying so.
|
||||
#[test]
|
||||
fn the_instance_gates_are_not_loosened_by_the_storage_path_split() {
|
||||
let text = std::fs::read_to_string(repository_root().join("bench/result-schema.json")).unwrap();
|
||||
let schema: serde_json::Value = serde_json::from_str(&text).unwrap();
|
||||
let rule = schema["allOf"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.find(|r| {
|
||||
r["if"]["properties"]["gate"]["const"] == "storage_primitive" && r.get("else").is_some()
|
||||
})
|
||||
.expect("missing the per-gate rule");
|
||||
let conditions = &rule["else"]["properties"]["run_conditions"]["properties"];
|
||||
assert_eq!(
|
||||
conditions["mutation_path"]["const"].as_str(),
|
||||
Some("store_engine_submit"),
|
||||
"no instance gate may be measured on the journal seam"
|
||||
);
|
||||
assert_eq!(
|
||||
conditions["initialization_path"]["const"].as_str(),
|
||||
Some("store_engine_open"),
|
||||
"no instance gate may be measured against a root seeded outside production"
|
||||
);
|
||||
assert_eq!(
|
||||
conditions["index_maintenance"]["const"].as_str(),
|
||||
Some("runs_sealed")
|
||||
);
|
||||
assert_eq!(
|
||||
conditions["checkpointing"]["enum"],
|
||||
serde_json::json!(["exercised", "enabled_not_reached"]),
|
||||
"an instance gate may not declare checkpointing unimplemented or disabled"
|
||||
);
|
||||
|
||||
// And the five graph claims are still required and true at every instance
|
||||
// gate, which the storage-path split must not have touched.
|
||||
for claim in [
|
||||
"unique_blob_tree_commit_ids",
|
||||
"objects_new_equals_three_per_commit",
|
||||
"blobs_recomputed",
|
||||
"operation_receipts_reconciled",
|
||||
"metadata_complete",
|
||||
"commits_in_recovered_closure",
|
||||
] {
|
||||
assert_eq!(
|
||||
rule["else"]["properties"]["verification"]["properties"][claim]["const"].as_bool(),
|
||||
Some(true),
|
||||
"{claim} must stay pinned true at every non-storage gate"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1217,6 +1217,183 @@ shard tree outside the root. `read_format` follows a link at `FORMAT`, read-only
|
|||
priority. The first is a correctness defect in the locking discipline and should be scheduled on
|
||||
its own, not folded into a later pass.
|
||||
|
||||
##### Contract review 2026-07-28-C
|
||||
|
||||
B4 re-pointed `store-bench` at a real `StoreEngine::submit` and found that four verification
|
||||
claims `bench/result-schema.json` declares not-applicable at `storage_primitive` have become
|
||||
genuinely earnable. It **requested rather than emitted** them, which is what §6.6 item 4 asks
|
||||
for. All four are granted, three with conditions that are landed as schema constraints rather
|
||||
than as prose, and one — `operation_receipts_reconciled` — is granted **in principle and is
|
||||
not earned by the emitter as it stands.** The schema and its contract tests land here; the
|
||||
emitter is B4's follow-up and is specified in scope §6.6.
|
||||
|
||||
**1. Machine-readable run conditions, ranked first because the other three depend on it.**
|
||||
There was nowhere in a bundle to record that the root was seeded outside `StoreEngine::open`,
|
||||
that `max_index_runs` was raised, or that no checkpoint was taken. Every one of those is
|
||||
true of the run that produces today's numbers, and every one of them lived only in a harness
|
||||
comment and a human report. A bundle whose caveats live outside it reads as unconditional to
|
||||
everyone who receives it, and the people most likely to receive it without the report are the
|
||||
ones furthest from the harness.
|
||||
|
||||
`run_conditions` is a new required top-level block with ten members: `initialization_path`,
|
||||
`mutation_path`, `checkpointing`, `index_maintenance`, `index_run_ceiling`,
|
||||
`receipt_reconciliation`, `objects_new_source`, `commit_id_uniqueness`, `build_profile`, and
|
||||
`environment_fidelity`. Every member is a closed enumeration; there is no free-text member and
|
||||
no catch-all value, and a contract test asserts both properties over the block rather than
|
||||
over a list this file also wrote.
|
||||
|
||||
**A prose caveat field was rejected outright, and the reason is the whole design.** A string
|
||||
is something a consumer reads; these are things a consumer checks. The block is not a place to
|
||||
put disclosures beside the claims — it is what the claims are *conditioned on*.
|
||||
`objects_new_equals_three_per_commit` is forbidden when `objects_new_source` says the count was
|
||||
derived from the transaction total. `unique_blob_tree_commit_ids` is forbidden when
|
||||
`commit_id_uniqueness` says the check was per-record or inferred. `operation_receipts_reconciled`
|
||||
is forbidden when `receipt_reconciliation` says any `Committed` status was accepted, and
|
||||
*required* when it says otherwise. A harness can only declare what it did, and the declaration
|
||||
decides what it may claim. That is the difference between a caveat and a condition.
|
||||
|
||||
Two of scope §7's exit clauses were prose until now and are mechanical here: a passing
|
||||
`storage_primitive` run must declare `checkpointing: "exercised"` — §7 requires the P2 runs not
|
||||
to have been achieved with checkpointing disabled — and `index_maintenance: "runs_sealed"`,
|
||||
because a run holding every index delta in memory with a lookup fan-out that grows for its
|
||||
whole duration is not the steady state a P2 number describes. It must also declare
|
||||
`initialization_path: "store_engine_open"` and `mutation_path: "store_engine_submit"`. The
|
||||
harness satisfies **two of the four** — B1's startup state 1 landed, so the submit path both
|
||||
creates its root and mutates it through the production entry points. It cannot satisfy
|
||||
`checkpointing` or `index_maintenance`, so it still cannot emit a passing P2 bundle, which is
|
||||
correct and was previously only an assertion in a comment.
|
||||
|
||||
That the count moved from zero to two is worth stating rather than silently editing: the four
|
||||
conditions are not decoration on a number, they are the number's preconditions, and knowing
|
||||
which remain unmet says exactly how far the P2 criterion is from being earned. The two that
|
||||
remain are the two that make a P2 figure a steady-state measurement rather than a burst.
|
||||
|
||||
**2. `objects_new_equals_three_per_commit`, granted for the production submit path.** The
|
||||
schema said it was absent at `storage_primitive` "which creates no objects". That stopped being
|
||||
true when the measured path became `submit`: the path stages the canonical three objects per
|
||||
commit and the harness sums `receipt.objects_new` from the store's own receipts. The condition
|
||||
is that the claim compares an **independently summed receipt total against a separately counted
|
||||
`3 × counted_commits`**. Both sides deriving from the transaction count is what the claim was
|
||||
originally excluded for — an assertion that cannot fail is not a check — and
|
||||
`objects_new_source` is what makes that exclusion survive the grant, at this gate and at every
|
||||
other.
|
||||
|
||||
**3. `operation_receipts_reconciled`, granted in principle and not earned.**
|
||||
`store-bench.rs:2033` accepts any `TransactionStatus::Committed(_)` without comparing its
|
||||
payload, and the `receipt_digest` the harness journals is `blake3(operation_id)` — a digest of
|
||||
the operation, not of the receipt. So the run reads back that *something* committed, which is
|
||||
already what `acknowledged_sequences_reconciled` reports, and calling it receipt reconciliation
|
||||
would be a second name for the same evidence. The claim is landed as expressible and correctly
|
||||
constrained: an emitter that reconciles exact receipts, or a frozen canonical receipt digest,
|
||||
declares it and **must** then assert the claim; an emitter that does not declares
|
||||
`acceptance_of_any_committed_status` and **cannot**. Landing it now means closing it is an
|
||||
emitter change rather than a second schema amendment, and the schema description says in as
|
||||
many words that the current emitter does not earn it.
|
||||
|
||||
**4. `unique_blob_tree_commit_ids`, granted for the production submit path**, on condition that
|
||||
uniqueness is established **globally across every recovered acknowledgment record**. Per-record
|
||||
uniqueness is not uniqueness — two records may each be internally distinct and still share a
|
||||
commit id — and distinct generator seed domains make a collision unlikely rather than absent,
|
||||
which is an argument about probability rather than an observation. `inferred_from_seed_domains`
|
||||
is therefore a *named* value of `commit_id_uniqueness` rather than something folded into the
|
||||
passing one: a harness that reasoned that way has a truthful thing to record and is refused the
|
||||
claim, which is a better outcome than having to choose between a lie and silence.
|
||||
|
||||
**The branch conditional, which is the part that is easy to get wrong.** These are not global
|
||||
loosenings. A schema that merely *permitted* the three claims on both paths would hand the
|
||||
Wave A journal seam a way to assert what nothing below `engine.rs` can observe — and that is a
|
||||
worse defect than the one being fixed, because it arrives disguised as the fix. Two rules key
|
||||
on `gate == "storage_primitive"` and `run_conditions.mutation_path`:
|
||||
|
||||
- **`journal_drive`** forbids all three claims outright *and* pins the four provenance
|
||||
declarations to the only values the seam can truthfully make (`no_index_in_path`,
|
||||
`no_receipts_in_path`, `derived_from_transaction_count`, `not_checked`). Forbidding the
|
||||
claims alone would have left the same hole one field over: a drive-path bundle could declare
|
||||
exact receipt reconciliation it has no receipts to perform, and nothing would have noticed.
|
||||
- **`store_engine_submit`** requires `unique_blob_tree_commit_ids` and
|
||||
`objects_new_equals_three_per_commit`, both `const true`. Omission is a missing result here,
|
||||
not an inapplicable one.
|
||||
|
||||
`blobs_recomputed`, `metadata_complete`, and `commits_in_recovered_closure` stay unavailable on
|
||||
**both** paths and stay in the gate-wide rule, because they need the graph traversal plan §5.1
|
||||
forbids the store from performing. The gate-wide forbidden set is now exactly the claims no
|
||||
path can earn, and a contract test asserts its size so a future claim cannot be quietly parked
|
||||
there.
|
||||
|
||||
**`max_index_runs` is now a named required member of `resources.configured_ceilings`.** It was
|
||||
reachable only through that block's free-form `additionalProperties`, so an emitter could omit
|
||||
the one ceiling this workload actually reaches — `submit` refuses `NotImplemented` at it — and
|
||||
the bundle stayed valid. It must be the value the run configured, read back from the options the
|
||||
store opened with. The schema cannot see the process's options, so the bite is a cross-check:
|
||||
`index_run_ceiling: "store_default"` bounds the recorded value at 64 and
|
||||
`"raised_because_index_sealing_unimplemented"` floors it at 65, and a bundle that declares one
|
||||
while recording the other is invalid in both directions. A contract test asserts that
|
||||
`StoreOptions::default`'s 64 is still 64, so the schema's bound and the library cannot drift in
|
||||
silence. What remains open is a bundle that lies about both consistently, which no schema
|
||||
closes, and it is stated here rather than left to be discovered.
|
||||
|
||||
**The truthful-environment ruling: yes, and here is why.** `deployment.persistent_data_mount`
|
||||
and `deployment.tmpfs` were unconditional `const true` / `const false`, so B4's debug/tmpfs
|
||||
diagnostic run at 8,052/s **could not be encoded at all**. It was not disqualified — it was
|
||||
unrepresentable, which is a strictly worse state: the number existed, it was informative, and
|
||||
the only places it could live were a console and a paragraph. That is the same failure the
|
||||
`outcome` field was added to fix in review 2026-07-24-B, one block over, and the same argument
|
||||
applies. A schema that can only express successful runs is not a record of what was measured.
|
||||
|
||||
The two fields relax to `type: boolean` and are **re-pinned** by
|
||||
`environment_fidelity: "reference_profile"`, which additionally requires a `release` build and
|
||||
a named hardware profile. `outcome: "pass"` requires `reference_profile` **at every gate**, so
|
||||
nothing a claim used to cost has changed — a `gate="storage_primitive"` bundle claiming P2
|
||||
still requires the real environment, by a rule that is one implication instead of two consts.
|
||||
Going the other way, `"diagnostic"` is not merely a label: outcome is bounded to `fail` or
|
||||
`preliminary` and no verdict may be `pass`. Recording a diagnostic run is worth nothing unless
|
||||
the record also refuses to let it be read as a result.
|
||||
|
||||
What was **not** relaxed, deliberately: `overlay`, `remote_storage`, and `durability_enabled`
|
||||
keep their unconditional consts. A run with durability disabled is not a slower measurement of
|
||||
the same thing, it is a measurement of something else, and there is no diagnostic value in a
|
||||
fence-free number that would justify making it expressible.
|
||||
|
||||
**Expected collateral: the emitter no longer produces a valid bundle, and the gate is red until
|
||||
B4's follow-up.** Exactly two fields are missing, on both paths:
|
||||
|
||||
```
|
||||
[]: 'run_conditions' is a required property
|
||||
['resources', 'configured_ceilings']: 'max_index_runs' is a required property
|
||||
```
|
||||
|
||||
`scripts/check-phase1.sh` does not run `scripts/verify-store-recovery.sh`, so the expectation
|
||||
was that the gate would stay green while bundle emission broke. **It does not, and the reason
|
||||
is worth recording:** the gate runs `store-bench`'s own unit tests, and since review
|
||||
2026-07-24-B three of them validate the emitted bundle against `bench/result-schema.json`
|
||||
rather than against a list of substrings. So the emitter's schema conformance is inside the
|
||||
gate, which is exactly the property that review was after — the drift is reported by the gate
|
||||
instead of by a script nobody ran. `the_emitted_bundle_validates_against_the_frozen_schema` and
|
||||
`a_failing_run_is_representable_rather_than_suppressed` fail with the two errors above;
|
||||
`the_schema_check_can_actually_fail` fails on its final assertion for the same reason and not a
|
||||
second one, because it asserts that a coordinated-omission mutation leaves a *clean* bundle and
|
||||
the base bundle is no longer clean. `scripts/verify-store-recovery.sh --cycles 2` was run
|
||||
directly rather than assumed and reports `matrix=pass`, `cycles_completed=2`,
|
||||
`acknowledged_loss=0`, `torn_transactions=0`, `repeated_adoptions=0`, `bundle=schema-invalid`,
|
||||
`VERIFY_EXIT=1`.
|
||||
|
||||
All three failures are in `store-bench.rs`, which is B4's file, and the fix is scope §6.6 item
|
||||
5 rather than an edit here. This is the sequencing of 2026-07-28-A repeated deliberately: the
|
||||
gate is transiently red between the contract and the package's pass, and landing the contract
|
||||
first is what keeps B4 from implementing against a surface that is about to move. It is
|
||||
recorded rather than worked around, because a lead who edits the emitter to keep the gate green
|
||||
has moved a package's work into a review and left no one able to see that it happened.
|
||||
|
||||
One measurement from that run belongs on the record, because it is what makes amendment 2 more
|
||||
than an argument: the submit path reported `objects_new=861` against `transactions=287`, summed
|
||||
from 287 independent receipts. Three per commit, counted rather than multiplied.
|
||||
|
||||
Amended: `bench/result-schema.json`, `crates/levcs-protocol/tests/phase0_benchmark_contracts.rs`,
|
||||
and scope §6.6 and §7. `bench/reference-hardware.toml` required no change: the frozen profiles
|
||||
describe the reference environment, and `environment_fidelity` records which runs met it —
|
||||
putting a diagnostic profile in the frozen file would have made a non-comparable configuration
|
||||
part of what "frozen" means.
|
||||
|
||||
### Phase 1 — storage engine spine
|
||||
|
||||
Lead first defines sealed transaction/frame/snapshot interfaces and file ownership. That deliverable (D0) landed on 2026-07-24 as `crates/levcs-store`: the frozen public API compiling against `StoreError::NotImplemented`, the file-ownership split, strict configuration validation, the single durability syscall funnel with its counters and fault hooks, the failpoint registry in enforced one-to-one correspondence with `oracle::AppendFailpoint`, and the journal-level drive seam that lets the crash harness run in Wave A. The enforced gate is `scripts/check-phase1.sh`, which runs `check-phase0.sh` first so the Phase 0 freeze stays enforced. That work is scoped in `doc/phase1-storage-spine-scope.md`, which realizes this section as a file-ownership matrix, a frozen `levcs-store` API, a physical format and durability/recovery specification, per-package deliverables and acceptance criteria, the Wave A adversarial review charter, and the capacity analysis for P2 on the frozen reference hardware. This plan remains authoritative; that document is the Phase 1 realization of it and lists the decisions that must be resolved before Wave A starts.
|
||||
|
|
|
|||
|
|
@ -1190,6 +1190,36 @@ enforced somewhere and not on the path that runs. Here, an invariant was documen
|
|||
than required. In both cases the gate reported green because nothing made the omission
|
||||
expressible as a failure.
|
||||
|
||||
### 5.1 Resource exhaustion is indistinguishable from a concurrency flake by symptom
|
||||
|
||||
Recorded from a Wave B incident, because the wrong diagnosis was already written down before
|
||||
the evidence arrived and only measurement caught it.
|
||||
|
||||
Verifying a commit in a second worktree put an 11 GiB `target` directory on this machine's
|
||||
`/tmp`, which is tmpfs. The store's tests build roots under `TMPDIR`, and the engine
|
||||
preallocates per shard, so the filesystem filled. Seventeen `engine::tests` failures appeared
|
||||
at once. **Every one passed in isolation and failed under the full suite** — the exact
|
||||
signature §5's `recovery_eio` record describes, and the reason is structural rather than
|
||||
coincidental: whichever tests run last are the ones that find the filesystem full, and which
|
||||
tests run last depends on scheduling. Re-running the main tree reproduced it 5 of 5, which
|
||||
looked like confirmation of an intrinsic flake in newly added startup tests. It was not. The
|
||||
panic carried `Io(Os { code: 122, kind: QuotaExceeded })`, and after the worktree was removed
|
||||
the same suite passed 5 of 5 unchanged.
|
||||
|
||||
**The rule this yields.** Before classifying clustered failures as a concurrency flake,
|
||||
preserve and read the **errno**, and capture free blocks, free inodes, and any quota state for
|
||||
the filesystem the test roots live on. `ENOSPC`, `EDQUOT`, and `EMFILE` all present as
|
||||
unrelated-looking failures that vanish in isolation, and all three are cheap to rule out and
|
||||
expensive to misdiagnose: the flake conclusion sends someone hunting a race that does not
|
||||
exist, and — worse — it invites the rerun-until-green habit §5 exists to forbid, which would
|
||||
have "resolved" this incident while leaving the disk full.
|
||||
|
||||
The corollary for harnesses: an I/O error must reach a report with its errno intact. A path
|
||||
that folds one into a boolean, a count, or a generic message destroys the only evidence that
|
||||
distinguishes these two diagnoses. That is the same requirement as the emitter's
|
||||
incomplete-accounting refusal in §6.6 — a failure the harness cannot account for must be
|
||||
reported as itself, not compressed into a symptom.
|
||||
|
||||
## 6. Wave B work packages
|
||||
|
||||
### 6.0 Preconditions
|
||||
|
|
@ -1767,6 +1797,98 @@ Owns the crash driver, the benchmark, the matrix, and the recovery script.
|
|||
`commits_in_recovered_closure` and the object-graph flags forbidden at this gate should be
|
||||
re-examined. If any becomes genuinely earnable, that is a schema amendment and a contract
|
||||
review — **request it, do not emit it.** `bench/result-schema.json` is lead-owned.
|
||||
*Requested, reviewed, and granted as contract review 2026-07-28-C; the schema and its
|
||||
contract tests have landed and item 5 below is what B4 must emit against them.*
|
||||
|
||||
#### Consequence of contract review 2026-07-28-C: the emitter contract
|
||||
|
||||
`bench/result-schema.json` now requires a `run_conditions` block and a named
|
||||
`resources.configured_ceilings.max_index_runs`, and requires two verification claims on the
|
||||
submit path. The emitter does not produce any of them, so `store-bench emit-skeleton` currently
|
||||
writes a bundle that fails validation on exactly two fields:
|
||||
|
||||
```
|
||||
[]: 'run_conditions' is a required property
|
||||
['resources', 'configured_ceilings']: 'max_index_runs' is a required property
|
||||
```
|
||||
|
||||
`scripts/verify-store-recovery.sh --cycles 2` reports `bundle=schema-invalid`, `VERIFY_EXIT=1`
|
||||
with everything else green (`matrix=pass`, `acknowledged_loss=0`, `torn_transactions=0`).
|
||||
**`scripts/check-phase1.sh` is red as well**, which is not what landing a schema alone would
|
||||
normally do: the gate runs `store-bench`'s unit tests, and three of them validate the emitted
|
||||
bundle against the schema rather than against substrings, so schema conformance is inside the
|
||||
gate. That is the property review 2026-07-24-B was after, working. All three failures are in
|
||||
`store-bench.rs` and none is a defect in the store; they are expected collateral of landing the
|
||||
contract first and they close with item 5.
|
||||
|
||||
5. **Emit the run conditions, the index-run ceiling, and the two earned claims.** All of it in
|
||||
`store-bench.rs`; no other file is involved. Nothing here may be a constant this file
|
||||
restates — every value must come from what the run configured or observed.
|
||||
|
||||
**a. `resources.configured_ceilings.max_index_runs`** — the `u32` from the `StoreOptions`
|
||||
the store was opened with, not `ENGINE_MAX_INDEX_RUNS` written out a second time. Emit it as
|
||||
an integer.
|
||||
|
||||
**b. A `run_conditions` object** with all ten members. The truthful values today are:
|
||||
|
||||
| member | submit path | drive path |
|
||||
|---|---|---|
|
||||
| `initialization_path` | `store_engine_open` (see **f**) | `shard_drive_create` |
|
||||
| `mutation_path` | `store_engine_submit` | `journal_drive` |
|
||||
| `checkpointing` | `unimplemented` | `unimplemented` |
|
||||
| `index_maintenance` | `deltas_retained_in_memory` | `no_index_in_path` |
|
||||
| `index_run_ceiling` | `raised_because_index_sealing_unimplemented` | `store_default` |
|
||||
| `receipt_reconciliation` | `acceptance_of_any_committed_status` | `no_receipts_in_path` |
|
||||
| `objects_new_source` | `summed_from_receipts` | `derived_from_transaction_count` |
|
||||
| `commit_id_uniqueness` | `checked_globally_across_ack_records` (after **d**) | `not_checked` |
|
||||
| `build_profile` | from `cfg!(debug_assertions)` | same |
|
||||
| `environment_fidelity` | `diagnostic` unless every reference condition holds | same |
|
||||
|
||||
These are **declarations of what the run did**, not configuration. Each must be derived from
|
||||
the `MeasuredRun` and the options rather than hardcoded per path where a derivation exists:
|
||||
`index_run_ceiling` follows from comparing the configured ceiling to the store default,
|
||||
`objects_new_source` is the existing `MeasuredRun::objects_new_counted`, `build_profile`
|
||||
follows from `cfg!`, and `environment_fidelity` follows from the profile the run verified.
|
||||
A hardcoded `run_conditions` block is the prose caveat with a different syntax.
|
||||
|
||||
**c. Both earned claims on the submit path**, and neither on the drive path.
|
||||
`objects_new_equals_three_per_commit` may be emitted only when the summed
|
||||
`receipt.objects_new` total equals a **separately counted** `3 × counted_commits` — count the
|
||||
commits, do not reuse the summed total to produce the expected value, and refuse to emit the
|
||||
bundle when they disagree rather than emitting the flag as `false`, which the schema does not
|
||||
permit and which would be a different untrue statement.
|
||||
|
||||
**d. A global uniqueness check** over every recovered ACK record, across all records at once:
|
||||
collect every `blob_ids`, `tree_ids`, and `commit_ids` entry from
|
||||
`ExternalAckJournal::recover` into one set per kind and require no repeat. Per-record checking
|
||||
and any argument from the distinctness of the generator seed domains are both explicitly
|
||||
insufficient, and `commit_id_uniqueness` has named values for both so a harness that did
|
||||
either has something truthful to record.
|
||||
|
||||
**e. Do not emit `operation_receipts_reconciled`.** The schema forbids it while
|
||||
`receipt_reconciliation` is `acceptance_of_any_committed_status`, which is the honest
|
||||
declaration for `store-bench.rs:2033` — it accepts any `Committed(_)` without comparing the
|
||||
payload, and the `AckRecord.receipt_digest` it writes is `blake3(operation_id)` rather than a
|
||||
digest of the receipt. Earning it is separate work: reconcile the exact receipt, or freeze a
|
||||
canonical receipt digest and reconcile that, then declare the matching value and assert the
|
||||
claim. The schema will then *require* the claim rather than permit it.
|
||||
|
||||
**f. Build every measured root through `StoreEngine::open`.** Added after B1 landed startup
|
||||
state 1. The benchmark previously seeded its root with `segment::initialize_root` and
|
||||
disclosed the fact in three places, because seeding a store off the production path in order
|
||||
to measure the production path is the charter item 8 smell and a disclosure is not a fix.
|
||||
With state 1 implemented the smell is closable rather than merely recordable, so it is
|
||||
closed: the seeding helpers and the `ROOT_SEEDED_BY_NON_PRODUCTION_PATH` constant are retired,
|
||||
and `initialization_path` is **observed** — the `FORMAT` marker is absent before the call and
|
||||
present after — rather than asserted. Deriving it from an observation is what keeps the
|
||||
declaration honest if the seeding ever regresses.
|
||||
|
||||
*Accept:* `bash scripts/verify-store-recovery.sh --cycles 2` reports `bundle=schema-valid`
|
||||
on both `--path submit` and `--path drive`; the emitter's own
|
||||
`the_emitted_bundle_validates_against_the_frozen_schema` passes; and
|
||||
`the_schema_check_can_actually_fail` gains a mutation for each newly required field, since a
|
||||
required field the negative control never removes is a field the suite cannot notice the loss
|
||||
of.
|
||||
|
||||
#### Carry-forward: the SIGKILL cycles still drive the journal seam
|
||||
|
||||
|
|
@ -1781,11 +1903,17 @@ one step of a publication and not the step where the status root, the sequencer,
|
|||
acknowledgment, and the checkpoint install are at risk. Every ordering hazard that only
|
||||
exists between those is untested by this script, at any cycle count.
|
||||
|
||||
Moving the cycles onto production submit is **blocked on `StoreEngine::open` startup state
|
||||
1**: the child process cannot create a store root through the production entry point, which
|
||||
still refuses that state by name (B1 deliverable 1). The same block is what forces
|
||||
`engine_matrix.rs` to seed roots through `segment::initialize_root`, and it is disclosed
|
||||
there as `ROOT_SEEDED_BY_NON_PRODUCTION_PATH`.
|
||||
Moving the cycles onto production submit was blocked on `StoreEngine::open` startup state 1,
|
||||
because the child process could not create a store root through the production entry point.
|
||||
**That block is gone**: B1 landed state 1, and every root B4 measures — the benchmark's and
|
||||
the Wave B rows' — is now built by `StoreEngine::open`, so `engine_matrix.rs`'s
|
||||
`ROOT_SEEDED_BY_NON_PRODUCTION_PATH` disclosure and its `segment::initialize_root` seeding
|
||||
are retired.
|
||||
|
||||
The move is therefore **deferred, not blocked** — a separate B4 assignment that has not been
|
||||
made rather than one that cannot be done. That distinction matters here: a blocked item waits
|
||||
for someone else, and a deferred one waits only for a decision, so this is the entry that
|
||||
should be picked up first when the acknowledged-crash-recovery criterion is next worked.
|
||||
|
||||
Consequences, stated so no later reader has to reconstruct them:
|
||||
|
||||
|
|
@ -1914,6 +2042,24 @@ Also required before the phase closes, from §13's stop conditions: the result b
|
|||
report index bytes/object and checkpoint lookup fan-out, and the P2 runs must not have been
|
||||
achieved with checkpointing disabled.
|
||||
|
||||
**Both of those last clauses are now mechanical rather than prose** (contract review
|
||||
2026-07-28-C). A `gate="storage_primitive"` bundle with `outcome="pass"` must declare
|
||||
`run_conditions.checkpointing = "exercised"` and `run_conditions.index_maintenance =
|
||||
"runs_sealed"`, alongside `initialization_path = "store_engine_open"` and `mutation_path =
|
||||
"store_engine_submit"`. A reader no longer has to take the P2 row of the table above on trust:
|
||||
the conditions the number was obtained under travel inside the bundle as values, and a bundle
|
||||
that met none of them cannot encode a pass.
|
||||
|
||||
The harness as it stands satisfies **two of the four**: since B1 landed startup state 1, the
|
||||
submit path both creates its root through `StoreEngine::open` and mutates it through
|
||||
`StoreEngine::submit`. It satisfies neither `checkpointing` nor `index_maintenance`, and those
|
||||
are the two that decide whether a P2 figure describes a steady state or a burst — a run holding
|
||||
every index delta in memory, with a lookup fan-out that grows for its whole duration and no
|
||||
checkpoint ever taken, is measuring a system that has not yet reached the condition the number
|
||||
is supposed to characterize. Two of four is the accurate reading of how much of the P2 exit
|
||||
criterion is currently earned, and the remaining two are the expensive ones — the same
|
||||
disclosure the SIGKILL carry-forward above makes about the crash-recovery row.
|
||||
|
||||
## 8. Capacity analysis for P2 on the frozen reference hardware
|
||||
|
||||
`bench/reference-hardware.toml` freezes both profiles as a Ryzen 7 9800X3D (8 physical
|
||||
|
|
|
|||
|
|
@ -237,15 +237,15 @@ done
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
bundle_status="skipped"
|
||||
zero_work_status="skipped"
|
||||
unaccounted_status="skipped"
|
||||
if [ "$run_bundle" = "1" ]; then
|
||||
echo "== skeleton result bundle ==" >&2
|
||||
if cargo build -q -p levcs-store \
|
||||
--features bench-harness,store-internals,store-privileged \
|
||||
--bin store-bench 2>/dev/null; then
|
||||
bundle_parent="$work/bundle"
|
||||
bundle_root="$bundle_parent/root"
|
||||
bundle_out="$work/storage-primitive-skeleton.json"
|
||||
rm -rf "$bundle_parent" "$bundle_out"
|
||||
rm -rf "$bundle_parent"
|
||||
|
||||
# The frozen profile requires nodatacow on the journal and segment
|
||||
# directories, and store-bench refuses on mismatch rather than recording
|
||||
|
|
@ -257,8 +257,21 @@ if [ "$run_bundle" = "1" ]; then
|
|||
mkdir -p "$bundle_parent"
|
||||
chattr +C "$bundle_parent" 2>/dev/null || true
|
||||
|
||||
# Both paths, because the schema's verification rules branch on
|
||||
# `run_conditions.mutation_path`: the production submit path is *required*
|
||||
# to assert the two claims contract review 2026-07-28-C granted, and the
|
||||
# journal seam is forbidden from asserting any of the three. A run that
|
||||
# validated one path would leave the other's rules unexercised, and the
|
||||
# unexercised one is where a seam bundle claiming what the seam cannot
|
||||
# observe would appear.
|
||||
bundle_status="schema-valid"
|
||||
for bundle_variant in submit drive; do
|
||||
bundle_root="$bundle_parent/$bundle_variant-root"
|
||||
bundle_out="$work/storage-primitive-skeleton-$bundle_variant.json"
|
||||
rm -rf "$bundle_root" "$bundle_out"
|
||||
|
||||
if "$repo_root/target/debug/store-bench" emit-skeleton \
|
||||
--root "$bundle_root" --out "$bundle_out" \
|
||||
--root "$bundle_root" --out "$bundle_out" --path "$bundle_variant" \
|
||||
--allow-unsigned --seconds 2 --group-len 16 >&2; then
|
||||
if python3 - "$repo_root/bench/result-schema.json" "$bundle_out" >&2 <<'PY'
|
||||
import json, sys
|
||||
|
|
@ -278,7 +291,9 @@ for error in errors:
|
|||
sys.exit(1 if errors else 0)
|
||||
PY
|
||||
then
|
||||
bundle_status="schema-valid"
|
||||
# A later variant may only keep the status the earlier one earned; it
|
||||
# can never upgrade a failure back to valid.
|
||||
:
|
||||
else
|
||||
case $? in
|
||||
3) bundle_status="unvalidated-no-jsonschema" ;;
|
||||
|
|
@ -288,6 +303,63 @@ PY
|
|||
else
|
||||
bundle_status="refused"
|
||||
fi
|
||||
done
|
||||
|
||||
# The zero-work negative control.
|
||||
#
|
||||
# A run with no submitter measures nothing, yet the repositories are still
|
||||
# created — so before this was fixed the bundle reported their fences and
|
||||
# their signatures as measured work and asserted setup_traffic_excluded,
|
||||
# unique_blob_tree_commit_ids, and objects_new_equals_three_per_commit over
|
||||
# an empty set. Every one of those is vacuously true over zero commits, and
|
||||
# bench/result-schema.json validates such a bundle without complaint: counts
|
||||
# are nonnegative and the claims are const true. The schema therefore cannot
|
||||
# be the thing that refuses it, and a gate that only ever ran the happy path
|
||||
# would not notice the emitter's refusal being removed.
|
||||
zero_work_root="$bundle_parent/zero-work-root"
|
||||
zero_work_out="$work/storage-primitive-zero-work.json"
|
||||
rm -rf "$zero_work_root" "$zero_work_out"
|
||||
if "$repo_root/target/debug/store-bench" emit-skeleton \
|
||||
--root "$zero_work_root" --out "$zero_work_out" --path submit \
|
||||
--allow-unsigned --seconds 2 --group-len 16 \
|
||||
--submitters-per-shard 0 >&2; then
|
||||
zero_work_status="emitted"
|
||||
else
|
||||
zero_work_status="refused"
|
||||
fi
|
||||
# A refusal that still wrote a bundle is not a refusal.
|
||||
if [ -f "$zero_work_out" ]; then
|
||||
zero_work_status="emitted"
|
||||
fi
|
||||
|
||||
# The incomplete-accounting negative control.
|
||||
#
|
||||
# A commit whose acknowledgment cannot be journaled is a transaction the
|
||||
# store performed, fenced, and signed, and that the harness can never
|
||||
# count. Until this was fixed the run merely stopped: the failure set no
|
||||
# counter and recorded no error, so the emitter's refused-submit guard
|
||||
# never saw it, and — because it happens after the first commit — neither
|
||||
# did the zero-work guard. The bundle that came out omitted a committed
|
||||
# transaction while still reporting its fence and its signature, and was
|
||||
# schema-valid, exactly like the zero-work bundle above. The failure is
|
||||
# induced with a write to /dev/full so the kernel supplies a real ENOSPC
|
||||
# rather than the harness inventing one; a full tmpfs reaches the same
|
||||
# code path with EDQUOT.
|
||||
unaccounted_root="$bundle_parent/unaccounted-root"
|
||||
unaccounted_out="$work/storage-primitive-unaccounted.json"
|
||||
rm -rf "$unaccounted_root" "$unaccounted_out"
|
||||
if "$repo_root/target/debug/store-bench" emit-skeleton \
|
||||
--root "$unaccounted_root" --out "$unaccounted_out" --path submit \
|
||||
--allow-unsigned --seconds 2 --group-len 4 \
|
||||
--shards 1 --submitters-per-shard 1 \
|
||||
--fail-ack-append-after 1 >&2; then
|
||||
unaccounted_status="emitted"
|
||||
else
|
||||
unaccounted_status="refused"
|
||||
fi
|
||||
if [ -f "$unaccounted_out" ]; then
|
||||
unaccounted_status="emitted"
|
||||
fi
|
||||
else
|
||||
bundle_status="build-failed"
|
||||
fi
|
||||
|
|
@ -311,6 +383,8 @@ echo "acknowledged_loss=$total_acknowledged_loss"
|
|||
echo "torn_transactions=$total_torn"
|
||||
echo "repeated_adoptions=$total_repeated"
|
||||
echo "bundle=$bundle_status"
|
||||
echo "zero_work_run=$zero_work_status"
|
||||
echo "unaccounted_ack_run=$unaccounted_status"
|
||||
|
||||
exit_code=0
|
||||
[ "$matrix_status" = "fail" ] && exit_code=1
|
||||
|
|
@ -325,6 +399,13 @@ exit_code=0
|
|||
[ "$bundle_status" = "unvalidated-no-jsonschema" ] && exit_code=1
|
||||
[ "$bundle_status" = "refused" ] && exit_code=1
|
||||
[ "$bundle_status" = "build-failed" ] && exit_code=1
|
||||
# A zero-work run that produced a bundle is a bundle whose claims are vacuous,
|
||||
# and it is schema-valid, so this is the only place it can be caught.
|
||||
[ "$zero_work_status" = "emitted" ] && exit_code=1
|
||||
# A run that could not account for a committed transaction and emitted a bundle
|
||||
# anyway published totals for a workload that did not happen, and that bundle is
|
||||
# schema-valid too.
|
||||
[ "$unaccounted_status" = "emitted" ] && exit_code=1
|
||||
|
||||
echo "VERIFY_EXIT=$exit_code"
|
||||
exit "$exit_code"
|
||||
|
|
|
|||
Loading…
Reference in New Issue