@tangle-network/agent-app 0.43.67 → 0.43.68

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.
Files changed (57) hide show
  1. package/dist/assistant/index.d.ts +4 -2
  2. package/dist/assistant/index.js +6 -3
  3. package/dist/assistant/index.js.map +1 -1
  4. package/dist/{attachment-validation-B2FFna9E.d.ts → attachment-validation-Dv1A_Puy.d.ts} +1 -1
  5. package/dist/chat-routes/index.d.ts +4 -3
  6. package/dist/chat-routes/index.js +6 -4
  7. package/dist/chat-routes/index.js.map +1 -1
  8. package/dist/chat-store/index.d.ts +3 -2
  9. package/dist/chat-store/index.js +4 -1
  10. package/dist/chat-store/index.js.map +1 -1
  11. package/dist/{chunk-JWBZ74TW.js → chunk-7ESQUSAC.js} +5 -3
  12. package/dist/{chunk-JWBZ74TW.js.map → chunk-7ESQUSAC.js.map} +1 -1
  13. package/dist/{chunk-X3N2H6JE.js → chunk-AFNTRJQ7.js} +10 -1
  14. package/dist/chunk-AFNTRJQ7.js.map +1 -0
  15. package/dist/chunk-F2CBC4DY.js +193 -0
  16. package/dist/chunk-F2CBC4DY.js.map +1 -0
  17. package/dist/chunk-HRH7ASAG.js +759 -0
  18. package/dist/chunk-HRH7ASAG.js.map +1 -0
  19. package/dist/{chunk-YTSEDJWA.js → chunk-RXOTWZ4G.js} +22 -6
  20. package/dist/chunk-RXOTWZ4G.js.map +1 -0
  21. package/dist/chunk-UDSY2F6N.js +331 -0
  22. package/dist/chunk-UDSY2F6N.js.map +1 -0
  23. package/dist/chunk-UOAYS72M.js +80 -0
  24. package/dist/chunk-UOAYS72M.js.map +1 -0
  25. package/dist/chunk-UP33Z633.js +141 -0
  26. package/dist/chunk-UP33Z633.js.map +1 -0
  27. package/dist/{chunk-FMDMI25K.js → chunk-V55WJSR4.js} +2 -2
  28. package/dist/{chunk-YKBDH2UY.js → chunk-WL7XHLDK.js} +2 -2
  29. package/dist/{chunk-7CTIUCQ4.js → chunk-YEFFHORB.js} +2 -73
  30. package/dist/chunk-YEFFHORB.js.map +1 -0
  31. package/dist/eval-campaign/index.d.ts +2 -81
  32. package/dist/index.d.ts +5 -1
  33. package/dist/index.js +62 -8
  34. package/dist/{parts-Bg8qcDvB.d.ts → parts-2ymE5cs-.d.ts} +15 -2
  35. package/dist/queue-C24V13h9.d.ts +68 -0
  36. package/dist/runtime/index.js +3 -2
  37. package/dist/sandbox/index.js +3 -2
  38. package/dist/teams/index.js +5 -5
  39. package/dist/teams/invitations-api.js +4 -4
  40. package/dist/teams-react/index.js +3 -3
  41. package/dist/tools/index.js +8 -6
  42. package/dist/trust-gate-Dcm5xSva.d.ts +83 -0
  43. package/dist/types-CEchbvgz.d.ts +268 -0
  44. package/dist/web-react/index.d.ts +97 -5
  45. package/dist/web-react/index.js +31 -4
  46. package/dist/work-product/index.d.ts +331 -0
  47. package/dist/work-product/index.js +54 -0
  48. package/dist/work-product/index.js.map +1 -0
  49. package/dist/work-product-react/index.d.ts +36 -0
  50. package/dist/work-product-react/index.js +180 -0
  51. package/dist/work-product-react/index.js.map +1 -0
  52. package/package.json +15 -1
  53. package/dist/chunk-7CTIUCQ4.js.map +0 -1
  54. package/dist/chunk-X3N2H6JE.js.map +0 -1
  55. package/dist/chunk-YTSEDJWA.js.map +0 -1
  56. /package/dist/{chunk-FMDMI25K.js.map → chunk-V55WJSR4.js.map} +0 -0
  57. /package/dist/{chunk-YKBDH2UY.js.map → chunk-WL7XHLDK.js.map} +0 -0
