@tangle-network/agent-app 0.45.27 → 0.45.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assistant/index.d.ts +1 -0
- package/dist/assistant/index.js +1 -1
- package/dist/chunk-C3CAYGGQ.js +18 -0
- package/dist/chunk-C3CAYGGQ.js.map +1 -0
- package/dist/chunk-EMLGWEHV.js +33 -0
- package/dist/chunk-EMLGWEHV.js.map +1 -0
- package/dist/{chunk-XEA5EG6P.js → chunk-EPZYYWCT.js} +8 -30
- package/dist/chunk-EPZYYWCT.js.map +1 -0
- package/dist/{chunk-WD2B6HGY.js → chunk-K4RA5T3A.js} +11 -32
- package/dist/chunk-K4RA5T3A.js.map +1 -0
- package/dist/{chunk-RT5RKAFX.js → chunk-QGSVF6DZ.js} +8 -18
- package/dist/chunk-QGSVF6DZ.js.map +1 -0
- package/dist/{chunk-ODYE4A7L.js → chunk-WC43OQMR.js} +40 -29
- package/dist/chunk-WC43OQMR.js.map +1 -0
- package/dist/{chunk-N3G3FSM4.js → chunk-YXA3U4JZ.js} +9 -47
- package/dist/chunk-YXA3U4JZ.js.map +1 -0
- package/dist/legibility/cli.js +14 -8
- package/dist/legibility/cli.js.map +1 -1
- package/dist/legibility/index.js +2 -1
- package/dist/peer-floors/cli.js +14 -8
- package/dist/peer-floors/cli.js.map +1 -1
- package/dist/preflight/cli.js +4 -2
- package/dist/preflight/cli.js.map +1 -1
- package/dist/{run-tEsZUhAf.d.ts → run-D80hoLKh.d.ts} +1 -1
- package/dist/signoff/cli.d.ts +2 -2
- package/dist/signoff/cli.js +6 -18
- package/dist/signoff/cli.js.map +1 -1
- package/dist/signoff/index.d.ts +4 -420
- package/dist/signoff/index.js +3 -55
- package/dist/signoff/proof-cli.js +11 -6
- package/dist/signoff/proof-cli.js.map +1 -1
- package/dist/signoff/proof.d.ts +70 -271
- package/dist/signoff/proof.js +3 -73
- package/dist/signoff/proof.js.map +1 -1
- package/dist/theme-contract/cli.js +6 -2
- package/dist/theme-contract/cli.js.map +1 -1
- package/dist/theme-contract/index.js +2 -1
- package/dist/{types-U7Nz-txa.d.ts → types-Bd6uW9vQ.d.ts} +1 -1
- package/dist/web-react/index.d.ts +28 -40
- package/dist/web-react/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-N3G3FSM4.js.map +0 -1
- package/dist/chunk-ODYE4A7L.js.map +0 -1
- package/dist/chunk-RT5RKAFX.js.map +0 -1
- package/dist/chunk-WD2B6HGY.js.map +0 -1
- package/dist/chunk-XEA5EG6P.js.map +0 -1
|
@@ -18,6 +18,7 @@ export { p as parseReviewQueueItem } from '../queue-VTBA5ONX.js';
|
|
|
18
18
|
export { SandboxTerminalConnection, SandboxTerminalConnectionResponse, UseSandboxTerminalConnectionOptions, UseSandboxTerminalConnectionResult, tabTerminalConnectionId, useSandboxTerminalConnection } from './terminal.js';
|
|
19
19
|
import { i as ProductSeatOffer } from '../billing-BibxgALe.js';
|
|
20
20
|
import { SessionSort, SessionPage, SessionSummary, SessionRailAction } from '../session-shell/index.js';
|
|
21
|
+
import { AsyncResourceState, AsyncEmptySpec } from './async/index.js';
|
|
21
22
|
import { CatalogModel } from '../catalog/index.js';
|
|
22
23
|
import { Harness } from '../harness/index.js';
|
|
23
24
|
export { a as ATTACHMENT_ACCEPT, e as FileIndexReadyResponse, f as FileIndexResponse, g as FileIndexWarmingResponse } from '../attachment-validation-BfJDBU1g.js';
|
|
@@ -1031,11 +1032,6 @@ interface AgentActivityPanelProps {
|
|
|
1031
1032
|
title?: string;
|
|
1032
1033
|
emptyLabel?: string;
|
|
1033
1034
|
}
|
|
1034
|
-
/**
|
|
1035
|
-
* The standalone cross-context delegation surface: every agent run the
|
|
1036
|
-
* product journaled, mission-spawned or not, with status, cost, drill-in, and
|
|
1037
|
-
* a mission link slot for promoted delegations.
|
|
1038
|
-
*/
|
|
1039
1035
|
declare function AgentActivityPanel({ fetchActivity, renderMissionRef, title, emptyLabel }: AgentActivityPanelProps): react.JSX.Element;
|
|
1040
1036
|
|
|
1041
1037
|
/** Human label for a queue state. */
|
|
@@ -1606,6 +1602,7 @@ declare function SessionHistoryPanel({ history, hasAnySessions, query, onQueryCh
|
|
|
1606
1602
|
* each re-derived — typed cells, an error a person can act on, and an
|
|
1607
1603
|
* optimistic edit that can be taken back.
|
|
1608
1604
|
*/
|
|
1605
|
+
|
|
1609
1606
|
/** The value one cell can hold. `null` is "no value on file". */
|
|
1610
1607
|
type RecordGridValue = string | number | boolean | null;
|
|
1611
1608
|
/** Typed outcome for one cell. Callers MUST inspect `succeeded` before reading
|
|
@@ -1631,14 +1628,16 @@ type RecordGridRowOutcome = {
|
|
|
1631
1628
|
declare function recordGridOk(value: RecordGridValue): RecordGridCellOutcome;
|
|
1632
1629
|
/** Build a cell failure outcome carrying the message shown next to the cell. */
|
|
1633
1630
|
declare function recordGridFail(error: string): RecordGridCellOutcome;
|
|
1634
|
-
/**
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
'
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1631
|
+
/**
|
|
1632
|
+
* How a value came to sit in a cell. Rendered as the provenance tone.
|
|
1633
|
+
*
|
|
1634
|
+
* A type alias of `./provenance-model`'s `ProvenanceBasis`, not a lookalike:
|
|
1635
|
+
* two vocabularies for the same concept — a grid cell's origin — shipped one
|
|
1636
|
+
* day apart and would have drifted the moment either one added a value. The
|
|
1637
|
+
* grid gains `asserted` for free (a cell an agent claimed with nothing behind
|
|
1638
|
+
* it), where the caller previously had no way to say that.
|
|
1639
|
+
*/
|
|
1640
|
+
type RecordGridSourceBasis = ProvenanceBasis;
|
|
1642
1641
|
/**
|
|
1643
1642
|
* Where one cell's value came from. Optional on every row — a grid over data
|
|
1644
1643
|
* with no lineage renders identically without it.
|
|
@@ -1652,7 +1651,9 @@ interface RecordGridCellSource {
|
|
|
1652
1651
|
href?: string;
|
|
1653
1652
|
/** Position inside the source: a page, a line, a span — the caller's words. */
|
|
1654
1653
|
locator?: string;
|
|
1655
|
-
/** How the value got here. Absent renders as
|
|
1654
|
+
/** How the value got here. Absent renders as `asserted` — the weakest claim
|
|
1655
|
+
* in the union — because a caller that stated no basis has established
|
|
1656
|
+
* nothing about a document, and an omission must never read as one. */
|
|
1656
1657
|
basis?: RecordGridSourceBasis;
|
|
1657
1658
|
}
|
|
1658
1659
|
/** One option of a `select` column. */
|
|
@@ -1845,17 +1846,6 @@ declare function withoutRecordGridRemoved(overlay: RecordGridOverlay, rowId: str
|
|
|
1845
1846
|
*/
|
|
1846
1847
|
declare function pruneRecordGridOverlay(rows: readonly RecordGridRow[], overlay: RecordGridOverlay): RecordGridOverlay;
|
|
1847
1848
|
|
|
1848
|
-
/** Which of the three data states the caller is in. Distinct renders: an
|
|
1849
|
-
* errored fetch must never be indistinguishable from an empty result. */
|
|
1850
|
-
type RecordGridState = 'loading' | 'error' | 'ready';
|
|
1851
|
-
/** The empty state's content. `action` is the caller's next step — a link into
|
|
1852
|
-
* chat, an import button — because only the product knows what unblocks the
|
|
1853
|
-
* reader. */
|
|
1854
|
-
interface RecordGridEmptyState {
|
|
1855
|
-
title: string;
|
|
1856
|
-
description?: string;
|
|
1857
|
-
action?: ReactNode;
|
|
1858
|
-
}
|
|
1859
1849
|
/** One committed cell edit, handed to `onUpdate`. */
|
|
1860
1850
|
interface RecordGridCellChange {
|
|
1861
1851
|
/** The row as it was BEFORE the edit — what rollback restores. */
|
|
@@ -1887,22 +1877,20 @@ type RecordGridCreateOutcome = {
|
|
|
1887
1877
|
interface RecordGridProps {
|
|
1888
1878
|
/** Column definitions, in render order. */
|
|
1889
1879
|
columns: readonly RecordGridColumn[];
|
|
1890
|
-
/**
|
|
1891
|
-
*
|
|
1892
|
-
|
|
1880
|
+
/** Fetch state over the caller's rows — `web-react/async`'s
|
|
1881
|
+
* `AsyncResourceState`, the same three-state contract every other screen
|
|
1882
|
+
* in the shell fetches through. `ready`/`empty`'s value is the base rows;
|
|
1883
|
+
* optimistic edits are layered over it and dropped as a later value
|
|
1884
|
+
* catches up. `error` always carries `retry` — there is no way to render a
|
|
1885
|
+
* failed fetch with no recovery action, by construction. */
|
|
1886
|
+
state: AsyncResourceState<readonly RecordGridRow[]>;
|
|
1893
1887
|
/** Accessible name for the grid. Required — an unnamed grid is unusable with
|
|
1894
1888
|
* a screen reader. */
|
|
1895
1889
|
caption: string;
|
|
1896
|
-
/**
|
|
1897
|
-
*
|
|
1898
|
-
*
|
|
1899
|
-
|
|
1900
|
-
/** The failure message the error state renders. */
|
|
1901
|
-
error?: string | null;
|
|
1902
|
-
/** Re-run the caller's fetch. Absent → the error state offers no retry. */
|
|
1903
|
-
onRetry?: () => void;
|
|
1904
|
-
/** What the empty state says, and what it offers next. */
|
|
1905
|
-
empty: RecordGridEmptyState;
|
|
1890
|
+
/** What the empty state says, and what it offers next — `web-react/async`'s
|
|
1891
|
+
* `AsyncEmptySpec`, so an empty grid reads in the same words as an empty
|
|
1892
|
+
* list or panel elsewhere in the product. */
|
|
1893
|
+
empty: AsyncEmptySpec;
|
|
1906
1894
|
/** Persist one created row. Absent → no add affordance. */
|
|
1907
1895
|
onCreate?: (values: Readonly<Record<string, RecordGridValue>>) => Promise<RecordGridCreateOutcome>;
|
|
1908
1896
|
/** Persist one cell edit. Absent → every cell renders read-only. */
|
|
@@ -1926,7 +1914,7 @@ interface RecordGridProps {
|
|
|
1926
1914
|
* id, so a record store's fold output maps straight on: one cell per entry,
|
|
1927
1915
|
* its quote and link in `sources`.
|
|
1928
1916
|
*/
|
|
1929
|
-
declare function RecordGrid({ columns,
|
|
1917
|
+
declare function RecordGrid({ columns, caption, state, empty, onCreate, onUpdate, onDelete, newRowDefaults, addLabel, locale, toolbar, loadingRowCount, className, }: RecordGridProps): react.JSX.Element;
|
|
1930
1918
|
|
|
1931
1919
|
/**
|
|
1932
1920
|
* Keyboard + pointer model for a trigger-and-popover pair, dependency-free.
|
|
@@ -2223,4 +2211,4 @@ declare function useThinkingSeconds(active: boolean): number;
|
|
|
2223
2211
|
*/
|
|
2224
2212
|
declare function ChatMessages({ messages, messageSize, models, renderMarkdown, renderExtras, durableCards, userLabel, agentLabel, loading, approval, onToolCallClick, toolRenderers, error, onRetry, renderEmpty, emptyState, header, resolveAttachmentUrl, workProductCards, }: ChatMessagesProps): react.JSX.Element;
|
|
2225
2213
|
|
|
2226
|
-
export { type ActivityTone, type AgentActivityPage, AgentActivityPanel, type AgentActivityPanelProps, type AgentActivityRecord, AgentSessionControls, type AgentSessionControlsProps, type AttachmentFileResult, CatalogModel, ChatAttachmentInput, ChatAttachmentKind, ChatAttachmentPart, ChatComposer, type ChatComposerProps, type ChatEmptyDoor, ChatEmptyState, type ChatEmptyStateProps, ChatInteraction, ChatInteractionField, type ChatInteractionRestoreMode, ChatInteractionStatus, ChatMentionPart, type ChatMessageMetrics, type ChatMessageSegment, ChatMessages, type ChatMessagesProps, ChatSelectField, type ChatStreamCallbacks, type ChatStreamToolCall, type ChatStreamToolResult, type ChatToolCallInfo, type ChatUiMessage, type ComposerFile, type ComposerFilePart, type ComposerSendFailure, type ComposerSendHandler, type ComposerSendOutcome, type ComposerSendPartsHandler, type ComposerSendRejected, type ComposerSendResult, type ConsumeChatStreamResult, DEFAULT_EFFORT_LEVELS, DEFAULT_PROVENANCE_CONFIDENCE_POLICY, type DurableChatCard, DurableChatCards, type DurableChatCardsProps, type DurableInteractionAnswerSubmitterOptions, DurablePlanCard, type DurablePlanCardProps, DurablePlanClientError, type DurablePlanCurrentInput, type DurablePlanDecision, type DurablePlanDecisionClient, type DurablePlanDecisionClientOptions, type DurablePlanDecisionInput, type DurablePlanDecisionResult, type DurablePlanFollowUpReceipt, EMPTY_RECORD_GRID_OVERLAY, type EffortLevel, EffortPicker, type EffortPickerProps, EvidenceLineageTable, type EvidenceLineageTableProps, ExceptionList, type ExceptionListProps, type FetchSessionPage, type FieldValues, FlowWaterfall, type FlowWaterfallProps, INTERACTION_SUBMIT_TIMEOUT_MESSAGE, INTERACTION_SUBMIT_TIMEOUT_MS, InteractionActionButton, type InteractionAnswerSubmission, type InteractionAnswerSubmitterOptions, InteractionAnswers, type InteractionAttemptStore, InteractionBadge, type InteractionBadgeVariant, InteractionCancelData, InteractionPlanCard, type InteractionPlanCardProps, InteractionQuestionCard, type InteractionQuestionCardProps, InteractionRequestWire, type InteractionSubmitResult, type LinkLikeComponent, type LinkLikeProps, type MentionTextSegment, MessageAttachments, type MessageAttachmentsProps, MissionActivityLane, type MissionActivityLaneProps, ModelPicker, type ModelPickerProps, PROVENANCE_BASES, type ProposalApprovalHandlers, type ProvenanceBasis, type ProvenanceBasisMeta, type ProvenanceConfidencePolicy, type ProvenanceGap, type ProvenanceGapKind, ProvenanceLegend, type ProvenanceLegendProps, type ProvenanceRecord, type ProvenanceSource, type ProvenanceSourceStatus, ProvenanceStamp, type ProvenanceStampProps, type ProvenanceStanding, type ProvenanceStandingMeta, ProvenanceValue, type ProvenanceValueProps, ProviderLogo, type ProviderLogoProps, QualityCheckList, type QualityCheckListProps, QuestionOptionList, type QuestionOptionListProps, RecordGrid, type RecordGridBooleanColumn, type RecordGridCellChange, type RecordGridCellOutcome, type RecordGridCellSource, type RecordGridColumn, type RecordGridColumnBase, type RecordGridCreateOutcome, type RecordGridCurrencyColumn, type RecordGridDateColumn, type RecordGridDependency, type
|
|
2214
|
+
export { type ActivityTone, type AgentActivityPage, AgentActivityPanel, type AgentActivityPanelProps, type AgentActivityRecord, AgentSessionControls, type AgentSessionControlsProps, type AttachmentFileResult, CatalogModel, ChatAttachmentInput, ChatAttachmentKind, ChatAttachmentPart, ChatComposer, type ChatComposerProps, type ChatEmptyDoor, ChatEmptyState, type ChatEmptyStateProps, ChatInteraction, ChatInteractionField, type ChatInteractionRestoreMode, ChatInteractionStatus, ChatMentionPart, type ChatMessageMetrics, type ChatMessageSegment, ChatMessages, type ChatMessagesProps, ChatSelectField, type ChatStreamCallbacks, type ChatStreamToolCall, type ChatStreamToolResult, type ChatToolCallInfo, type ChatUiMessage, type ComposerFile, type ComposerFilePart, type ComposerSendFailure, type ComposerSendHandler, type ComposerSendOutcome, type ComposerSendPartsHandler, type ComposerSendRejected, type ComposerSendResult, type ConsumeChatStreamResult, DEFAULT_EFFORT_LEVELS, DEFAULT_PROVENANCE_CONFIDENCE_POLICY, type DurableChatCard, DurableChatCards, type DurableChatCardsProps, type DurableInteractionAnswerSubmitterOptions, DurablePlanCard, type DurablePlanCardProps, DurablePlanClientError, type DurablePlanCurrentInput, type DurablePlanDecision, type DurablePlanDecisionClient, type DurablePlanDecisionClientOptions, type DurablePlanDecisionInput, type DurablePlanDecisionResult, type DurablePlanFollowUpReceipt, EMPTY_RECORD_GRID_OVERLAY, type EffortLevel, EffortPicker, type EffortPickerProps, EvidenceLineageTable, type EvidenceLineageTableProps, ExceptionList, type ExceptionListProps, type FetchSessionPage, type FieldValues, FlowWaterfall, type FlowWaterfallProps, INTERACTION_SUBMIT_TIMEOUT_MESSAGE, INTERACTION_SUBMIT_TIMEOUT_MS, InteractionActionButton, type InteractionAnswerSubmission, type InteractionAnswerSubmitterOptions, InteractionAnswers, type InteractionAttemptStore, InteractionBadge, type InteractionBadgeVariant, InteractionCancelData, InteractionPlanCard, type InteractionPlanCardProps, InteractionQuestionCard, type InteractionQuestionCardProps, InteractionRequestWire, type InteractionSubmitResult, type LinkLikeComponent, type LinkLikeProps, type MentionTextSegment, MessageAttachments, type MessageAttachmentsProps, MissionActivityLane, type MissionActivityLaneProps, ModelPicker, type ModelPickerProps, PROVENANCE_BASES, type ProposalApprovalHandlers, type ProvenanceBasis, type ProvenanceBasisMeta, type ProvenanceConfidencePolicy, type ProvenanceGap, type ProvenanceGapKind, ProvenanceLegend, type ProvenanceLegendProps, type ProvenanceRecord, type ProvenanceSource, type ProvenanceSourceStatus, ProvenanceStamp, type ProvenanceStampProps, type ProvenanceStanding, type ProvenanceStandingMeta, ProvenanceValue, type ProvenanceValueProps, ProviderLogo, type ProviderLogoProps, QualityCheckList, type QualityCheckListProps, QuestionOptionList, type QuestionOptionListProps, RecordGrid, type RecordGridBooleanColumn, type RecordGridCellChange, type RecordGridCellOutcome, type RecordGridCellSource, type RecordGridColumn, type RecordGridColumnBase, type RecordGridCreateOutcome, type RecordGridCurrencyColumn, type RecordGridDateColumn, type RecordGridDependency, type RecordGridNumberColumn, type RecordGridOverlay, type RecordGridProps, type RecordGridRow, type RecordGridRowOutcome, type RecordGridSelectColumn, type RecordGridSelectOption, type RecordGridSourceBasis, type RecordGridTextColumn, type RecordGridValue, type RecordGridWriteOutcome, type RestoreChatInteractionsOptions, ReviewQueueItem, type ReviewQueuePage, ReviewQueuePanel, type ReviewQueuePanelProps, ReviewQueueState, RunDrillIn, type RunDrillInProps, SeatPaywall, type SeatPaywallProps, type SessionActionLabels, type SessionActions, type SessionActionsOptions, type SessionBulkAction, SessionHistoryPanel, type SessionHistoryPanelProps, type SessionHistoryState, type SessionPageQuery, type SmoothRevealOptions, type StreamChatOptions, type SubmitInteractionAnswer, type ToolDetailRenderers, type ToolRunRecord, type ToolRunStep, type UseChatInteractionsOptions, type UseChatInteractionsResult, type UseComposerAttachmentsOptions, type UseComposerAttachmentsResult, type UseDurablePlanFlowOptions, type UseDurablePlanFlowResult, type UseInfiniteScrollOptions, type UseSessionHistoryOptions, type WaterfallRow, WorkProductCard, type WorkProductCardProps, __resetAttachmentFileCacheForTests, activityTone, buildAnswerData, cancelChatInteraction, consumeChatStream, createDurableInteractionAnswerSubmitter, createDurablePlanDecisionClient, createInteractionAnswerSubmitter, createMemoryInteractionAttemptStore, createSessionInteractionAttemptStore, describeProvenance, describeProvenanceSourceStatus, dispatchChatStreamLine, durableChatCardsFromParts, fieldAnswer, fieldValuesFromAnswers, formatActivityCost, formatActivityDuration, formatModelCost, formatRecordGridValue, formatSessionTimestamp, formatTokensPerSecond, hasSecretField, hydrateChatInteractions, interactionStatusLabels, interactionSubmissionSignature, interactionTerminalNotes, isLateAnswerableStatus, isRecordGridCellApplicable, lateAnswerMessage, loadAttachmentFile, loadingProvenanceSources, mergeActivityPages, mergeReviewQueuePages, nextRevealCount, parseRecordGridInput, pendingApprovalOf, projectRecordGridRows, provenanceBasisMeta, provenanceGaps, provenanceNextMove, provenanceStandingMeta, provenanceTriggerLabel, pruneRecordGridOverlay, readRecordGridCell, recordGridEditorText, recordGridFail, recordGridOk, recordGridRowLabel, resolveChatInteraction, resolveProvenanceStanding, responseErrorMessage, restoreChatInteractions, reviewQueueStateLabel, rollUpProvenanceStanding, sameRecordGridValue, segmentMentionContent, settleInteractionSubmit, standingFromConfidence, streamChatTurn, sumRecordGridColumn, terminalizePendingChatInteractions, triggerAttachmentDownload, upsertChatInteraction, useChatInteractions, useComposerAttachments, useDurablePlanFlow, useInfiniteScroll, usePending, usePopover, useSessionActions, useSessionHistory, useSmoothText, useThinkingSeconds, validateRecordGridCell, validateRecordGridRow, waterfallLayout, weakerProvenanceStanding, withRecordGridCreated, withRecordGridRemoved, withRecordGridServerRow, withRecordGridUpdate, withoutRecordGridCreated, withoutRecordGridRemoved, withoutRecordGridUpdate, workProductPartsFromMessageParts, workProductStatusLabel };
|
package/dist/web-react/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/signoff/proof-git.ts","../src/signoff/proof-record.ts","../src/signoff/proof-attach.ts","../src/signoff/proof-verify.ts"],"sourcesContent":["/**\n * The git facts a sign-off proof is bound to, read straight from the object\n * database rather than reported by the process that ran the checks.\n *\n * Everything here is re-derivable by anyone holding the repository, which is\n * what makes the proof checkable: a verifier never trusts a field in the JSON,\n * it recomputes the same value with the same commands and compares.\n */\nimport { spawnSync } from 'node:child_process'\nimport { mkdtempSync, rmSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\n\n/** A git invocation that exited non-zero, carrying stderr so the caller can act. */\nexport class SignoffGitError extends Error {\n readonly args: readonly string[]\n readonly status: number | null\n readonly stderr: string\n\n constructor(args: readonly string[], status: number | null, stderr: string) {\n super(`git ${args.join(' ')} exited ${status ?? 'null'}: ${stderr.trim()}`)\n this.name = 'SignoffGitError'\n this.args = args\n this.status = status\n this.stderr = stderr\n }\n}\n\nexport interface GitResult {\n readonly status: number | null\n readonly stdout: string\n readonly stderr: string\n}\n\n/**\n * Run git and hand back the raw result. `GIT_OPTIONAL_LOCKS=0` keeps a read\n * from touching the index while another agent works the same worktree — this\n * repo is shared by concurrent sessions.\n */\nexport function runGit(repoDir: string, args: readonly string[], options: { readonly input?: string; readonly env?: Readonly<Record<string, string>> } = {}): GitResult {\n const result = spawnSync('git', [...args], {\n cwd: repoDir,\n encoding: 'utf8',\n input: options.input,\n env: { ...process.env, GIT_OPTIONAL_LOCKS: '0', ...options.env },\n maxBuffer: 128 * 1024 * 1024,\n })\n if (result.error) throw new Error(`git ${args.join(' ')} could not run: ${result.error.message}`)\n return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' }\n}\n\n/** Run git, or throw. Trailing newline is stripped — every caller wants the value, not the line. */\nexport function gitText(repoDir: string, args: readonly string[], options: { readonly input?: string; readonly env?: Readonly<Record<string, string>> } = {}): string {\n const result = runGit(repoDir, args, options)\n if (result.status !== 0) throw new SignoffGitError(args, result.status, result.stderr)\n return result.stdout.replace(/\\n$/, '')\n}\n\n/**\n * Is `ancestor` reachable from `descendant`? A port rather than a direct call so\n * the verifier stays a pure function over facts a caller supplies.\n */\nexport type IsAncestorFn = (ancestor: string, descendant: string) => boolean\n\nexport function gitIsAncestor(repoDir: string): IsAncestorFn {\n return (ancestor, descendant) => {\n const result = runGit(repoDir, ['merge-base', '--is-ancestor', ancestor, descendant])\n if (result.status === 0) return true\n if (result.status === 1) return false\n throw new SignoffGitError(['merge-base', '--is-ancestor', ancestor, descendant], result.status, result.stderr)\n }\n}\n\nexport interface CommitFacts {\n /** 40-hex commit id. */\n readonly commit: string\n /** 40-hex id of the tree the COMMIT points at. */\n readonly commitTree: string\n readonly parents: readonly string[]\n /** Committer date, UTC ISO-8601 with a `Z` suffix. */\n readonly committedAt: string\n}\n\n/** Resolve a revision to the commit it names, failing loud on an unknown rev. */\nexport function resolveCommit(repoDir: string, rev: string): string {\n return gitText(repoDir, ['rev-parse', '--verify', `${rev}^{commit}`])\n}\n\nexport function readCommitFacts(repoDir: string, rev: string): CommitFacts {\n const commit = resolveCommit(repoDir, rev)\n const record = gitText(repoDir, ['show', '--no-patch', '--format=%T%n%P%n%cI', commit])\n const [tree, parents, committedAt] = record.split('\\n')\n if (tree === undefined || parents === undefined || committedAt === undefined) {\n throw new Error(`git show returned an unreadable record for ${commit}: ${JSON.stringify(record)}`)\n }\n return {\n commit,\n commitTree: tree,\n parents: parents.length === 0 ? [] : parents.split(' '),\n committedAt: new Date(committedAt).toISOString(),\n }\n}\n\n/**\n * Hash the tree the checks actually ran against, including uncommitted and\n * untracked (non-ignored) files.\n *\n * This is the field that makes drift detectable. A sign-off that ran over an\n * edited worktree produces a tree id no commit carries, so it cannot verify\n * against the commit it claims — which is the intended outcome, not a bug.\n *\n * Written through a throwaway index (`GIT_INDEX_FILE`) so a concurrent agent's\n * staged work in the real index is neither read nor disturbed. `git add -A`\n * honours `.gitignore`, so `node_modules` / `dist` stay out.\n */\nexport function computeWorktreeTree(repoDir: string): string {\n const scratch = mkdtempSync(join(tmpdir(), 'agent-app-signoff-index-'))\n const indexFile = join(scratch, 'index')\n try {\n const env = { GIT_INDEX_FILE: indexFile }\n gitText(repoDir, ['add', '-A', '--'], { env })\n return gitText(repoDir, ['write-tree'], { env })\n } finally {\n rmSync(scratch, { recursive: true, force: true })\n }\n}\n","/**\n * The sign-off proof record: what a local verification run produces so that a\n * merged commit can be interrogated later.\n *\n * ## Threat model — read this before trusting a proof\n *\n * A proof defends against **accident and drift**:\n * - a check that was never run, or ran and failed, being reported as green\n * - a proof produced over a different tree than the commit carries\n * - a proof copied from one commit onto another\n * - a field edited by hand after the fact\n * - a run whose peer versions or tool versions differ from what a reader assumes\n *\n * It does **not** defend against a malicious operator. The HMAC key is a local\n * file on the same machine that runs the checks, so anyone who can run a\n * sign-off can also mint a proof for checks that never ran. There is no secret\n * server, by requirement. What the seal buys is that a proof cannot be produced\n * or altered by someone WITHOUT that key, and that a proof cannot be silently\n * retargeted, which is the whole failure class an absent CI leaves open.\n *\n * Trust in the numbers themselves comes from the steps being real commands with\n * real exit codes and an output digest — not from cryptography.\n */\nimport { spawnSync } from 'node:child_process'\nimport { createHash, createHmac, timingSafeEqual } from 'node:crypto'\nimport { readFileSync } from 'node:fs'\nimport { hostname, userInfo } from 'node:os'\nimport { join } from 'node:path'\nimport { z } from 'zod'\nimport { computeWorktreeTree, readCommitFacts } from './proof-git'\nimport type { SignoffStepStatus } from './types'\n\n/** Bumped when the canonical body shape changes; a verifier refuses versions it does not know. */\nexport const SIGNOFF_PROOF_VERSION = 1\n\nconst isoString = z.string().regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$/, 'must be a UTC ISO-8601 timestamp')\nconst sha1Hex = z.string().regex(/^[0-9a-f]{40}$/, 'must be a 40-hex git object id')\nconst sha256Hex = z.string().regex(/^[0-9a-f]{64}$/, 'must be a 64-hex sha256 digest')\n\n/**\n * The runner's step outcomes, restated as proof vocabulary.\n *\n * A status is carried alongside the exit code because they answer different\n * questions and only one of them is safe on its own: a step that was `skipped`,\n * `cancelled` or `blocked` never produced an exit code at all, and defaulting\n * that to `0` is precisely how a run that did not happen reads as a pass.\n *\n * The `satisfies` and the `Exclude` below pin this list to the runner's own\n * union in BOTH directions, so a status added there fails this file's typecheck\n * instead of quietly arriving as an unmodelled string.\n */\nexport const SIGNOFF_STEP_STATUSES = ['passed', 'failed', 'skipped', 'cancelled', 'blocked'] as const satisfies readonly SignoffStepStatus[]\ntype UnmodelledStatus = Exclude<SignoffStepStatus, (typeof SIGNOFF_STEP_STATUSES)[number]>\nconst _everyRunnerStatusIsModelled: UnmodelledStatus[] = []\nvoid _everyRunnerStatusIsModelled\n\nexport const signoffProofStepSchema = z.object({\n /** Stable id a repo's required-step table refers to (`typecheck`, `test`, `knip`, …). */\n id: z.string().min(1),\n command: z.string().min(1),\n cwd: z.string().min(1),\n /** How the runner judged the step. Only `passed` can satisfy a requirement. */\n status: z.enum(SIGNOFF_STEP_STATUSES),\n exitCode: z.number().int(),\n durationMs: z.number().int().nonnegative(),\n startedAt: isoString,\n /** sha256 of the step's combined stdout+stderr. Logs are not carried; the digest is. */\n outputSha256: sha256Hex,\n})\n\nconst signoffProofPeerSchema = z.object({\n name: z.string().min(1),\n /** `null` when the package is not resolvable on disk — recorded, never guessed. */\n version: z.string().min(1).nullable(),\n})\n\nconst signoffProofSubjectSchema = z.object({\n repo: z.string().min(1),\n commit: sha1Hex,\n /** Tree the checks actually ran against, including uncommitted work. */\n tree: sha1Hex,\n /** Tree the commit itself carries. Equal to `tree` on a clean sign-off. */\n commitTree: sha1Hex,\n parents: z.array(sha1Hex),\n committedAt: isoString,\n})\n\nexport const signoffProofBodySchema = z.object({\n proofVersion: z.number().int().positive(),\n subject: signoffProofSubjectSchema,\n signedAt: isoString,\n host: z.object({\n hostname: z.string().min(1),\n platform: z.string().min(1),\n arch: z.string().min(1),\n user: z.string().min(1),\n }),\n tooling: z.object({\n node: z.string().min(1),\n pnpm: z.string().min(1).nullable(),\n peers: z.array(signoffProofPeerSchema),\n }),\n /**\n * Real elapsed time for the whole run. Recorded separately from the steps\n * because the runner schedules them as wide as their dependencies allow, so\n * the sum of step durations is the SERIAL cost and would overstate this.\n */\n wallClockMs: z.number().int().nonnegative(),\n /** Seeds fed to anything non-deterministic, so a reader can reproduce the same run. */\n seeds: z.record(z.string(), z.union([z.string(), z.number()])),\n /** The step ids this run claims were required. The verifier holds the authoritative table. */\n declaredRequired: z.array(z.string().min(1)),\n steps: z.array(signoffProofStepSchema),\n verdict: z.enum(['pass', 'fail']),\n})\n\nexport const signoffProofSealSchema = z.object({\n algorithm: z.enum(['sha256', 'hmac-sha256']),\n /** sha256 over the canonical body. Chains the seal to every field, including the commit and tree. */\n bodySha256: sha256Hex,\n /** First 12 hex of sha256(key), so a reader can tell WHICH key sealed this. */\n keyId: z.string().regex(/^[0-9a-f]{12}$/).nullable(),\n mac: sha256Hex.nullable(),\n})\n\nexport const signoffProofSchema = z.object({\n body: signoffProofBodySchema,\n seal: signoffProofSealSchema,\n})\n\nexport type SignoffProofStep = z.infer<typeof signoffProofStepSchema>\nexport type SignoffProofPeer = z.infer<typeof signoffProofPeerSchema>\nexport type SignoffProofSubject = z.infer<typeof signoffProofSubjectSchema>\nexport type SignoffProofBody = z.infer<typeof signoffProofBodySchema>\nexport type SignoffProofSeal = z.infer<typeof signoffProofSealSchema>\nexport type SignoffProof = z.infer<typeof signoffProofSchema>\n\ntype CanonicalValue = string | number | boolean | null | readonly CanonicalValue[] | { readonly [key: string]: CanonicalValue }\n\n/**\n * Deterministic JSON: object keys sorted, array order preserved, no whitespace.\n *\n * The seal is a hash over this string, so two readers must produce byte-identical\n * bytes from the same record. `undefined` throws rather than vanishing — a field\n * that silently disappears is a field the hash stops covering.\n */\nexport function canonicalJson(value: CanonicalValue): string {\n if (value === null) return 'null'\n if (typeof value === 'string') return JSON.stringify(value)\n if (typeof value === 'boolean') return value ? 'true' : 'false'\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) throw new Error(`canonicalJson: ${String(value)} is not representable`)\n return JSON.stringify(value)\n }\n if (Array.isArray(value)) return `[${value.map((entry) => canonicalJson(entry)).join(',')}]`\n const record = value as { readonly [key: string]: CanonicalValue }\n const keys = Object.keys(record).sort()\n const fields = keys.map((key) => {\n const entry = record[key]\n if (entry === undefined) throw new Error(`canonicalJson: field ${JSON.stringify(key)} is undefined`)\n return `${JSON.stringify(key)}:${canonicalJson(entry)}`\n })\n return `{${fields.join(',')}}`\n}\n\nexport function canonicalizeProofBody(body: SignoffProofBody): string {\n return canonicalJson(body as unknown as CanonicalValue)\n}\n\nexport function hashProofBody(body: SignoffProofBody): string {\n return createHash('sha256').update(canonicalizeProofBody(body), 'utf8').digest('hex')\n}\n\n/** The digest a runner records for a step's combined output. Shared so both halves agree. */\nexport function hashStepOutput(output: string): string {\n return createHash('sha256').update(output, 'utf8').digest('hex')\n}\n\nexport function signoffKeyId(key: Uint8Array): string {\n return createHash('sha256').update(key).digest('hex').slice(0, 12)\n}\n\n/** Read the local sign-off key. Throws when absent — an unreadable key is never a silent downgrade to unsealed. */\nexport function readSignoffKey(path: string): Uint8Array {\n const raw = readFileSync(path)\n if (raw.byteLength < 16) throw new Error(`sign-off key at ${path} is ${raw.byteLength} bytes; at least 16 are required`)\n return new Uint8Array(raw)\n}\n\nexport function sealProof(body: SignoffProofBody, key?: Uint8Array): SignoffProof {\n const canonical = canonicalizeProofBody(body)\n const bodySha256 = createHash('sha256').update(canonical, 'utf8').digest('hex')\n if (key === undefined) {\n return { body, seal: { algorithm: 'sha256', bodySha256, keyId: null, mac: null } }\n }\n return {\n body,\n seal: {\n algorithm: 'hmac-sha256',\n bodySha256,\n keyId: signoffKeyId(key),\n mac: createHmac('sha256', key).update(canonical, 'utf8').digest('hex'),\n },\n }\n}\n\n/** Constant-time comparison of two hex digests of equal length. */\nexport function macMatches(expected: string, actual: string): boolean {\n if (expected.length !== actual.length) return false\n return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(actual, 'hex'))\n}\n\nexport interface ToolingFactsInput {\n readonly repoDir: string\n /** Package names whose resolved on-disk version belongs in the proof. */\n readonly peerNames: readonly string[]\n}\n\n/**\n * The versions that actually resolved on disk — the field CI's clean install\n * makes trustworthy and a warm local `node_modules` does not. A below-floor peer\n * is invisible to typecheck and to a green suite (it fails at the wire call), so\n * the proof records what was really there rather than what the manifest asks for.\n */\nexport function collectToolingFacts(input: ToolingFactsInput): SignoffProofBody['tooling'] {\n return {\n node: process.version,\n pnpm: readPnpmVersion(input.repoDir),\n peers: input.peerNames.map((name) => ({ name, version: readInstalledVersion(input.repoDir, name) })),\n }\n}\n\n/** `null` when pnpm is not on PATH — a missing version is recorded as missing, never as a guess. */\nfunction readPnpmVersion(repoDir: string): string | null {\n const result = spawnSync('pnpm', ['--version'], { cwd: repoDir, encoding: 'utf8' })\n if (result.error || result.status !== 0) return null\n return result.stdout.trim()\n}\n\n/** Resolved version from the consumer's own `node_modules`, or `null` when the package is not there. */\nexport function readInstalledVersion(repoDir: string, packageName: string): string | null {\n try {\n const manifest = JSON.parse(readFileSync(join(repoDir, 'node_modules', packageName, 'package.json'), 'utf8')) as { version?: unknown }\n return typeof manifest.version === 'string' ? manifest.version : null\n } catch {\n return null\n }\n}\n\n/** Every `@tangle-network/*` name the repo declares as a peer or a dependency. */\nexport function tangleDependencyNames(repoDir: string): readonly string[] {\n const manifest = JSON.parse(readFileSync(join(repoDir, 'package.json'), 'utf8')) as {\n dependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n }\n const names = new Set<string>()\n for (const block of [manifest.dependencies, manifest.peerDependencies, manifest.devDependencies]) {\n for (const name of Object.keys(block ?? {})) {\n if (name.startsWith('@tangle-network/')) names.add(name)\n }\n }\n return [...names].sort()\n}\n\nexport interface BuildSignoffProofInput {\n readonly repoDir: string\n /** Repo identity the verifier's required-step table is keyed on. */\n readonly repo: string\n /** Revision the sign-off is for; defaults to `HEAD`. */\n readonly rev?: string\n readonly steps: readonly SignoffProofStep[]\n /** Measured elapsed time for the run. Required — it is not derivable from the steps. */\n readonly wallClockMs: number\n /** Step ids this run treated as required. Checked against the verifier's table. */\n readonly declaredRequired: readonly string[]\n readonly seeds: Readonly<Record<string, string | number>>\n readonly peerNames?: readonly string[]\n readonly key?: Uint8Array\n readonly now?: Date\n}\n\nexport function buildSignoffProof(input: BuildSignoffProofInput): SignoffProof {\n const facts = readCommitFacts(input.repoDir, input.rev ?? 'HEAD')\n const body: SignoffProofBody = {\n proofVersion: SIGNOFF_PROOF_VERSION,\n subject: {\n repo: input.repo,\n commit: facts.commit,\n tree: computeWorktreeTree(input.repoDir),\n commitTree: facts.commitTree,\n parents: [...facts.parents],\n committedAt: facts.committedAt,\n },\n signedAt: (input.now ?? new Date()).toISOString(),\n wallClockMs: Math.max(0, Math.round(input.wallClockMs)),\n host: { hostname: hostname(), platform: process.platform, arch: process.arch, user: userInfo().username },\n tooling: collectToolingFacts({ repoDir: input.repoDir, peerNames: input.peerNames ?? tangleDependencyNames(input.repoDir) }),\n seeds: { ...input.seeds },\n declaredRequired: [...input.declaredRequired],\n steps: input.steps.map((step) => ({ ...step })),\n verdict: input.steps.every((step) => step.status === 'passed' && step.exitCode === 0) ? 'pass' : 'fail',\n }\n return sealProof(signoffProofBodySchema.parse(body), input.key)\n}\n\n/** Parse an untrusted proof document, failing loud on any shape the verifier cannot reason about. */\nexport function parseSignoffProof(json: string): SignoffProof {\n return signoffProofSchema.parse(JSON.parse(json))\n}\n\nexport function serializeSignoffProof(proof: SignoffProof): string {\n return `${JSON.stringify(proof, null, 2)}\\n`\n}\n\nfunction formatDuration(ms: number): string {\n const seconds = Math.round(ms / 1000)\n if (seconds < 60) return `${seconds}s`\n return `${Math.floor(seconds / 60)}m${String(seconds % 60).padStart(2, '0')}s`\n}\n\n/**\n * The single line an operator pastes into a PR or a merge commit: how many steps\n * ran, how long it took, the seeds, and the verdict.\n */\nexport function formatSignoffSummary(proof: SignoffProof): string {\n const { body, seal } = proof\n const passed = body.steps.filter((step) => step.status === 'passed' && step.exitCode === 0).length\n const serialMs = body.steps.reduce((total, step) => total + step.durationMs, 0)\n // Wall clock is the number an operator is deciding on. The serial total rides\n // alongside it only when the schedule actually overlapped, so a parallel run\n // shows its saving instead of claiming one.\n const wall = serialMs > body.wallClockMs ? `${formatDuration(body.wallClockMs)} (serial ${formatDuration(serialMs)})` : formatDuration(body.wallClockMs)\n const seeds = Object.entries(body.seeds)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, value]) => `${name}=${value}`)\n .join(' ')\n const seal_ = seal.algorithm === 'hmac-sha256' ? `sealed ${seal.algorithm} key ${seal.keyId ?? 'unknown'}` : `unsealed sha256 ${seal.bodySha256.slice(0, 12)}`\n const dirty = body.subject.tree === body.subject.commitTree ? '' : ' DIRTY-TREE'\n return [\n `signoff ${body.verdict}${dirty}`,\n `${passed}/${body.steps.length} steps`,\n wall,\n `${body.subject.repo}@${body.subject.commit.slice(0, 9)} tree ${body.subject.tree.slice(0, 9)}`,\n seeds.length === 0 ? 'seeds none' : `seeds ${seeds}`,\n `node ${body.tooling.node} pnpm ${body.tooling.pnpm ?? 'unresolved'}`,\n seal_,\n body.signedAt,\n ].join(' · ')\n}\n","/**\n * Attaching a proof to the commit it verified.\n *\n * ## Why `git notes`, and what the two rejected carriers cost\n *\n * **A commit-message trailer** cannot work for the field that matters. The\n * trailer is part of the commit object, so writing it changes the SHA the proof\n * claims to cover — the proof would have to be produced before the commit it\n * names exists. Amending re-writes the SHA again, and GitHub's squash-merge\n * rebuilds the message from the PR body, so the trailer does not survive the one\n * transition it would need to.\n *\n * **A committed artifact directory** (`.signoff/<sha>.json`) changes the tree,\n * so the tree hash inside the proof can never cover the file carrying it. It\n * also lands in every diff, and it is exactly the \"file someone can forget\"\n * shape the requirement rules out — deleting it is a normal-looking change.\n *\n * **`git notes` wins because it is the only carrier that is addressed BY the\n * SHA without being part of it.** The note is written after the commit exists,\n * it changes neither the SHA nor the tree, and `git notes show <sha>` is a\n * definite yes/no for any commit anyone can name.\n *\n * ## The tradeoff `git notes` really carries, and how this module answers it\n *\n * Notes are attached to a commit id, and a rebase or a squash-merge produces a\n * NEW commit id, so the note does not follow by itself. Two mechanisms close\n * that gap, and both are needed:\n *\n * 1. `notes.rewriteRef` (see `SIGNOFF_NOTES_GIT_CONFIG`) makes local rebase and\n * amend copy the note forward automatically.\n * 2. `resolveSignoffProof` falls back to a **tree scan**: it reads every proof\n * under the notes ref and matches on the TREE the commit carries. A rebase\n * or a squash of one branch onto an unchanged base preserves the tree, so\n * the content that was verified is still provably the content that merged,\n * even though the SHA changed. The verifier reports which binding it used —\n * `exact` or `tree-equivalent` — and never conflates them.\n *\n * Notes are neither pushed nor fetched by default; `SIGNOFF_NOTES_GIT_CONFIG`\n * carries the refspecs that fix that, and a missing note is reported as\n * `not-found`, never as a pass.\n */\nimport { parseSignoffProof, type SignoffProof } from './proof-record'\nimport { gitText, readCommitFacts, resolveCommit, runGit, SignoffGitError } from './proof-git'\n\nexport const SIGNOFF_NOTES_REF = 'refs/notes/signoff'\n\n/**\n * The git configuration a repo needs for notes to travel. Emitted by the CLI\n * when a proof cannot be found, because the usual cause is an unconfigured repo\n * rather than an unsigned commit.\n */\nexport const SIGNOFF_NOTES_GIT_CONFIG: readonly string[] = [\n `git config --add remote.origin.fetch '+${SIGNOFF_NOTES_REF}:${SIGNOFF_NOTES_REF}'`,\n `git config --add remote.origin.push '${SIGNOFF_NOTES_REF}'`,\n `git config notes.rewriteRef '${SIGNOFF_NOTES_REF}'`,\n 'git config notes.rewrite.amend true',\n 'git config notes.rewrite.rebase true',\n]\n\nexport interface AttachSignoffProofInput {\n readonly repoDir: string\n readonly proof: SignoffProof\n /** Revision to annotate; defaults to the commit the proof names. */\n readonly rev?: string\n /** Replace an existing note. Off by default so a second sign-off cannot quietly overwrite the first. */\n readonly overwrite?: boolean\n}\n\nexport interface AttachedSignoffProof {\n readonly commit: string\n readonly ref: string\n}\n\nexport function attachSignoffProof(input: AttachSignoffProofInput): AttachedSignoffProof {\n const commit = resolveCommit(input.repoDir, input.rev ?? input.proof.body.subject.commit)\n const args = ['notes', `--ref=${SIGNOFF_NOTES_REF}`, 'add']\n if (input.overwrite === true) args.push('-f')\n args.push('-F', '-', commit)\n const result = runGit(input.repoDir, args, { input: `${JSON.stringify(input.proof, null, 2)}\\n` })\n if (result.status !== 0) throw new SignoffGitError(args, result.status, result.stderr)\n return { commit, ref: SIGNOFF_NOTES_REF }\n}\n\nexport type SignoffProofLookup =\n | { readonly found: true; readonly proof: SignoffProof; readonly commit: string; readonly binding: 'exact' | 'tree-equivalent' }\n | { readonly found: false; readonly commit: string }\n\n/** The note attached to exactly this commit, or `found: false`. Never searches. */\nexport function readSignoffProofNote(repoDir: string, rev: string): SignoffProofLookup {\n const commit = resolveCommit(repoDir, rev)\n const result = runGit(repoDir, ['notes', `--ref=${SIGNOFF_NOTES_REF}`, 'show', commit])\n if (result.status !== 0) return { found: false, commit }\n return { found: true, proof: parseSignoffProof(result.stdout), commit, binding: 'exact' }\n}\n\n/** Every proof stored under the notes ref, paired with the commit it annotates. */\nexport function listSignoffProofs(repoDir: string): readonly { readonly commit: string; readonly proof: SignoffProof }[] {\n const listed = runGit(repoDir, ['notes', `--ref=${SIGNOFF_NOTES_REF}`, 'list'])\n if (listed.status !== 0) return []\n const out: { commit: string; proof: SignoffProof }[] = []\n for (const line of listed.stdout.split('\\n')) {\n const [noteBlob, commit] = line.trim().split(/\\s+/)\n if (noteBlob === undefined || commit === undefined) continue\n out.push({ commit, proof: parseSignoffProof(gitText(repoDir, ['cat-file', 'blob', noteBlob])) })\n }\n return out\n}\n\n/**\n * Answer \"was this SHA signed off\" for any commit, including one produced by a\n * rebase or a squash-merge of the branch that was actually verified.\n *\n * Exact note first. Then the tree scan — a proof whose `commitTree` equals this\n * commit's tree verified byte-identical content, which is the strongest claim\n * available once the SHA has been rewritten. The binding is returned so a caller\n * can tell the two apart; nothing here treats them as the same thing.\n */\nexport function resolveSignoffProof(repoDir: string, rev: string): SignoffProofLookup {\n const direct = readSignoffProofNote(repoDir, rev)\n if (direct.found) return direct\n const facts = readCommitFacts(repoDir, rev)\n for (const entry of listSignoffProofs(repoDir)) {\n if (entry.proof.body.subject.commitTree === facts.commitTree) {\n return { found: true, proof: entry.proof, commit: facts.commit, binding: 'tree-equivalent' }\n }\n }\n return { found: false, commit: facts.commit }\n}\n","/**\n * `verify-proof` — the half a reader runs, on a machine that did not produce\n * the proof, to decide whether a commit was really signed off.\n *\n * The verifier never believes the document. Every claim it can re-derive, it\n * re-derives from git and compares; every claim it cannot re-derive is reported\n * as recorded, not as checked. The one field the proof is deliberately not\n * allowed to own is **which steps were required**: a run that declares its own\n * bar can declare an empty one, so the authoritative table lives here and a\n * proof declaring fewer requirements than its repo's table fails as\n * `lowered-bar`.\n */\nimport type { CommitFacts, IsAncestorFn } from './proof-git'\nimport { gitIsAncestor, readCommitFacts } from './proof-git'\nimport { readFileSync } from 'node:fs'\nimport { resolveSignoffProof, SIGNOFF_NOTES_GIT_CONFIG } from './proof-attach'\nimport { canonicalizeProofBody, hashProofBody, macMatches, parseSignoffProof, SIGNOFF_PROOF_VERSION, type SignoffProof } from './proof-record'\nimport { createHmac } from 'node:crypto'\n\n/**\n * The steps a repo's sign-off MUST cover, transcribed from each repo's CI job.\n * A runner is free to run more; it may never run fewer.\n *\n * agent-app .github/workflows/ci.yml\n * tax-agent .github/workflows/deploy.yml (the `ci` job)\n * legal-agent .github/workflows/deploy.yml (the `ci` job)\n */\nexport const SIGNOFF_REQUIRED_STEPS: Readonly<Record<string, readonly string[]>> = {\n 'agent-app': ['install', 'typecheck', 'test:gates', 'test', 'build', 'test:generated', 'knip'],\n 'tax-agent': ['install', 'peer-check', 'typecheck', 'test', 'toolkit-deps', 'toolkit-test', 'build', 'worker-startup'],\n 'legal-agent': ['install', 'peer-check', 'typegen', 'typecheck', 'test', 'build:check'],\n}\n\n/** Throws for a repo with no table — an unrecognised repo has no bar, and no bar is not a pass. */\nexport function requiredStepsFor(repo: string): readonly string[] {\n const steps = SIGNOFF_REQUIRED_STEPS[repo]\n if (steps === undefined) {\n throw new Error(`no required-step table for repo ${JSON.stringify(repo)}; known: ${Object.keys(SIGNOFF_REQUIRED_STEPS).sort().join(', ')}`)\n }\n return steps\n}\n\nexport type SignoffFailureCode =\n | 'unsupported-version'\n | 'body-tampered'\n | 'mac-missing'\n | 'mac-invalid'\n | 'unknown-repo'\n | 'repo-mismatch'\n | 'tree-mismatch'\n | 'dirty-worktree'\n | 'commit-unbound'\n | 'missing-required-step'\n | 'lowered-bar'\n | 'duplicate-step'\n | 'step-failed'\n | 'verdict-fail'\n | 'stale-proof'\n\nexport interface SignoffFailure {\n readonly code: SignoffFailureCode\n readonly detail: string\n}\n\n/** How the proof attaches to the commit that was asked about. */\nexport type SignoffCommitBinding =\n /** The proof names this exact commit. */\n | 'exact'\n /** A different commit id, but byte-identical content — a rebase or a squash of what was verified. */\n | 'tree-equivalent'\n /** Neither. The proof does not describe this commit. */\n | 'none'\n\nexport interface SignoffVerification {\n readonly ok: boolean\n readonly commitBinding: SignoffCommitBinding\n /** True only when a key was supplied AND the mac over the canonical body matched. */\n readonly macChecked: boolean\n readonly failures: readonly SignoffFailure[]\n readonly proof: SignoffProof\n readonly target: CommitFacts\n readonly requiredSteps: readonly string[]\n}\n\nexport interface VerifySignoffProofOptions {\n /** The commit the reader is asking about, read from git — never from the proof. */\n readonly target: CommitFacts\n /**\n * Reachability in the target's history. Required, because the clock cannot\n * answer staleness on its own: git records committer time to the SECOND, so a\n * proof and the commit it is being replayed onto routinely share a timestamp.\n * Ancestry is exact and clock-free.\n */\n readonly isAncestor: IsAncestorFn\n /** Local HMAC key. Omitted, the mac is reported unchecked rather than assumed good. */\n readonly key?: Uint8Array\n /** Overrides the built-in table. Supplying `[]` is a deliberate no-bar check, and says so. */\n readonly requiredSteps?: readonly string[]\n /** Repo identity the caller expects; a mismatch against the proof is a failure, not a rename. */\n readonly expectRepo?: string\n}\n\nexport function verifySignoffProof(proof: SignoffProof, options: VerifySignoffProofOptions): SignoffVerification {\n const failures: SignoffFailure[] = []\n const { body, seal } = proof\n const target = options.target\n\n if (body.proofVersion !== SIGNOFF_PROOF_VERSION) {\n failures.push({ code: 'unsupported-version', detail: `proof declares version ${body.proofVersion}; this verifier reads ${SIGNOFF_PROOF_VERSION}` })\n }\n\n const recomputed = hashProofBody(body)\n if (recomputed !== seal.bodySha256) {\n failures.push({ code: 'body-tampered', detail: `seal claims body sha256 ${seal.bodySha256}; the body hashes to ${recomputed}` })\n }\n\n let macChecked = false\n if (options.key !== undefined) {\n if (seal.mac === null) {\n failures.push({ code: 'mac-missing', detail: 'a key was supplied but the proof carries no mac; it was produced unsealed' })\n } else {\n const expected = createHmac('sha256', options.key).update(canonicalizeProofBody(body), 'utf8').digest('hex')\n if (macMatches(expected, seal.mac)) macChecked = true\n else failures.push({ code: 'mac-invalid', detail: `mac does not verify under the supplied key (proof keyId ${seal.keyId ?? 'none'})` })\n }\n }\n\n if (options.expectRepo !== undefined && options.expectRepo !== body.subject.repo) {\n failures.push({ code: 'repo-mismatch', detail: `proof is for repo ${body.subject.repo}; ${options.expectRepo} was requested` })\n }\n\n let requiredSteps: readonly string[] = options.requiredSteps ?? []\n if (options.requiredSteps === undefined) {\n const known = SIGNOFF_REQUIRED_STEPS[body.subject.repo]\n if (known === undefined) {\n failures.push({ code: 'unknown-repo', detail: `no required-step table for ${body.subject.repo}; a repo with no declared bar cannot be signed off` })\n } else {\n requiredSteps = known\n }\n }\n\n const seen = new Map<string, number>()\n for (const step of body.steps) seen.set(step.id, (seen.get(step.id) ?? 0) + 1)\n for (const [id, count] of seen) {\n if (count > 1) failures.push({ code: 'duplicate-step', detail: `step ${id} appears ${count} times; a repeated id makes coverage ambiguous` })\n }\n\n const missing = requiredSteps.filter((id) => !seen.has(id))\n if (missing.length > 0) {\n failures.push({ code: 'missing-required-step', detail: `required step(s) never ran: ${missing.join(', ')}` })\n }\n\n const declared = new Set(body.declaredRequired)\n const understated = requiredSteps.filter((id) => !declared.has(id))\n if (understated.length > 0) {\n failures.push({ code: 'lowered-bar', detail: `proof declares a smaller required set than ${body.subject.repo}'s table; missing: ${understated.join(', ')}` })\n }\n\n for (const step of body.steps) {\n if (step.status !== 'passed') {\n failures.push({ code: 'step-failed', detail: `step ${step.id} is ${step.status}, not passed (exit ${step.exitCode}, ${step.command})` })\n } else if (step.exitCode !== 0) {\n // An internally inconsistent record: the runner called it passed and the\n // process disagreed. Reported rather than resolved in either direction.\n failures.push({ code: 'step-failed', detail: `step ${step.id} claims status passed but exited ${step.exitCode} (${step.command})` })\n }\n }\n\n if (body.verdict !== 'pass') {\n failures.push({ code: 'verdict-fail', detail: `the run recorded verdict ${body.verdict}` })\n }\n\n if (body.subject.tree !== body.subject.commitTree) {\n failures.push({\n code: 'dirty-worktree',\n detail: `checks ran against tree ${body.subject.tree} while the commit carries ${body.subject.commitTree}; uncommitted work was in the tree`,\n })\n }\n\n if (body.subject.commitTree !== target.commitTree) {\n failures.push({ code: 'tree-mismatch', detail: `proof covers tree ${body.subject.commitTree}; ${target.commit} carries ${target.commitTree}` })\n }\n\n const commitBinding: SignoffCommitBinding =\n body.subject.commit === target.commit ? 'exact' : body.subject.commitTree === target.commitTree ? 'tree-equivalent' : 'none'\n if (commitBinding === 'none') {\n failures.push({ code: 'commit-unbound', detail: `proof names commit ${body.subject.commit}, which is neither ${target.commit} nor its content` })\n }\n\n // Staleness, checked two ways because neither is sufficient alone.\n //\n // The clock catches a proof back-dated relative to the commit it names. Its\n // resolution is git's, one second, so it is deliberately not the only check.\n const signedAt = Date.parse(body.signedAt)\n if (signedAt < Date.parse(body.subject.committedAt)) {\n failures.push({ code: 'stale-proof', detail: `signed at ${body.signedAt}, before the commit it names was written at ${body.subject.committedAt}` })\n }\n // Ancestry catches the case the clock cannot: a proof accepted on CONTENT\n // grounds for a LATER commit in the same history. A rebase or a squash\n // replaces the verified commit, so it is not reachable from the result — but a\n // revert restores an old tree on top of work nobody verified, and there the\n // proof's commit IS an ancestor. Same tree, different history, unverified\n // commits in between.\n if (commitBinding === 'tree-equivalent' && options.isAncestor(body.subject.commit, target.commit)) {\n failures.push({\n code: 'stale-proof',\n detail: `${body.subject.commit} is an ancestor of ${target.commit}; the tree matches only because later work was undone, and that work was never signed off`,\n })\n }\n\n return { ok: failures.length === 0, commitBinding, macChecked, failures, proof, target, requiredSteps }\n}\n\nexport interface VerifySignoffAtRevInput {\n readonly repoDir: string\n readonly rev: string\n readonly key?: Uint8Array\n readonly requiredSteps?: readonly string[]\n readonly expectRepo?: string\n}\n\nexport type SignoffLookupFailure = { readonly found: false; readonly commit: string; readonly hint: readonly string[] }\nexport type SignoffVerifyOutcome = ({ readonly found: true } & SignoffVerification) | SignoffLookupFailure\n\n/** Verify by revision: find the proof attached to that SHA (or to its content), then check it. */\nexport function verifySignoffAtRev(input: VerifySignoffAtRevInput): SignoffVerifyOutcome {\n const lookup = resolveSignoffProof(input.repoDir, input.rev)\n const target = readCommitFacts(input.repoDir, input.rev)\n if (!lookup.found) return { found: false, commit: lookup.commit, hint: SIGNOFF_NOTES_GIT_CONFIG }\n return {\n found: true,\n ...verifySignoffProof(lookup.proof, {\n target,\n isAncestor: gitIsAncestor(input.repoDir),\n key: input.key,\n requiredSteps: input.requiredSteps,\n expectRepo: input.expectRepo,\n }),\n }\n}\n\nexport interface VerifySignoffFileInput {\n readonly repoDir: string\n readonly file: string\n /**\n * The commit to check the file against. REQUIRED, and deliberately not\n * defaulted to the commit the proof names: a proof checked against its own\n * subject can never fail the commit binding, which is a check that reads as\n * strong and cannot catch anything. The reader always states what they are\n * asking about.\n */\n readonly rev: string\n readonly key?: Uint8Array\n readonly requiredSteps?: readonly string[]\n readonly expectRepo?: string\n}\n\n/** Verify a proof document on disk. The repo is still required — \"matches the tree it claims\" is not answerable without it. */\nexport function verifySignoffProofFile(input: VerifySignoffFileInput): SignoffVerification {\n const proof = parseSignoffProof(readFileSync(input.file, 'utf8'))\n const target = readCommitFacts(input.repoDir, input.rev)\n return verifySignoffProof(proof, {\n target,\n isAncestor: gitIsAncestor(input.repoDir),\n key: input.key,\n requiredSteps: input.requiredSteps,\n expectRepo: input.expectRepo,\n })\n}\n\n/** One line per failure, prefixed by its code, in the order the checks ran. */\nexport function formatSignoffVerification(result: SignoffVerification): string {\n const head = result.ok\n ? `VERIFIED ${result.proof.body.subject.repo}@${result.target.commit.slice(0, 9)} binding=${result.commitBinding} mac=${result.macChecked ? 'checked' : 'unchecked'}`\n : `REJECTED ${result.proof.body.subject.repo}@${result.target.commit.slice(0, 9)} binding=${result.commitBinding} (${result.failures.length} failure${result.failures.length === 1 ? '' : 's'})`\n return [head, ...result.failures.map((failure) => ` ${failure.code}: ${failure.detail}`)].join('\\n')\n}\n"],"mappings":"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","names":["spawnSync","join","spawnSync","join","readFileSync","createHmac","readFileSync"]}
|