/** * RFC 3161 Daily Anchor — TSA timestamp anchoring for the sentient event chain. * * Runs once per UTC day from the sentient daemon tick. Posts the SHA-256 of * the current chain HEAD's raw serialised line to a configurable Timestamp * Authority (TSA). Appends a `kind:'tsa_anchor'` sentient event carrying the * opaque `TimeStampToken` bytes (base64-encoded) so that any retroactive * chain forking after the anchor point is detectable by a third party holding * the TSA receipt. * * ## Implementation notes * * This implementation hand-codes the minimal RFC 3161 `TimeStampReq` DER * structure using `node:crypto` for SHA-256 and `node:https`/`node:http` for * HTTP transport. No external dependencies are required. * * The `TimeStampReq` sent to the TSA is: * * ```asn1 * TimeStampReq ::= SEQUENCE { * version INTEGER { v1(1) }, * messageImprint MessageImprint, * certReq BOOLEAN DEFAULT TRUE * } * * MessageImprint ::= SEQUENCE { * hashAlgorithm AlgorithmIdentifier, -- SHA-256 OID * hashedMessage OCTET STRING (32 bytes) * } * ``` * * The response `TimeStampToken` (DER bytes) is stored opaquely as base64 in * the event payload. Full ASN.1 response parsing is not performed — the token * is a tamper-evident receipt whose time can be extracted later by a proper * RFC 3161 library (future follow-up). * * ## Sentient config * * The TSA endpoint URL is read from `.cleo/sentient.json` at key * `tsaEndpoint`. Defaults to `http://timestamp.digicert.com`. * * ## Failure handling * * If the TSA request fails (network error, non-200 response, timeout), the * function logs a warning and returns `null` without throwing. This prevents * a network partition from blocking the daemon tick. * * @see DESIGN.md §8 T1010-S6 * @task T1026 */ import type { TsaAnchorEvent } from './events.js'; export type { TsaAnchorEvent } from './events.js'; /** * Read the TSA endpoint URL from `.cleo/sentient.json`, falling back to the * default if the file is absent or the field is not set. * * @param projectRoot - Absolute path to the CLEO project root. * @returns The TSA endpoint URL to use. * @internal */ export declare function readTsaUrl(projectRoot: string): Promise; /** * Anchor the current sentient event chain head with an RFC 3161 timestamp. * * This function is designed to be called once per UTC day from the daemon * tick. It is a no-op if the last `tsa_anchor` event was appended less than * 24 hours ago, preventing duplicate anchor charges against rate-limited * free-tier TSAs. * * Steps: * 1. Check if a `tsa_anchor` event was written within the last 24 h. * If so, return `null` immediately. * 2. Read the current chain HEAD (last event in the log). * 3. Compute `sha256(chainHeadHash bytes)` — the message imprint. * 4. Build a minimal RFC 3161 `TimeStampReq` DER buffer and POST it to the * TSA endpoint from `.cleo/sentient.json.tsaEndpoint` (or default). * 5. On success, store the raw `TimeStampResp` DER bytes as base64. * 6. Append a `tsa_anchor` sentient event with the token and metadata. * 7. Return the written event. * * On any TSA error (network, non-200, timeout), logs a warning and returns * `null` without throwing. * * @param projectRoot - Absolute path to the CLEO project root. * @param tsaClientOverride - Optional override for the HTTP POST function. * Used in tests to avoid real network calls. Defaults to * {@link postTimestampRequest}. * @returns The written {@link TsaAnchorEvent}, or `null` if the anchor was * skipped (< 24 h since last anchor or TSA failure). * * @example * ```ts * import { anchorChainDaily } from '@cleocode/core/sentient/tsa-anchor.js'; * * const anchored = await anchorChainDaily(projectRoot); * if (anchored) { * console.log('Chain anchored. Receipt:', anchored.receiptId); * } * ``` */ export declare function anchorChainDaily(projectRoot: string, tsaClientOverride?: (url: string, body: Buffer) => Promise): Promise; /** * Build a minimal RFC 3161 `TimeStampReq` DER buffer. * * Encodes: * * ```asn1 * TimeStampReq ::= SEQUENCE { * version INTEGER (1), * messageImprint MessageImprint, * certReq BOOLEAN (TRUE) * } * MessageImprint ::= SEQUENCE { * hashAlgorithm AlgorithmIdentifier { SHA-256 OID, NULL }, * hashedMessage OCTET STRING (32 bytes) * } * ``` * * DER uses definite-length encoding. Short-form (≤ 127 bytes) is used for * inner elements; long-form two-byte prefix is used if needed for the outer * SEQUENCE. * * @param messageHash - 32-byte SHA-256 digest to timestamp. * @returns DER-encoded `TimeStampReq` buffer. */ export declare function buildTimestampRequest(messageHash: Buffer): Buffer; /** * POST a DER-encoded `TimeStampReq` to a TSA endpoint. * * Uses `node:https` for HTTPS URLs and `node:http` for HTTP URLs. * Enforces a 30-second timeout. * * @param tsaUrl - Full URL of the TSA endpoint. * @param body - DER-encoded `TimeStampReq` buffer. * @returns Raw response body as a `Buffer` (the `TimeStampResp` DER). * @throws On network error, non-2xx HTTP status, or timeout. */ export declare function postTimestampRequest(tsaUrl: string, body: Buffer): Promise; //# sourceMappingURL=tsa-anchor.d.ts.map