# CTCL v1 — normative digest

This is a compact, agent-facing digest of the API's actual behavior. It is derived from
the same router as the live deployment; where it disagrees with the running Worker, the
Worker is right.

## Core formula

    tau_i = Phi_i(I*)

I* is a shared reference instant. Phi_i is system i's own transform (epoch, rate,
offset, timezone, calendar, or policy). tau_i is that system's local time. Systems never
need to share a clock, calendar, or epoch — only agree on I*.

## Response envelope

Success: {ok: true, data: {...}, meta: {api_version, request_id, ...}}.
Failure:  {ok: false, error: {code, message, details}, meta: {api_version, request_id}}.
This shape is frozen for API version v1 (see governance/versioning-policy.md).

## Challenge-bound attested now

POST /v1/attest-now and MCP ctcl.attest_now take only a 32–128 character lowercase
hex nonce and a 64-character lowercase SHA-256 context_digest. CTCL selects the
instant from its own edge clock; no caller time or public KV write is accepted.
The Ed25519 signed bytes are UTF-8 "CTCL-ATTEST-NOW/V1\n" followed by compact
recursively key-sorted JSON of the complete attestation object. Its trust_tier
is T2, not T3/T4; estimated_uncertainty_ns is an estimate, not a calibrated
accuracy bound. A relying system must independently pin the CTCL public key,
verify the exact signature scheme, and own nonce uniqueness, freshness and
context binding. This signature proves neither the caller's identity nor
authority over the digest's underlying content.

## Encodings and timescales

Encodings: unix_s, unix_ms, unix_us, unix_ns, rfc3339 (iso8601 accepted as an alias).
Timescales: utc (civil reference, includes leap seconds), posix (unix time, leap
seconds flattened), tai and gps (leap-aware for any past instant via the full
1972-2017 historical offset table; cannot predict a future leap second not yet
declared, so post-2017 accuracy depends on the table staying current — none has
been declared since 2017-01-01).

## MUST / SHOULD

- A client MUST treat quality.precision and quality.estimated_uncertainty_ns as
  authoritative over any assumption drawn from the presence of ns/us fields.
- A client MUST NOT silently pick one candidate when /v1/resolve or the Boundary
  Inspector returns more than one — surface the ambiguity.
- A client SHOULD store an instant_id (from /v1/instants) for anything that needs to be
  recalled later, rather than a bare numeric timestamp.
- A client SHOULD check /v1/planner/constraint-types before relying on a constraint
  type in /v1/planner/shared-instant — unsupported types are reported per-item, not
  silently dropped, but they also don't count toward a plan's satisfied score.
- A server extension MUST NOT remove or repurpose an existing field in the v1 envelope;
  new capability ships as additive fields or as a new /v2 surface.

## Error codes

See ai/tools/tools.md or the human /developers page for the full table with HTTP
status codes and one-line descriptions; the canonical list is also declared in
ai/specs/error-schema.json's error.code description.

## Endpoint index

now, timescales, encodings, convert, transform, instants (create/get), i/{id} (human
share page), systems (create/list/get/now), path, temporal-groups (create/list/get/
expand), workspaces (create/list/get/expand), boundaries/inspect, resolve,
planner/shared-instant, planner/constraint-types, validate, transforms (catalog),
version, pubkey. Full detail: /openapi.json and /ai/ctcl.json.
