Skip to content

intent_bridge: normalize integer-by-value timestamps (authorized_at, expires_at, observed_at) to int and bound now by JCS_SAFE_INTEGER #568

Closed

Description

@drk-ram

What is wrong

Contributor: Raghuvar Durga (@drk-ram)

On main (e1560f3), src/agentrust_trace/intent_bridge.py has two defects in its timestamp handling:

  1. Whole-valued float timestamps (100.0, 150.0) are validated by _integer_value but not normalized to int:

    • In verify_bridge (lines 410-421), _integer_value(authorization[field], f"authorization.{field}") validates authorized_at and expires_at per §3.2.2 (accepting 100.0 and 200.0), but discards the returned int, leaving float values in the returned authorization dict.
    • In _bind_successor_observation (lines 275-285), observed_at = _integer_value(after["observed_at"], "successor envelope observed_at") validates after["observed_at"], but _bind_successor_observation returns after with after["observed_at"] still a float.
    • Because sign_successor_artifact (lines 111-118) sets "observed_at": bound["observed_at"], calling sign_successor_artifact with after={"observation": {...}, "observer": "obs-1", "observed_at": 150.0} emits a signed artifact whose observed_at is 150.0 (float instead of int).
    • And in verify_successor_artifact (line 216), bound["observed_at"] in the returned dictionary remains 150.0 (float).
  2. verify_bridge does not bound now by JCS_SAFE_INTEGER:

    • Unlike successor_observation.evaluate_successor_observation (which checks 0 <= now <= JCS_SAFE_INTEGER), verify_bridge (lines 422-424) accepts now = 10**20 (above JCS_SAFE_INTEGER). Notice in tools/sweep_public_surface.py that successor_observation.evaluate_successor_observation.now rejects 10**20, whereas intent_bridge.verify_bridge did not check now > JCS_SAFE_INTEGER.

Reproduction on main (e1560f3):

from agentrust_trace import generate_key
from agentrust_trace.intent_bridge import sign_successor_artifact

key = generate_key()
after = {"observation": {"ok": True}, "observer": "obs-1", "observed_at": 150.0}
artifact = sign_successor_artifact("auth-1", after, "key-1", key)
assert type(artifact["observed_at"]) is float  # 150.0 instead of int 150!

Spec section or file

  • spec/trace-v0.2.md §3.2.2
  • src/agentrust_trace/intent_bridge.py (_bind_successor_observation, sign_successor_artifact, verify_successor_artifact, verify_bridge)

Expected behavior

  1. _bind_successor_observation and verify_bridge should return a shallow copy with observed_at, authorized_at, and expires_at normalized to int (without mutating the caller's input dictionary in place), so sign_successor_artifact, verify_successor_artifact, and verify_bridge always emit/return int timestamps.
  2. verify_bridge should reject now > JCS_SAFE_INTEGER with IntentBridgeError("now must be a non-negative integer Unix timestamp within the JCS safe-integer range").

Impact

Prevents float timestamps from leaking out of sign_successor_artifact, verify_successor_artifact, and verify_bridge when whole-valued float timestamps (100.0, 1.76e9) are supplied, and aligns verify_bridge's now bound with JCS_SAFE_INTEGER.

Activity

  1. added a commit that references this issue on Oct 19, 2026
    754b68e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions