← snapshot
6435 bytes
/** Wire types mirroring jac-serve's DTOs (crates/jac-serve/src/dto.rs). */
export type ProvenanceLabel = "human" | "agent" | "mixed";
export interface ActorView {
kind: "human" | "agent" | "unknown";
id: string;
display_name?: string;
}
export interface SnapshotDto {
id: string;
short: string;
tree: string;
parents: string[];
author: ActorView;
provenance: ProvenanceLabel;
message: string;
at: number;
}
export interface RefDto {
name: string;
head: string;
}
export interface RepoSummary {
slug: string;
org: { id: string; name: string };
default_ref: string;
refs: number;
decisions: { unsettled: number; settled: number };
head: SnapshotDto | null;
created_at: number;
}
export interface RepoDetail {
slug: string;
org: { id: string; name: string };
default_ref: string;
refs: RefDto[];
humans: ActorView[];
agents: ActorView[];
decisions: { unsettled: number; settled: number };
object_count: number;
created_at: number;
}
export interface AttestationDto {
id: string;
decision: string;
attestor: ActorView;
statement: string;
at: number;
}
export interface DecisionDto {
id: string;
short: string;
title: string;
rationale: string;
families: string[];
proposed_by: ActorView;
scope: string[];
at: number;
state: "unsettled" | "settled";
attestation?: AttestationDto;
}
export type VerdictDto =
| {
verdict: "admitted";
decisions_checked: number;
ungoverned: boolean;
ref_moved: boolean;
into_head?: string;
}
| {
verdict: "blocked";
reason: string;
unsettled: string[];
ref_moved: boolean;
};
export interface PromotePreview {
verdict: VerdictDto;
changed: string[];
fast_forward: boolean;
}
export interface FileEntry {
path: string;
blob: string;
size: number;
}
export interface SnapshotDetail {
snapshot: SnapshotDto;
files: FileEntry[];
changed_from_parent: string[];
}
export interface TreeEntryDto {
name: string;
kind: "blob" | "tree";
id: string;
size?: number;
}
export interface BlobDto {
id: string;
size: number;
content: string | null;
binary: boolean;
}
export interface PublicationRow {
org: string;
kind: "content" | "decision";
at: number;
}
export interface IntroductionRow {
token: string;
parties: [string, string];
at: number;
}
export interface SketchMatchRow {
publication: string;
org: string;
similarity_permille: number;
similarity_percent: string;
}
export interface ApiErrorBody {
error: { code: string; message: string };
}
/** The init request — the whole ceremony in one POST. */
export interface InitRepoRequest {
name: string;
founder: { display_name: string };
default_ref?: string;
agents?: { model: string }[];
initial_commit?: {
message: string;
files: { path: string; content: string }[];
provenance?: ProvenanceLabel;
};
founding_decision?: {
title: string;
rationale: string;
families?: string[];
scope?: string[];
attestation?: { statement: string };
};
}
export interface InitRepoResponse {
slug: string;
org: { id: string; name: string };
founder: ActorView;
agents: ActorView[];
default_ref: string;
head: SnapshotDto | null;
founding_decision: DecisionDto | null;
created_at: number;
honesty: string;
}
export const RATIONALE_FAMILIES: { label: string; hint: string }[] = [
{ label: "alternatives", hint: "Alternatives considered and what ruled them out." },
{ label: "constraints", hint: "The constraint that forced this shape." },
{
label: "missed-abstraction",
hint: "An abstraction within reach that was skipped — deliberately or not.",
},
{ label: "deferred-work", hint: "Known debt: what another week would have changed." },
{
label: "confidence-risk",
hint: "The part the author is least sure will hold up.",
},
];
/** What a reviewer meant by speaking up. */
export type RemarkKind = "suggestion" | "question" | "note";
/** What they were looking at when they said it. */
export interface RemarkAnchorDto {
kind: "decision" | "file" | "snapshot" | "gate";
id: string;
/** The exact span they had selected, when they had one. */
quote: string | null;
}
/**
* Something a reviewer said that should be acted on.
*
* Not an engine object: a remark is conversation about the work, not an
* attestable claim about it. The path to something durable is to draft it
* into a decision, which a human then attests.
*/
export interface RemarkDto {
id: string;
anchor: RemarkAnchorDto;
/** The reviewer's own words, verbatim. */
body: string;
kind: RemarkKind;
by: { id: string; display_name: string | null };
at: number;
state: "open" | "drafted" | "declined";
outcome: { decision?: string; because?: string } | null;
}
/**
* What an import found, and — more to the point — what it had to guess.
*
* GitHub records who pushed, which is not whose hands made the work, and a PR
* description, which is a summary rather than a rationale anyone signed. The
* report names both gaps rather than papering over them.
*/
export interface ImportReport {
slug: string;
source: {
owner: string;
repo: string;
pull_request: number;
base: string;
head: string;
author: string;
};
imported: {
files: number;
changed_on_github: number;
truncated: boolean;
skipped: string[];
};
decision: string;
inference: {
subject: string;
provenance: ProvenanceLabel;
/** The rule that fired, in words a reader can argue with. */
because: string;
/** True when the label is a working assumption, not evidence. */
assumed: boolean;
};
/** What a person still has to answer. */
gaps: { kind: string; ask: string; why: string }[];
honesty: string;
}
/** One repo's tally inside a shelf. */
export interface ShelfRepo {
slug: string;
source: string;
snapshots: number;
provenance: { human: number; agent: number; mixed: number; assumed: number };
}
/** What a batch import left on disk. */
export interface ShelfIndex {
kind: string;
root: string;
imported: number;
failed: number;
failures: { repo: string; why: string }[];
provenance: {
human: number;
agent: number;
mixed: number;
/** Snapshots labelled human with no evidence either way. */
assumed: number;
note: string;
};
repos: ShelfRepo[];
}