Skip to content

Releases: RobotRegistryFoundation/rcan-py

rcan 3.7.0

Choose a tag to compare

@craigm26 craigm26 released this 16 Oct 06:42
8f5435c

Added

  • rcan.assurance: optional recovery fields from rcan-spec#232 (Appendix C.1.3).
    Envelope.stop.safe_state, Envelope.recovery (on_reject, repeated_stops,
    estop_reset), GateDecision.stop_kind and GateDecision.reason_returned, with
    check_envelope_recovery and check_stop_fields for the schema's conditional
    rules. Not a full schema validation.
  • BE_LEVELS (BE-1, BE-2, BE-3), the level names schemas/envelope.json has
    used since rcan-spec#226. AssuranceLevel accepts both; ASSURANCE_LEVELS keeps
    its A1-A3 value.
  • STOP_KINDS, ON_REJECT_BEHAVIOURS.
  • A LICENSE file (MIT, as the package metadata already declared).

Fixed

  • NodeClient.resolve() fallback requested {api_base}/api/v1/robots/{rrn}, doubling
    /api/v1 on nodes whose api_base already ends in it (rcan.dev does). It now requests
    {api_base}/robots/{rrn}, as the federation protocol defines.
  • README quickstarts call APIs that exist, and were checked against PyPI.

Changed

  • Test fixtures re-copied from rcan-spec master (BE levels; new legged-recovery
    envelope and chain, estop-auto-restart invalid envelope).

rcan 3.6.0

Choose a tag to compare

@craigm26 craigm26 released this 30 Sep 06:03
0184314