@@ -0,0 +1,68 @@
1
+ import { i as WorkProductRecord, j as WorkProductRef, h as WorkProductProvenance } from './types-CEchbvgz.js';
2
+
3
+ /**
4
+ * The review queue is a PROJECTION, not a store — a client-safe pure fold of
5
+ * existing sources into queue items (the `/missions` events.ts pattern: pure
6
+ * data, re-validation at JSON boundaries). The only genuinely-new durable
7
+ * state behind it is the {@link WorkProductRecord} row and its status
8
+ * machine; everything else reads what already exists:
9
+ *
10
+ * - intake: a chat thread for the engagement scope with NO record yet
11
+ * - missing_info: the open record's thread has a PENDING `/interactions` ask
12
+ * - working: record status `draft` (the live token tail stays on the chat
13
+ * surface's existing running-turns endpoint — the projection tracks no
14
+ * live runs, per the reuse-the-primitive invariant)
15
+ * - ready_for_review / changes_requested / approved / blocked: read directly
16
+ * off `WorkProductRecord.status` (blocked surfaces its unresolved count)
17
+ */
18
+
19
+ type ReviewQueueState = 'intake' | 'missing_info' | 'working' | 'ready_for_review' | 'changes_requested' | 'approved' | 'blocked';
20
+ /** One row of the review queue projection for an engagement scope */
21
+ interface ReviewQueueItem {
22
+ scopeKey: string;
23
+ state: ReviewQueueState;
24
+ threadId: string | null;
25
+ workProduct?: WorkProductRef & {
26
+ title: string;
27
+ kind: string;
28
+ };
29
+ /** The pending `/interactions` ask parking this scope, when any. */
30
+ pendingAsk?: {
31
+ interactionId: string;
32
+ title: string;
33
+ };
34
+ blockingExceptions: number;
35
+ failedChecks: number;
36
+ provenance?: Pick<WorkProductProvenance, 'profileHash' | 'servingModels'>;
37
+ updatedAt: number;
38
+ }
39
+ /** An engagement-scoped chat thread — the intake candidate source. Products
40
+ * that scope threads already carry a scopeKey-style column. */
41
+ interface ReviewQueueThread {
42
+ scopeKey: string;
43
+ threadId: string;
44
+ updatedAt: number;
45
+ }
46
+ /** A pending `/interactions` ask on a thread (from the existing list
47
+ * endpoint) — the missing_info source. */
48
+ interface ReviewQueuePendingAsk {
49
+ threadId: string;
50
+ interactionId: string;
51
+ title: string;
52
+ }
53
+ /** Existing-source inputs the projection folds — no new stores */
54
+ interface ReviewQueueInputs {
55
+ workProducts: readonly WorkProductRecord[];
56
+ /** Engagement threads with no work product yet → intake items. */
57
+ threads?: readonly ReviewQueueThread[];
58
+ /** Pending asks by thread → missing_info override on open records. */
59
+ pendingAsks?: readonly ReviewQueuePendingAsk[];
60
+ }
61
+ /** Fold the existing sources into queue items, newest first. */
62
+ declare function projectReviewQueue(inputs: ReviewQueueInputs): ReviewQueueItem[];
63
+ /** Re-validate one JSON-boundary row into a queue item; null for junk. The
64
+ * client-side twin of the server projection, for payloads that cross a
65
+ * fetch boundary. */
66
+ declare function parseReviewQueueItem(raw: unknown): ReviewQueueItem | null;
67
+
68
+ export { type ReviewQueueInputs as R, type ReviewQueueItem as a, type ReviewQueuePendingAsk as b, type ReviewQueueState as c, type ReviewQueueThread as d, projectReviewQueue as e, parseReviewQueueItem as p };
@@ -8,7 +8,7 @@ import {
8
8
  runToolLoop,
9
9
  streamToolLoop,
10
10
  toLoopEvents
11
- } from "../chunk-JWBZ74TW.js";
11
+ } from "../chunk-7ESQUSAC.js";
12
12
  import {
13
13
  DEFAULT_TANGLE_BILLING_ENFORCEMENT_ENV_VAR,
14
14
  DEFAULT_TANGLE_ROUTER_BASE_URL,
@@ -24,7 +24,8 @@ import {
24
24
  tangleExecutionKeyHttpError,
25
25
  trimOrNull
26
26
  } from "../chunk-JML7WKWU.js";
27
- import "../chunk-7CTIUCQ4.js";
27
+ import "../chunk-UOAYS72M.js";
28
+ import "../chunk-YEFFHORB.js";
28
29
  import {
29
30
  __resetCatalogCache,
30
31
  buildCatalog,
@@ -60,11 +60,12 @@ import {
60
60
  writeProfileFilesToBox
61
61
  } from "../chunk-3ALFBTIW.js";
62
62
  import "../chunk-CQZSAR77.js";
63
- import "../chunk-YKBDH2UY.js";
63
+ import "../chunk-WL7XHLDK.js";
64
64
  import "../chunk-3EJ6SFJI.js";
65
65
  import "../chunk-S5SRJJQG.js";
66
66
  import "../chunk-JML7WKWU.js";
67
- import "../chunk-7CTIUCQ4.js";
67
+ import "../chunk-UOAYS72M.js";
68
+ import "../chunk-YEFFHORB.js";
68
69
  export {
69
70
  DEFAULT_SANDBOX_RESOURCES,
70
71
  ENV_TOTAL_MAX_BYTES,
@@ -1,3 +1,8 @@
1
+ import {
2
+ generateInviteToken,
3
+ isInviteTokenShape,
4
+ validateInviteToken
5
+ } from "../chunk-DJ4VJIH5.js";
1
6
  import {
2
7
  INVITATION_EXPIRY_DAYS,
3
8
  generateInvitationToken,
@@ -7,11 +12,6 @@ import {
7
12
  parseInvitationPermission,
8
13
  renderInvitationEmail
9
14
  } from "../chunk-2DRYTJHI.js";
10
- import {
11
- generateInviteToken,
12
- isInviteTokenShape,
13
- validateInviteToken
14
- } from "../chunk-DJ4VJIH5.js";
15
15
  import {
16
16
  ASSIGNABLE_WORKSPACE_ROLES,
17
17
  ORGANIZATION_ROLES,
@@ -1,3 +1,7 @@
1
+ import {
2
+ SeatLimitError
3
+ } from "../chunk-MEUNTJL5.js";
4
+ import "../chunk-DJ4VJIH5.js";
1
5
  import {
2
6
  generateInvitationToken,
3
7
  getInvitationExpiresAt,
@@ -5,10 +9,6 @@ import {
5
9
  normalizeInvitationEmail,
6
10
  parseInvitationPermission
7
11
  } from "../chunk-2DRYTJHI.js";
8
- import {
9
- SeatLimitError
10
- } from "../chunk-MEUNTJL5.js";
11
- import "../chunk-DJ4VJIH5.js";
12
12
  import {
13
13
  hasWorkspaceRole
14
14
  } from "../chunk-6XIAPIW6.js";
@@ -1,12 +1,12 @@
1
+ import {
2
+ InviteAcceptPage
3
+ } from "../chunk-VCPZ3HTN.js";
1
4
  import {
2
5
  MembersPanel
3
6
  } from "../chunk-S564OFTL.js";
4
7
  import {
5
8
  InvitationsPanel
6
9
  } from "../chunk-5SXS3YAB.js";
7
- import {
8
- InviteAcceptPage
9
- } from "../chunk-VCPZ3HTN.js";
10
10
  import "../chunk-6XIAPIW6.js";
11
11
  export {
12
12
  InvitationsPanel,
@@ -6,7 +6,7 @@ import {
6
6
  restrictTaxonomy,
7
7
  verifyCapabilityToken,
8
8
  verifyExpiringCapabilityToken
9
- } from "../chunk-YKBDH2UY.js";
9
+ } from "../chunk-WL7XHLDK.js";
10
10
  import {
11
11
  DEFAULT_APP_TOOL_PATHS,
12
12
  DEFAULT_HEADER_NAMES,
@@ -19,18 +19,20 @@ import {
19
19
  readToolArgs
20
20
  } from "../chunk-3EJ6SFJI.js";
21
21
  import "../chunk-S5SRJJQG.js";
22
+ import {
23
+ createAppToolRuntimeExecutor,
24
+ dispatchAppTool,
25
+ outcomeStatus
26
+ } from "../chunk-UOAYS72M.js";
22
27
  import {
23
28
  APP_TOOL_NAMES,
24
29
  ToolInputError,
25
30
  buildAppToolOpenAITools,
26
- createAppToolRuntimeExecutor,
27
31
  customToolToOpenAI,
28
32
  defineAppTool,
29
- dispatchAppTool,
30
33
  findCustomTool,
31
- isAppToolName,
32
- outcomeStatus
33
- } from "../chunk-7CTIUCQ4.js";
34
+ isAppToolName
35
+ } from "../chunk-YEFFHORB.js";
34
36
  export {
35
37
  APP_TOOL_NAMES,
36
38
  DEFAULT_APP_TOOL_PATHS,
@@ -0,0 +1,83 @@
1
+ import { JudgeVerdict } from '@tangle-network/agent-eval';
2
+
3
+ /**
4
+ * Trust gate — decides whether an ensemble's scores are allowed to be BELIEVED,
5
+ * one level up from {@link aggregateJudgeVerdicts} (which only reduces ONE
6
+ * artifact's raters to a composite). A composite is a number; this is the check
7
+ * that the number means anything. It is the code "Enforced by" for the
8
+ * measurement-validation skill's after-gate ("is this result allowed to be
9
+ * believed").
10
+ *
11
+ * Three checks, each fail-loud and named in `trustReasons`:
12
+ * (1) inter-rater reliability over the corpus ≥ `irrFloor` — raters that
13
+ * disagree no better than chance carry no signal to optimize against.
14
+ * (2) per-item rater spread ≤ `spreadCeiling` — for EACH item, raters must
15
+ * converge on THAT item.
16
+ * (3) surviving raters per item ≥ `minSurvivors` — a mean over one or two
17
+ * raters is an anecdote, not an ensemble.
18
+ *
19
+ * CRITICAL metric semantics — per-item spread is rater disagreement about the
20
+ * SAME item: `max(score) − min(score)` across the raters that scored THAT item
21
+ * (max over its dimensions), never pooled across different items or across the
22
+ * baseline/candidate sides. Pooling reads a genuine quality gap BETWEEN items as
23
+ * "the raters split" and so trips the gate exactly when the finding is largest —
24
+ * the failure mode the after-gate exists to prevent. The corpus IRR (check 1)
25
+ * leans on the substrate's `interRaterReliability`, whose expected-disagreement
26
+ * denominator already pools across items, so genuine item-to-item variation
27
+ * RAISES reliability rather than lowering it.
28
+ */
29
+
30
+ /** One item's raters: the per-judge verdicts {@link aggregateJudgeVerdicts}
31
+ * reduces, tagged with the item they scored so spread stays within-item. */
32
+ interface TrustItem<D extends string = string> {
33
+ /** Stable item identifier — surfaces in `perItemSpread` and `trustReasons`. */
34
+ itemId: string;
35
+ /** The raters' verdicts for THIS item (one per judge call). A failed judge
36
+ * (`perDimension: null`) is dropped before spread/IRR, never folded as 0. */
37
+ verdicts: readonly JudgeVerdict<D>[];
38
+ }
39
+ /** Thresholds for {@link trustVerdicts}. All overridable; defaults are the
40
+ * conservative after-gate bar. */
41
+ interface TrustThresholds {
42
+ /** Minimum corpus inter-rater reliability (Krippendorff-style α). Below this
43
+ * the raters agree no better than chance. Default 0.2. */
44
+ irrFloor?: number;
45
+ /** Maximum per-item rater spread (`max − min` over a single item's surviving
46
+ * raters, across its dimensions). Above this the raters split ON THAT ITEM.
47
+ * Default 0.5. */
48
+ spreadCeiling?: number;
49
+ /** Minimum surviving (non-failed) raters required per item. Default 3. */
50
+ minSurvivors?: number;
51
+ }
52
+ /** Result of the trust gate. `trustworthy` iff every check passed; `trustReasons`
53
+ * is empty iff `trustworthy`. */
54
+ interface TrustVerdict {
55
+ /** True iff IRR ≥ floor AND every item's spread ≤ ceiling AND every item has
56
+ * ≥ `minSurvivors` surviving raters. */
57
+ trustworthy: boolean;
58
+ /** One entry per FAILED check, each naming its number + the offending value.
59
+ * Empty iff `trustworthy`. */
60
+ trustReasons: string[];
61
+ /** Corpus inter-rater reliability actually measured (the check-1 value). */
62
+ interRaterReliability: number;
63
+ /** Per-item spread (`max − min` over surviving raters, max over dimensions),
64
+ * keyed by `itemId`. The check-2 input, surfaced for drill-down. */
65
+ perItemSpread: Record<string, number>;
66
+ }
67
+ /**
68
+ * Decide whether an ensemble's per-item verdicts are trustworthy enough to
69
+ * believe a lift computed from them. Pure: no LLM, no I/O, no clock, no random —
70
+ * the same `items` + `thresholds` always yield the same verdict.
71
+ *
72
+ * Sibling to {@link aggregateJudgeVerdicts}: that reduces ONE item's raters to a
73
+ * composite; this audits the raters ACROSS items and reports whether the
74
+ * composites are believable. Run it on the corpus of held-out items before
75
+ * reporting any lift over their scores.
76
+ *
77
+ * @throws if `items` is empty — an empty corpus has no measurable trust, and a
78
+ * silent `trustworthy: true` over zero evidence is the exact lie the gate
79
+ * exists to refuse.
80
+ */
81
+ declare function trustVerdicts<D extends string>(items: readonly TrustItem<D>[], thresholds?: TrustThresholds): TrustVerdict;
82
+
83
+ export { type TrustItem as T, type TrustThresholds as a, type TrustVerdict as b, trustVerdicts as t };
@@ -0,0 +1,268 @@
1
+ /**
2
+ * The reviewable work-product contract — the one durable object every Tangle
3
+ * agent product converges on: an artifact plus its evidence map (source→field
4
+ * lineage), exceptions, quality checks, version history, and run provenance,
5
+ * produced by an agent and signed off by a professional.
6
+ *
7
+ * Import-free and client-safe by construction: the queue projection and the
8
+ * React surfaces re-validate these shapes at JSON boundaries, so every type
9
+ * and codec here must load in a browser bundle. Every domain word — artifact
10
+ * `kind`, evidence `target`, exception `kind`, check `name`, `scopeKey`
11
+ * format — is a STRING PARAMETER validated against product-supplied
12
+ * vocabularies in the tool layer; nothing domain-specific is baked here.
13
+ */
14
+ /** Stable pointer at one version of one work product. */
15
+ interface WorkProductRef {
16
+ id: string;
17
+ version: number;
18
+ }
19
+ type WorkProductStatus = 'draft' | 'blocked' | 'ready' | 'changes_requested' | 'approved' | 'superseded';
20
+ /** Runtime guard for re-validating a status read off a JSON boundary. */
21
+ declare function isWorkProductStatus(value: unknown): value is WorkProductStatus;
22
+ /** Define the reviewable artifact body with its kind, sources, and structured field map */
23
+ interface WorkProductArtifact {
24
+ /** PARAMETER: 'return_package' | 'redline' | 'outreach_campaign' — validated
25
+ * against the product's `artifactKinds` vocabulary at submit. */
26
+ kind: string;
27
+ title: string;
28
+ /** Vault/object-store ref for the rendered document (large bodies). */
29
+ path?: string;
30
+ /** Inline body when small (markdown/JSON). */
31
+ content?: string;
32
+ mediaType?: string;
33
+ /** Diff-first products (legal): the source document the artifact redlines. */
34
+ baseline?: {
35
+ path?: string;
36
+ content?: string;
37
+ };
38
+ /** The structured field map lineage targets anchor to (tax: form-line ids). */
39
+ fields?: Record<string, unknown>;
40
+ }
41
+ /** Point into a source document: page, free-form range, verbatim quote */
42
+ interface EvidenceLocator {
43
+ page?: number;
44
+ /** 'L120-L134' | 'B7' | '¶4' — free-form, non-empty when present. */
45
+ range?: string;
46
+ /** Verbatim supporting quote from the source. */
47
+ quote?: string;
48
+ }
49
+ /** One lineage row: a source document location supporting one artifact claim */
50
+ interface EvidenceEntry {
51
+ /** Agent-supplied stable id — the same id re-emitted is an upsert/replace. */
52
+ id: string;
53
+ /** Vault path / attachment id / object-store key of the SOURCE document. */
54
+ sourceRef: string;
55
+ locator: EvidenceLocator;
56
+ /** Artifact field/claim the evidence supports: '1040.line_9' |
57
+ * 'clause:indemnification' | 'icp.employee_count' — product vocabulary. */
58
+ target: string;
59
+ /** The value/assertion at the target. */
60
+ claim: string;
61
+ /** 0..1; absent = unstated (never defaulted). */
62
+ confidence?: number;
63
+ }
64
+ type ExceptionSeverity = 'blocking' | 'material' | 'advisory';
65
+ /** One flagged problem with the work product, resolvable by agent or reviewer */
66
+ interface ExceptionEntry {
67
+ id: string;
68
+ severity: ExceptionSeverity;
69
+ /** PARAMETER: 'missing_document' | 'inconsistent_source' | … — validated
70
+ * against the product's `exceptionKinds` vocabulary. */
71
+ kind: string;
72
+ message: string;
73
+ /** Affected artifact targets. */
74
+ targets?: string[];
75
+ resolved: boolean;
76
+ resolvedBy?: 'agent' | 'reviewer';
77
+ resolutionNote?: string;
78
+ }
79
+ /** Unresolved blocking exceptions are what park a work product in `blocked`. */
80
+ declare function unresolvedBlockingExceptions(exceptions: readonly ExceptionEntry[]): ExceptionEntry[];
81
+ /** One named quality verdict on the work product, tagged with who computed it */
82
+ interface QualityCheck {
83
+ id: string;
84
+ /** Product vocabulary: 'totals_reconcile', 'evidence_coverage', … */
85
+ name: string;
86
+ passed: boolean;
87
+ detail?: string;
88
+ /** agent self-report | shell-computed | eval-ensemble verdict. */
89
+ source: 'agent' | 'platform' | 'judge';
90
+ }
91
+ /** The audit triple binding a work product to the exact configuration and run
92
+ * that produced it. `profileHash` is agent-eval's `agentProfileHash()` of the
93
+ * EXACT shipped profile — the same hash that keys scorecard cells, so a
94
+ * reviewer can see the measured backtest history of the configuration that
95
+ * produced the document. */
96
+ interface WorkProductProvenance {
97
+ profileHash: string;
98
+ /** Chat turnId or mission-step run id. */
99
+ runId: string;
100
+ /** Back-filled from the usage receipt / serving-model header at turn
101
+ * completion — only the completed turn knows what actually served. */
102
+ servingModels: string[];
103
+ sessionId?: string;
104
+ missionRef?: {
105
+ missionId: string;
106
+ stepId: string;
107
+ };
108
+ costUsd?: number;
109
+ producedAt: number;
110
+ }
111
+ /** The product-resolved backtest summary for one profile hash (from its own
112
+ * eval artifacts via agent-eval's `loadScorecard`) — the shell defines only
113
+ * this TYPE and the `ProvenanceStamp` slot that renders it. */
114
+ interface ProfileBacktestSummary {
115
+ profileHash: string;
116
+ /** Backtest cases behind the composite. */
117
+ cases: number;
118
+ composite: number;
119
+ /** The eval-campaign trust gate's verdict on whether the composite is
120
+ * allowed to be believed; 'fail' renders as "quality: unverified". */
121
+ trust: 'pass' | 'fail';
122
+ trustReasons: string[];
123
+ }
124
+ /** Frozen milestone row for one version of the work product */
125
+ interface WorkProductVersionEntry {
126
+ version: number;
127
+ status: WorkProductStatus;
128
+ provenance: WorkProductProvenance;
129
+ /** Frozen snapshot ref of this version's body (object-store key) — the
130
+ * DiffView input for vN-1 vs vN. */
131
+ artifactPath?: string;
132
+ reviewedBy?: string;
133
+ reviewNote?: string;
134
+ at: number;
135
+ }
136
+ /** Define the durable work product row accumulating artifact, lineage, exceptions, checks, and history */
137
+ interface WorkProductRecord {
138
+ /** Minted server-side; the model NEVER supplies ids — it addresses work by
139
+ * `scopeKey`. */
140
+ id: string;
141
+ workspaceId: string;
142
+ /** The chat thread that drives it (chat stays first). */
143
+ threadId: string | null;
144
+ /** Product engagement key: 'return:acme:2025' | 'contract:acme-msa' |
145
+ * 'campaign:cpa-pilots'. */
146
+ scopeKey: string;
147
+ status: WorkProductStatus;
148
+ version: number;
149
+ /** `null` while the draft accumulates (evidence streams in before the
150
+ * artifact arrives); non-null from the submit transition onward. Typed
151
+ * honestly rather than forcing a placeholder artifact on every draft. */
152
+ artifact: WorkProductArtifact | null;
153
+ evidence: EvidenceEntry[];
154
+ exceptions: ExceptionEntry[];
155
+ checks: QualityCheck[];
156
+ provenance: WorkProductProvenance;
157
+ history: WorkProductVersionEntry[];
158
+ createdAt: number;
159
+ updatedAt: number;
160
+ }
161
+ /** Fields a guarded write compares against the values the caller read. An
162
+ * absent field is unguarded. A SQL implementation compares like-for-like
163
+ * scalar columns; the in-memory store does the same. */
164
+ interface WorkProductUpdateGuard {
165
+ status?: WorkProductStatus;
166
+ version?: number;
167
+ }
168
+ /** Fields a guarded write sets when the guard holds. */
169
+ interface WorkProductPatch {
170
+ status?: WorkProductStatus;
171
+ version?: number;
172
+ artifact?: WorkProductArtifact;
173
+ evidence?: EvidenceEntry[];
174
+ exceptions?: ExceptionEntry[];
175
+ checks?: QualityCheck[];
176
+ provenance?: WorkProductProvenance;
177
+ history?: WorkProductVersionEntry[];
178
+ updatedAt?: number;
179
+ }
180
+ /** One audit-trail row, appended after every committed state change. */
181
+ interface WorkProductAuditEvent {
182
+ workProductId: string;
183
+ workspaceId: string;
184
+ /** Machine-readable transition name ('wp.created' | 'wp.evidence' |
185
+ * 'wp.ready' | 'wp.verdict' | …). */
186
+ step: string;
187
+ message: string;
188
+ metadata: Record<string, unknown>;
189
+ at: number;
190
+ }
191
+ /**
192
+ * Persistence seam — the product implements this over its own tables. The
193
+ * invariant the implementation MUST keep: `update` applies `patch` ONLY when
194
+ * every guard field still equals the stored value, and returns `null` when
195
+ * the guard misses — a typed conflict, never a clobber.
196
+ */
197
+ interface WorkProductStorePort {
198
+ load(id: string): Promise<WorkProductRecord | null>;
199
+ /** The scope's single OPEN accumulator row — status `draft` or `blocked` —
200
+ * or null when the scope has only reviewed/terminal rows (or none). The
201
+ * `changes_requested` row is found via {@link listByWorkspace}; reopening
202
+ * it is the service's job. */
203
+ findDraft(workspaceId: string, scopeKey: string): Promise<WorkProductRecord | null>;
204
+ listByWorkspace(workspaceId: string, opts?: {
205
+ status?: WorkProductStatus[];
206
+ }): Promise<WorkProductRecord[]>;
207
+ /** `extras` are opaque product-column values written in the SAME statement
208
+ * as the record (single-write creation), or ignored when the table has no
209
+ * extra columns. */
210
+ insert(record: WorkProductRecord, extras?: Record<string, unknown>): Promise<WorkProductRecord>;
211
+ /** CAS: apply `patch` ONLY when guard fields equal stored values; null on a
212
+ * miss — typed conflict, never a clobber. */
213
+ update(id: string, guard: WorkProductUpdateGuard, patch: WorkProductPatch): Promise<WorkProductRecord | null>;
214
+ appendEvent(event: WorkProductAuditEvent): Promise<void>;
215
+ }
216
+ /** Validation result whose failure names the exact field, so a tool layer can
217
+ * hand the model a correctable error it can act on. */
218
+ type WorkProductParseResult<T> = {
219
+ ok: true;
220
+ value: T;
221
+ } | {
222
+ ok: false;
223
+ field: string;
224
+ error: string;
225
+ };
226
+ /** Validate one raw evidence entry field-by-field. `path` prefixes the failure
227
+ * field name (e.g. `entries[3]`) so batched calls name the exact offender. */
228
+ declare function parseEvidenceInput(raw: unknown, path?: string): WorkProductParseResult<EvidenceEntry>;
229
+ /** Validate one raw exception entry field-by-field. Kind MEMBERSHIP in the
230
+ * product vocabulary is the tool layer's check (it owns the config). */
231
+ declare function parseExceptionInput(raw: unknown, path?: string): WorkProductParseResult<ExceptionEntry>;
232
+ /** Validate a raw artifact. Kind MEMBERSHIP in `artifactKinds` is the tool
233
+ * layer's check. An artifact must carry a body: at least one of `path`,
234
+ * `content`, or `fields`. */
235
+ declare function parseArtifactInput(raw: unknown, path?: string): WorkProductParseResult<WorkProductArtifact>;
236
+ /** Agent self-reported check input for `submit_work_product` (persisted with
237
+ * `source: 'agent'`; `platform`/`judge` sources are never model-suppliable). */
238
+ interface AgentCheckInput {
239
+ id: string;
240
+ name: string;
241
+ passed: boolean;
242
+ detail?: string;
243
+ }
244
+ /** Validate one agent self-check ensuring identifiers, verdict flag, and optional detail are well formed */
245
+ declare function parseAgentCheckInput(raw: unknown, path?: string): WorkProductParseResult<AgentCheckInput>;
246
+ /**
247
+ * The persisted `type:'work_product'` transcript anchor — the chat card that
248
+ * keeps chat the driver surface for review. The PLATFORM writes it on the
249
+ * ready transition (and updates it on a verdict); no prompt ever teaches an
250
+ * agent to author one. `/chat-store` aliases this as `ChatWorkProductPart` in
251
+ * its stored-part union, exactly like the `interaction`/`plan` members.
252
+ */
253
+ interface WorkProductPersistedPart {
254
+ type: 'work_product';
255
+ ref: WorkProductRef;
256
+ kind: string;
257
+ title: string;
258
+ status: WorkProductStatus;
259
+ }
260
+ /** Project the transcript anchor part from a record. Requires the submitted
261
+ * artifact (the anchor is written on the ready transition, after which
262
+ * `artifact` is always non-null); falls back to the scopeKey label for
263
+ * defensive callers on an accumulating draft. */
264
+ declare function workProductToPersistedPart(record: WorkProductRecord): WorkProductPersistedPart;
265
+ /** Re-validate a stored/wire part into the typed anchor; null for junk. */
266
+ declare function persistedPartToWorkProduct(part: Record<string, unknown>): WorkProductPersistedPart | null;
267
+
268
+ export { type AgentCheckInput as A, type EvidenceEntry as E, type ProfileBacktestSummary as P, type QualityCheck as Q, type WorkProductArtifact as W, type EvidenceLocator as a, type ExceptionEntry as b, type ExceptionSeverity as c, type WorkProductAuditEvent as d, type WorkProductParseResult as e, type WorkProductPatch as f, type WorkProductPersistedPart as g, type WorkProductProvenance as h, type WorkProductRecord as i, type WorkProductRef as j, type WorkProductStatus as k, type WorkProductStorePort as l, type WorkProductUpdateGuard as m, type WorkProductVersionEntry as n, isWorkProductStatus as o, parseAgentCheckInput as p, parseArtifactInput as q, parseEvidenceInput as r, parseExceptionInput as s, persistedPartToWorkProduct as t, unresolvedBlockingExceptions as u, workProductToPersistedPart as w };