Skip to content

fix(provenance): type issued_at and tool_count as integer and decide by value (#485) - #520

Merged
imran-siddique merged 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-provenance-integer-by-value-485
Oct 15, 2026
Merged

imran-siddique merged 1 commit into
agentrust-io:mainfrom
drk-ram:drk-ram-fix-provenance-integer-by-value-485

Conversation

@drk-ram

@drk-ram drk-ram commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

What this changes

Closes #485
Contributor: Raghuvar Durga (@drk-ram)

Per maintainer direction on #485 (@imran-siddique — option 1, decide by value per TRACE v0.2 §3.2.2):

  1. spec/server-provenance-v1.md (§3 field table, inherited by spec/server-provenance-v2.md §1):
    Types both issued_at and tool_catalog.tool_count as non-negative integers:

    • | issued_at | yes | Non-negative integer: Unix seconds when this record was signed <!-- CHANGED: #485 - type issued_at as integer --> |
    • | tool_catalog.tool_count | yes | Non-negative integer: number of tools. Redundant with the hash by design: a consumer that sees a plausible count and an unexpected hash learns more than one that sees only a mismatch <!-- CHANGED: #485 - type tool_catalog.tool_count as integer --> |
      Per @imran-siddique, the spec sentence is carried as a maintainer correction and CHANGELOG.md is left untouched.
  2. src/agentrust_trace/provenance.py:

    • Decides issued_at (in _check_structure, used by both build_record and verify_record) and tool_catalog.tool_count (in _tool_count, used by both verify_record and check_tool_catalog) by value via _integer_value (spec/trace-v0.2.md §3.2.2), wrapping ValueError in ProvenanceError and preserving the bool exclusion, the >= 0 bound, and the <= JCS_SAFE_INTEGER bound.
    • build_record stores the validated integer value stamped_at returned by _check_structure, while verify_record and check_tool_catalog accept whole-valued float spellings (1760000000.0, 1.76e9, 1.0, 1e0) over the same RFC 8785 canonical bytes and signature as their integer spellings.
  3. Tests (tests/test_provenance.py, tests/test_provenance_tool_count.py, tests/test_integer_by_value.py):

    • Adds paired vectors accepting whole-valued float and exponent spellings (1760000000.0 / 1.76e9 for issued_at; 1.0 / 1e0 and 2.0 / 2e0 for tool_catalog.tool_count) beside fractional (1760000000.5 / 17600000005e-1, 1.5 / 15e-1), boolean, string, negative (-1, -1.0), and out-of-range (9007199254740992, 9007199254740992.0, 1e21) values refused across v1 and v2.

Cold-reader review: A fresh code-review agent inspected the diff against issue #485, spec/server-provenance-v1.md, spec/server-provenance-v2.md, spec/trace-v0.2.md §3.2.2, and src/agentrust_trace/sign.py. It verified that _check_structure and _tool_count preserve the bool, non-negative (>= 0), and JCS_SAFE_INTEGER guards while deciding integer membership by value, that check_tool_catalog still checks hash mismatches ahead of tool_count, and that paired positive/negative test cases cover both v1 and v2; no defects were found and no post-review changes were required.

Type of change

  • Editorial (typo, link fix, clarification: no normative effect)
  • Non-breaking spec change (new optional field, new platform profile, informative addition)
  • Breaking spec change (requires 14-day comment period and Project Lead sign-off)
  • Schema change
  • Example addition

Spec section

spec/server-provenance-v1.md §3 ("The record", inherited by spec/server-provenance-v2.md §1), applying spec/trace-v0.2.md §3.2.2 ("What counts as an integer").

Tests for a fix

Running python tools/review_bar.py --base 6666574 --head HEAD reports 53 fail on behaviour, 0 fail on a missing name or file:

  • tests/test_provenance.py::test_issued_at_is_decided_by_value_in_pairs[1760000000.0-1760000000.5] and [1760000000.0-1760000000.5] / [9007199254740991.0-9007199254740992.0]: fails on main because build_record and verify_record rejected whole-valued float timestamps (1760000000.0, 1.76e9, float(JCS_SAFE_INTEGER)).
  • tests/test_provenance_tool_count.py::test_whole_float_tool_count_verifies_and_matches_live_catalog[2.0] and [2.0]: fails on main because _tool_count rejected whole-valued float counts (2.0, 2e0).
  • tests/test_provenance_tool_count.py::test_verify_record_refuses_out_of_range_tool_count_in_both_spellings and tests/test_provenance_tool_count.py::test_check_tool_catalog_alone_refuses_malformed_count: fail on main for JCS_SAFE_INTEGER + 1, float(JCS_SAFE_INTEGER + 1), and 1e21 because _tool_count previously lacked the JCS_SAFE_INTEGER bound.
  • tests/test_integer_by_value.py::test_provenance_integer_members_written_as_whole_floats_are_the_values_signed, test_a_provenance_issued_at_that_is_not_a_non_negative_integer_is_refused_with_its_reason, and test_a_provenance_tool_count_that_is_not_a_non_negative_integer_is_refused_with_its_reason: fail on main across v1 and v2.

Validation commands run and passed:

  • pytest tests/test_provenance.py tests/test_provenance_clock.py tests/test_provenance_tool_count.py tests/test_integer_by_value.py tests/test_public_functions_raise_what_they_document.py tests/test_requirement_keywords_are_attributable.py — passed (665 passed)
  • python tools/sweep_public_surface.py --strict — passed (89 parameters swept, 141 accepted junk values, 0 unfiled leak(s))
  • ruff check src tests scripts — passed (All checks passed!)
  • python tools/check_dashes.py — passed (no dashes outside examples/, spec/trace-v0.1.md)
  • mypy src/agentrust_trace — passed (Success: no issues found in 15 source files)

Checklist

  • DCO sign-off on all commits (git commit -s)
  • CHANGELOG.md updated (for any normative change)
  • Breaking changes marked with <!-- CHANGED: #NNN: description --> in spec text
  • Backward compatibility statement included (for breaking changes)

…by value (agentrust-io#485)

Signed-off-by: Raghuvar Durga <177662415+drk-ram@users.noreply.github.com>

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@drk-ram
drk-ram requested review from a team, lywinged and rajnisht7 as code owners October 14, 2026 22:56

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the #485 ruling as written: both members decided by value, the bool and range guards kept, and the 1760000000.0 / 1760000000.5 pair in place. I'm taking the two server-provenance-v1.md rows as the maintainer correction I said I would carry, so they land here rather than separately. Checked together with #518, #519 and #521: all four merge cleanly onto main and the combined tree passes everything main passes.

@imran-siddique
imran-siddique merged commit d328146 into agentrust-io:main Oct 15, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Server provenance: are issued_at and tool_count decided by value?

2 participants