Added

  • MessageType.AUTHORIZE = 45. Spec §16.4 requires an AUTHORIZE message but the canonical table never numbered it; 45 is the next free value (RobotRegistryFoundation/rcan-spec#221). Additive: no existing value changes.

  • rcan.assurance: helpers for RCAN Appendix C, the Physical Assurance Profile
    (informative, optional; rcan-spec PR #221, not yet merged). Python port of the
    rcan-spec reference verifier scripts/assurance/evidence-chain.ts, with the
    same hashing and finding codes:

    • GateDecision and Envelope TypedDicts, the Decision literal
      (allow | clamp | reject | stop), Finding, ASSURANCE_LEVELS
      (A1, A2, A3) and GENESIS_PREV.
    • envelope_hash, record_hash and append_record, built on
      rcan.encoding.canonical_json.
    • verify_chain(chain, expected_head=None) (EV-08: BAD_GENESIS, SEQ_GAP,
      PREV_MISMATCH, HASH_MISMATCH, HEAD_MISMATCH). Removal of records from
      the end of a chain is only detected against an anchored expected_head.
    • audit_authority (EV-07 log half: NO_PRINCIPAL, NO_AUTHORITY).
    • replay_against_envelope (ENVELOPE_MISMATCH, REJECT_APPLIED,
      STOP_WITH_MOTION, SPEED_EXCEEDED, TURN_EXCEEDED, OUTSIDE_KEEP_IN,
      INSIDE_KEEP_OUT, and UNCHECKED_FIELDS for fields it does not judge).
    • The functions and constants are also exported from rcan.
  • Tests in tests/test_assurance.py with fixtures copied from rcan-spec. They
    recompute every fixture record hash and the envelope hash produced by the
    TypeScript reference, as a cross-language parity check.

These helpers verify evidence, not robots. Physical assurance levels A1-A3 are
independent of RCAN conformance levels L1-L4. Conformance is not certification.

rcan-py v3.4.1

Choose a tag to compare

@github-actions github-actions released this 09 May 14:27
b184625

What's Changed

  • ci(publish): bump emit-version-tuple action @v3.2.0 → @v3.2.3 by @craigm26 in #60
  • docs(claude-md): bump CLAUDE.md version refs to current (Plan 9 carryover) by @craigm26 in #61
  • fix(audit-bundle): verify_bundle accepts hybrid sig shape (Ed25519+ML-DSA-65) by @craigm26 in #62

Full Changelog: v3.4.0...v3.4.1

rcan-py v3.4.0

Choose a tag to compare

@github-actions github-actions released this 03 May 21:31
221206c

What's Changed

  • docs: Plan 2 Phase 5 PR 2B — retire hardcoded RCAN versions by @craigm26 in #56
  • ci: forbidden-phrase-lint workflow (Plan 2 Phase 5 PR 3B) by @craigm26 in #57
  • feat(audit-bundle): typed v1.0 helpers + verify by @craigm26 in #58

Full Changelog: v3.3.3...v3.4.0

rcan-py v3.3.3

Choose a tag to compare

@github-actions github-actions released this 03 May 00:48

What's Changed

  • feat(manifest): parse + soft-validate optional voice: block (rcan-spec §8.7) by @craigm26 in #50

Full Changelog: v3.3.2...v3.3.3

rcan-py 3.3.0

Choose a tag to compare

@craigm26 craigm26 released this 24 Apr 05:55

Tracks rcan-spec v3.2 (shipped 2026-04-23).

Added

  • ManifestInfo.agent_runtimes — normalized agent.runtimes[] on ROBOT.md frontmatter
  • _normalize_agent + _validate_agent_runtimes helpers in rcan.manifest

Changed

  • SPEC_VERSION 3.1 → 3.2, SDK_VERSION 3.2.0 → 3.3.0
  • from_manifest() validates the agent: block; invalid runtimes[] raise ValueError

Deprecated

  • Flat agent.provider / agent.model ROBOT.md form. Emits DeprecationWarning; wrapped into single-entry runtimes[]. Removal scheduled for rcan-spec v4.0.

Links

  • rcan-spec v3.2: https://rcan.dev/spec/section-8/#multi-runtime
  • Design spec: opencastor-ops/docs/superpowers/specs/2026-04-23-peer-runtimes.md
  • Plan: opencastor-ops/docs/superpowers/plans/2026-04-23-r2-rcan-py-3.3.0-agent-runtimes.md

rcan-py v2.1.0 — from_manifest() ROBOT.md cross-link

Choose a tag to compare

@craigm26 craigm26 released this 18 Apr 15:27

See CHANGELOG.md for details.

  • rcan.from_manifest(path) reads a ROBOT.md manifest and returns a ManifestInfo with rrn, rcan_uri, endpoint, signing_alg, public resolver URL, robot_name, rcan_version, and the raw frontmatter.
  • Optional extra rcan[manifest] installs pyyaml.

See https://robotmd.dev for the ROBOT.md spec.

v2.0.0

Choose a tag to compare

@craigm26 craigm26 released this 17 Apr 22:55

rcan-py 2.0.0 — RCAN spec v3.0, compliance types

PyPI: pip install rcan==2.0.0

Breaking Changes

  • REGISTRY_REGISTER payload now requires fria_ref (RCAN v3.0 §21.3). Use the new make_registry_register() helper which enforces this field.
  • SPEC_VERSION updated from "2.2.1" to "3.0".
  • __version__ updated from "1.4.0" to "2.0.0".

Added

  • rcan.compliance module — dataclasses for RCAN v3.0 §22–§26: FriaDocument, FriaSigningKey, FriaConformance, SafetyBenchmark, InstructionsForUse, PostMarketIncident, EuRegisterEntry.
  • RegistryRegisterPayload TypedDict.
  • make_registry_register() builder function.
  • New feature flags in SUPPORTED_FEATURES: FRIA_COMPLIANCE, SAFETY_BENCHMARK, INSTRUCTIONS_FOR_USE, POST_MARKET_MONITORING, EU_REGISTER.

754 tests passing.

rcan-py v1.2.1 — ML-DSA-65 only (RCAN v2.2)

Choose a tag to compare

@craigm26 craigm26 released this 27 Mar 03:25
69a555e

Breaking Changes

  • Ed25519 fully removed — KeyPair class raises DeprecationWarning and redirects to MLDSAKeyPair
  • pq_sig field removed from wire format — signature.alg = "ml-dsa-65" is the sole signing block
  • sign_message() simplified: sign_message(msg, mldsa_keypair)
  • verify_message() simplified: verify_message(msg, trusted: list[MLDSAKeyPair])

What's New

  • ML-DSA-65 (NIST FIPS 204) is the ONLY signing algorithm
  • Bob (RRN-000000000001) is the first robot running this stack
  • Q-Day timeline: ML-DSA-65 primary NOW (2026), Ed25519 sunset 2027, NIST deadline 2029
  • 675 tests passing

Install

pip install rcan==1.2.1
pip install "rcan[pq]==1.2.1"  # includes dilithium-py

rcan-py v1.2.0 — RCAN v2.2 ML-DSA-65 hybrid signing

Choose a tag to compare

@craigm26 craigm26 released this 27 Mar 00:01

What's New

  • MLDSAKeyPair — ML-DSA-65 key generation, sign, verify, save/load (NIST FIPS 204)
  • Hybrid signing — sign_message(msg, ed_kp, pq_keypair=pq_kp) adds both Ed25519 (sig) and ML-DSA-65 (pq_sig) signatures
  • Hybrid verify — verify_message(msg, trusted, pq_trusted_keys=[...]) checks both; require_pq=True enforces ML-DSA presence (post-2028 mode)
  • RCANMessage.pq_sig — new optional field (dict), serialised/deserialised transparently
  • PQ_HYBRID_SIGNING feature flag in SUPPORTED_FEATURES
  • [pq] extra — pip install 'rcan[pq]' pulls in dilithium-py
  • 593 tests (was 571, +22 PQ signing tests)

Q-Day 2029 Timeline

  • 2026–2028: Hybrid mode — Ed25519 + ML-DSA-65 in every signed message
  • 2028: ML-DSA primary, Ed25519 verify-only
  • 2029: Ed25519 sunset — castor migrate --crypto rotates all keys

References