import { CP_ARTIFACT_NAMES } from "./artifactNames.js"; import type { ContractPipelineArtifactName } from "./artifactNames.js"; export { CP_ARTIFACT_NAMES }; export type { ContractPipelineArtifactName }; export declare const DEPENDENCY_MAP: Record; export interface ContractPipelineArtifactEnvelope { artifact_name: ContractPipelineArtifactName; /** SHA-256 of the raw payload bytes — byte identity of this exact emission. */ content_hash: string; /** Semantic-projection hashes of upstream dependency artifacts at write time. */ dependency_hashes: Partial>; payload: unknown; } /** * Canonical predicate for a stored content-hash envelope. Single-sourced here so * any consumer (the contract-pipeline ingest path, the `validate-artifact` CLI) * unwraps with identical structural rules and cannot drift. A plain payload that * happens to carry an `artifact_name` but no `content_hash` is NOT an envelope. */ export declare function isEnvelope(value: unknown): value is ContractPipelineArtifactEnvelope; /** * Stamp a tool-owned `created_at` onto a raw artifact payload when the host did * not provide one. The host has no clock — `created_at` is tool bookkeeping, not * a judgment field — so the tool stamps it at the point the payload enters the * tool (ingest + the `validate-artifact` self-check), and the host-facing * schemas no longer ask for it. A payload that already carries a string * `created_at` (e.g. a tool-derived artifact) is returned untouched. The stamp * is a universal non-semantic field (`semanticProjection` strips it), so adding * it never affects staleness. Non-object payloads pass through unchanged — their * own validator reports the shape error. */ export declare function stampToolCreatedAt(payload: unknown, now: string): unknown; export declare function contractPipelineDir(artifactsDir: string): string; /** * Path to the optional Path-A seed file. Present only when the intake source * is a structured audit-findings report; absent for document/conversation runs. */ export declare function pathASeedFilePath(artifactsDir: string): string; /** * Canonical envelope path `.json` — the TOOL-owned content-hash envelope. * Host code never reads or writes this; every tool-side consumer reaches it * through `readContractArtifact`. */ export declare function contractArtifactFilePath(artifactsDir: string, name: ContractPipelineArtifactName): string; /** * Host input path `.input.json` — the plain payload the host writes (and * reads for upstreams). The host never sees the tool's canonical envelope; the * tool reads this at ingest, validates, and derives the canonical `.json` * envelope from it (D3). Keeping the two paths disjoint means the on-disk file * the host wrote is never mutated into an envelope in place. */ export declare function contractInputFilePath(artifactsDir: string, name: ContractPipelineArtifactName): string; /** * Hash an artifact's semantic projection (order-independent, stamp-stripped). * Exported so the ingest idempotency guard can compare a freshly-read host input * against the canonical envelope without re-deriving a new (stamp-bearing) * content hash on every next-step. */ export declare function payloadSemanticHash(name: ContractPipelineArtifactName, payload: unknown): string; /** * The semantic hash to compare a dependency against. ALWAYS recomputed from the * envelope's current `payload` — never read from a stored header field — so an * in-place edit to a payload (header untouched) reconverges staleness on the next * read. Cosmetic edits project to the same hash (see `semanticProjection`) and so * still do not re-stale downstreams (B3). */ export declare function envelopeSemanticHash(envelope: ContractPipelineArtifactEnvelope): string; /** Write an artifact envelope. Creates parent directories as needed. */ export declare function writeContractArtifact(artifactsDir: string, name: ContractPipelineArtifactName, payload: unknown): Promise; /** * Write a TOOL-DERIVED artifact to BOTH path roles: the plain payload at the * host-input path `.input.json` and the canonical envelope at * `.json`. * * Why the input path too. Every host-facing artifact path the pipeline renders — * both where a role WRITES its output and where it READS its upstreams — is * `.input.json` (D3: the host's world is entirely plain input files). An * artifact the TOOL derives (the obligation ledger, the finalized contracts, a * degenerate seam report, a no-cycles seam resolution, a merged shard aggregate) * used to land only in the canonical envelope, so any downstream prompt naming * it pointed a worker at a file that never existed. Materializing it here makes * that ENOENT class unrepresentable: the write map and the prompts' input map * are the same map. * * Deliberately NOT folded into `writeContractArtifact`: that one is also how * INGEST wraps a host-authored payload, and writing back there would mutate the * host's own input file in place — the exact separation D3 exists to keep. The * derived input file is idempotent for ingest: its semantic projection matches * the canonical envelope's, so the ingest idempotency guard skips it on every * later pass rather than re-deriving. */ export declare function writeDerivedContractArtifact(artifactsDir: string, name: ContractPipelineArtifactName, payload: unknown): Promise; /** * Payload of a stored artifact whether or not it has been enveloped yet. A null * envelope (absent on disk) yields undefined; a bare payload that was written * without the envelope wrapper is returned as-is. Single-sourced here so every * consumer unwraps identically (cannot drift from `isEnvelope`). */ export declare function envelopePayload(envelope: ContractPipelineArtifactEnvelope | null): unknown; /** Read a stored artifact envelope, or null if absent. */ export declare function readContractArtifact(artifactsDir: string, name: ContractPipelineArtifactName): Promise; export interface StalenessResult { /** Names of artifacts that are stale (upstream changed) or missing (never written). */ stale: ContractPipelineArtifactName[]; /** Names of artifacts that are absent (file does not exist). */ absent: ContractPipelineArtifactName[]; } /** * Detect stale artifacts by walking the dependency DAG transitively. * An artifact is stale when: * - A dependency artifact is absent/missing. * - A dependency artifact's current SEMANTIC-projection hash differs from what * was recorded at write time in this artifact's envelope. Cosmetic upstream * edits (reworded prose, regenerated timestamps, reordered keys) project to * the same hash and do NOT mark downstreams stale (B3). * * Absent artifacts (never written) are reported under `absent`, not `stale`. */ export declare function detectStaleArtifacts(artifactsDir: string): Promise; /** Returns true when the artifact file is present on disk. */ export declare function contractArtifactExists(artifactsDir: string, name: ContractPipelineArtifactName): boolean; //# sourceMappingURL=artifactStore.d.ts.map