Class: Reeve::Testing::Checks::ContractVersion
- Defined in:
- lib/reeve/testing/checks/contract_version.rb
Overview
FR-015: the ledger the host actually migrated implements the entry shape this version of the gem writes.
The audit-entry contract is versioned in prose and in Audit::CONTRACT_VERSION;
what this check adds is the third party to that agreement — the table. A host that
upgraded the gem and skipped the migration has a ledger one shape behind, and every
other check in this kit would go on passing while columns quietly went unwritten.
What each half of this check is worth, stated plainly because it is easy to read more into the version number than it carries:
- The column list is the real test. It is compared against the columns the host's table actually has, and it is written out by hand rather than read back off the model — a check that derives its expectation from the thing it is checking checks nothing.
- The version number is compared against what the ledger model reports, which
is this gem's own
Audit::CONTRACT_VERSION— so by default it compares the gem to itself and can only pass. It earns its keep when a host passesexpected:to pin the version it built its exports against.
Those two are not as separate as they look, and that is by design. A contract bump
is defined as a change to the shape or to what a value means; every such bump also
moves the contract_version column, which means the column list catches a stale
table even when the bump was purely semantic. Contract 2 is the worked example: the
change was metadata's meaning, no existing column moved, and a host still on the
contract 1 table fails here on a missing contract_version column rather than
passing while writing rows nothing can interpret.
The constant below is written out rather than read from Audit for the same
reason the column list is, and one more: the testing kit loads with no ledger and
no ActiveRecord at all (spec/reeve/testing/isolation_spec.rb), so it cannot
reference the audit module. Bumping the contract means editing both by hand, and
spec/reeve/audit/contract_version_spec.rb fails if they drift.
Reeve::Checks::ContractVersion.new.call
Reeve::Checks::ContractVersion.new(expected: 2).call # pinned by the host
Constant Summary collapse
- TABLE =
"reeve_audit_entries"- COLUMNS =
%w[ invocation_id occurred_at agent_id agent_name principal_type principal_id tool_name arguments outcome rule detail record_type record_ids record_count truncated derived guard duration_ms metadata contract_version ].freeze
- EXPECTED_VERSION =
2
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(tool: nil, expected: EXPECTED_VERSION, ledger: nil) ⇒ ContractVersion
constructor
A new instance of ContractVersion.
Methods inherited from Base
Constructor Details
#initialize(tool: nil, expected: EXPECTED_VERSION, ledger: nil) ⇒ ContractVersion
Returns a new instance of ContractVersion.
53 54 55 56 |
# File 'lib/reeve/testing/checks/contract_version.rb', line 53 def initialize(tool: nil, expected: EXPECTED_VERSION, ledger: nil) super(tool: tool, ledger: ledger) @expected = expected end |
Instance Method Details
#call ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/reeve/testing/checks/contract_version.rb', line 58 def call return ledger_unavailable("the audit-entry contract version") unless ledger.available? recorded = ledger.contract_version return version_mismatch(recorded) unless recorded == @expected missing = COLUMNS - ledger.columns return missing_columns(missing) unless missing.empty? passed("the ledger implements audit-entry contract version #{@expected}", version: @expected) end |