{
  "tool_id": "art-506-classify-t1-posttrade-timing",
  "tool_version": "1.0.0",
  "display_name": "T+1 Post-Trade Timing Classifier",
  "mcp_name": "classify_t1_posttrade_timing",
  "mandate_type": "compliance_mandate",
  "wave": 78,
  "gpu": false,
  "url": "https://ainumbers.co/chaingraph/art-506-classify-t1-posttrade-timing.html",
  "description": "Classifies the post-trade timings a caller supplies to answer the question a settlement readiness programme is actually trying to answer: which step breaches its cut-off under the shorter settlement cycle that did not breach under the longer one. Each step in the caller's declared chain order is measured against a target-cycle cut-off and a baseline-cycle cut-off, and reports its status as on time, at risk, breached or undetermined, the residual margin in seconds on both sides, and whether the shorter cycle is what breaks it. The first failing step is named, and it is the first in the declared chain order rather than the earliest by clock, because a post-trade chain is a sequence of dependencies and not a sorted list of instants. The at-risk band is a caller policy input: with no band declared there is no at-risk zone, and that absence is reported rather than filled with an invented threshold. No cut-off table is shipped and there is no named-venue profile set. Market and venue cut-offs are caller inputs, never data kept current here, because a table of cut-offs is a standing maintenance duty and a duty that silently goes false is worse than no table at all. This classifies supplied timings. It observes no venue, no central securities depository and no matching platform, it opens no connection, and it is not monitoring. No clock is read: timestamps are parsed from caller strings with a strict ISO 8601 grammar and nothing is compared against the present moment, so nothing expires on its own. Every emitted number passes a finite gate, so a missing, blank, malformed or non-existent timestamp yields a null margin with a named reason and marks the step undetermined rather than reading as on time, and an unclassified step is never counted as an on-time step. Zero personal data by construction: trades and steps are identified by opaque caller references only. Stated boundary: this computes no settlement penalty, which is a separate concern, it states nothing about funding or foreign exchange implications, it makes no claim about markets outside the cycle change the caller declares, and it is not legal, tax or regulatory advice.",
  "input_schema_ref": "chaingraph/art-506-classify-t1-posttrade-timing.html#manifest",
  "consumes": [],
  "feeds": [],
  "status": "live",
  "conformance_fixtures": true,
  "compute_capability": "server",
  "compute_images": [
    {
      "system": "sha256-source",
      "image_id": "sha256:bdca1dc3844ae202963a66ac4fb582aeafa1861b4dc2945696bf1d060d5bf780",
      "valid_from": "2026-07-10"
    },
    {
      "system": "risc0",
      "image_id": "sha256:a1a0bc89b5b1febaeda3519f6dbade0fa5ac16beeb143c4e1b01689573567bc6",
      "valid_from": "2026-07-31"
    }
  ],
  "compute_proof_ready": "ready",
  "export_capability": [
    "json"
  ],
  "compute_proof": {
    "type": "ZkVmReceipt",
    "system": "risc0",
    "receiptFormat": "groth16-bn254",
    "imageId": "sha256:a1a0bc89b5b1febaeda3519f6dbade0fa5ac16beeb143c4e1b01689573567bc6",
    "seal": "EilsmiGNYhHKR3ZMcnsoPAVZBPPB3yFf3ZbALjsXM7kAPaOQzh95PCXL8wuuOgx3MTXk/hgpRzUxY3dnFKH6wC6b7cQXqqgKOqVHSdRU4Q517ainHhqca6Vmz8jgvz7IBYFUn7PmrkIp+PXvoeEGxkx0sCdmFDmok077YyqtNzYMtqjafICfgGln18zMlPeMZ49A/NuOwse5QlTIUtbqXh7fyAj8AcWg19VpkAPUD6Uh9s7a2A6a93da95wYX4z3FharVeFNx448hNdRX8oMNk98obmgMjejJozbGi0qmDklW3WMK6aqvPIbREAyQUJXQ5euH4CxsbY851neOR9Zmw==",
    "journal": {
      "chaingraph_version": "0.4.0",
      "kernel_digest": "sha256:bdca1dc3844ae202963a66ac4fb582aeafa1861b4dc2945696bf1d060d5bf780",
      "output": {
        "at_risk_count": 0,
        "at_risk_margin_seconds": 0,
        "baseline_cycle": "T+2",
        "baseline_not_compared_count": 0,
        "breached_count": 2,
        "cycle_compared": "T+2 to T+1",
        "first_failing_step": "allocation_sent",
        "first_newly_breaching_step": "allocation_sent",
        "newly_breaching_count": 2,
        "note": "Deterministic classification of post-trade step timings the caller supplies, comparing each step against a target-cycle cut-off and a baseline-cycle cut-off to identify which steps the shorter cycle is what breaks. Every cut-off is a caller input: no market or venue cut-off table is shipped, because a table of cut-offs is a maintenance duty that would silently go false. No clock is read and nothing is compared against the present moment. This tool observes no venue, no central securities depository and no matching platform, and it is not monitoring. It computes no settlement penalty, which is a separate concern, and it makes no claim about markets outside the cycle change the caller declares. It is not legal, tax or regulatory advice.",
        "on_time_count": 3,
        "rationale": [
          "Step allocation_sent breaches its T+1 cut-off by 4500 second(s) and met its T+2 cut-off with 31500 second(s) to spare. The shorter cycle is what breaks it.",
          "Step confirmation_affirmation breaches its T+1 cut-off by 6000 second(s) and met its T+2 cut-off with 44400 second(s) to spare. The shorter cycle is what breaks it.",
          "No at-risk band was declared, so at_risk_margin_seconds is zero and no step can be classified at risk. A step that clears its cut-off by one second reads as on time. Declare at_risk_margin_seconds to open a band."
        ],
        "step_count": 5,
        "steps": [
          {
            "achieved_at": "2027-10-12T15:40:00Z",
            "achieved_epoch_seconds": 1823355600,
            "achieved_offset_source": "explicit_utc",
            "baseline_not_compared": false,
            "breaches_under_target_only": false,
            "cutoff_baseline": "2027-10-12T16:30:00Z",
            "cutoff_baseline_epoch_seconds": 1823358600,
            "cutoff_target": "2027-10-12T16:30:00Z",
            "cutoff_target_epoch_seconds": 1823358600,
            "margin_seconds": 3000,
            "margin_seconds_baseline": 3000,
            "status": "on_time",
            "status_baseline": "on_time",
            "step": "trade_execution",
            "synthesised_from": "trade_timestamp and venue_cutoff",
            "undetermined_reason": null
          },
          {
            "achieved_at": "2027-10-12T21:15:00Z",
            "achieved_epoch_seconds": 1823375700,
            "achieved_offset_source": "explicit_utc",
            "baseline_not_compared": false,
            "breaches_under_target_only": true,
            "cutoff_baseline": "2027-10-13T06:00:00Z",
            "cutoff_baseline_epoch_seconds": 1823407200,
            "cutoff_target": "2027-10-12T20:00:00Z",
            "cutoff_target_epoch_seconds": 1823371200,
            "margin_seconds": -4500,
            "margin_seconds_baseline": 31500,
            "status": "breached",
            "status_baseline": "on_time",
            "step": "allocation_sent",
            "synthesised_from": null,
            "undetermined_reason": null
          },
          {
            "achieved_at": "2027-10-12T22:40:00Z",
            "achieved_epoch_seconds": 1823380800,
            "achieved_offset_source": "explicit_utc",
            "baseline_not_compared": false,
            "breaches_under_target_only": true,
            "cutoff_baseline": "2027-10-13T11:00:00Z",
            "cutoff_baseline_epoch_seconds": 1823425200,
            "cutoff_target": "2027-10-12T21:00:00Z",
            "cutoff_target_epoch_seconds": 1823374800,
            "margin_seconds": -6000,
            "margin_seconds_baseline": 44400,
            "status": "breached",
            "status_baseline": "on_time",
            "step": "confirmation_affirmation",
            "synthesised_from": null,
            "undetermined_reason": null
          },
          {
            "achieved_at": "2027-10-13T05:30:00Z",
            "achieved_epoch_seconds": 1823405400,
            "achieved_offset_source": "explicit_utc",
            "baseline_not_compared": false,
            "breaches_under_target_only": false,
            "cutoff_baseline": "2027-10-13T18:00:00Z",
            "cutoff_baseline_epoch_seconds": 1823450400,
            "cutoff_target": "2027-10-13T06:00:00Z",
            "cutoff_target_epoch_seconds": 1823407200,
            "margin_seconds": 1800,
            "margin_seconds_baseline": 45000,
            "status": "on_time",
            "status_baseline": "on_time",
            "step": "settlement_instruction_release",
            "synthesised_from": null,
            "undetermined_reason": null
          },
          {
            "achieved_at": "2027-10-13T07:00:00Z",
            "achieved_epoch_seconds": 1823410800,
            "achieved_offset_source": "explicit_utc",
            "baseline_not_compared": false,
            "breaches_under_target_only": false,
            "cutoff_baseline": "2027-10-14T14:00:00Z",
            "cutoff_baseline_epoch_seconds": 1823522400,
            "cutoff_target": "2027-10-13T14:00:00Z",
            "cutoff_target_epoch_seconds": 1823436000,
            "margin_seconds": 25200,
            "margin_seconds_baseline": 111600,
            "status": "on_time",
            "status_baseline": "on_time",
            "step": "csd_matching",
            "synthesised_from": null,
            "undetermined_reason": null
          }
        ],
        "target_cycle": "T+1",
        "time_zone_offset_minutes": 0,
        "trade_ref": "TRD-OPAQUE-2027-0001",
        "trade_timestamp": "2027-10-12T15:40:00Z",
        "undetermined_count": 0,
        "venue_cutoff": "2027-10-12T16:30:00Z",
        "verdict": "breaches_introduced_by_target_cycle",
        "verdict_reason": "2 step(s) breach under T+1 that met their T+2 cut-off. The first is allocation_sent."
      }
    }
  }
}
