wicked-crew-api-types 0.20.0 → 0.25.0

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 (2) hide show
  1. package/index.d.ts +315 -0
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -255,6 +255,33 @@ export interface AgentSession {
255
255
  * `GET /campaigns`.
256
256
  */
257
257
  group_label?: string;
258
+ /**
259
+ * When this run was LAUNCHED — unix SECONDS (home command-center run metrics; api-types 0.24.0).
260
+ * Daemon-derived at DTO assembly on BOTH `GET /runs` and `GET /runs/:id` from the `run.launched`
261
+ * audit entry's timestamp (the daemon's durable system-of-record for run provenance — task #88),
262
+ * joined exactly like {@link retry_of} / {@link guidance} and hydrated from the SAME trail scan
263
+ * at boot, so it survives a daemon restart.
264
+ *
265
+ * This is the ONE launch instant the daemon records: "created" and "started" are the SAME event
266
+ * here — the engine's `AgentSession` (wicked-core `domain.rs`) carries no launch time, so there
267
+ * is no separate queued-vs-started split to expose. Unlocks time-bucketed KPI deltas and a real
268
+ * 7/30/90-day range on the home dashboard.
269
+ *
270
+ * ABSENT — never `null`, never fabricated — when the daemon has no `run.launched` entry for the
271
+ * run: a run launched OFF the `POST /runs` path (a repo's onboarding run, a campaign's own
272
+ * DAG-node runs), a run predating this field, or a `--db`-isolated daemon reading a trail that
273
+ * never saw the launch. Read with `typeof === 'number'`; a bucketed KPI or a 7/30/90-day range
274
+ * must EXCLUDE an undated run, never date it with a fabricated now.
275
+ *
276
+ * COST (deferred, not faked): a per-run cost/spend figure is deliberately NOT joined onto this
277
+ * DTO. Cost exists only on the per-unit {@link CliUsageEvent} (`costUsd`), streamed over `/ws`
278
+ * and never accumulated per run daemon-side — a reliable per-run total would require replaying
279
+ * the durable event log per run on this hot path (the unbounded cost the GET /runs delivery-cache
280
+ * architecture forbids) or a new live cliUsage accumulator plus a durable per-run store. A burn
281
+ * chart should sum `cliUsage.costUsd` from the live `/ws` stream (or `GET /runs/:id/events`) for
282
+ * now; a joined `AgentSession.cost` is a follow-up once that store exists.
283
+ */
284
+ created_at?: number;
258
285
  }
259
286
 
260
287
  /** An ordered unit of work within a run (`WorkUnit`). */
@@ -448,6 +475,16 @@ export interface GateDecision {
448
475
  amend?: string;
449
476
  }
450
477
 
478
+ /**
479
+ * Body of `POST /runs/:id/reassign` — the manual operator lever that reassigns a wedged run's
480
+ * cursor unit through the same engine path the stall-watchdog's automatic escalation uses
481
+ * (crew#442). `cli` omitted lets the engine's council re-pick the seat; when present it must be
482
+ * a seat in the run's own pool (`SessionView.clis`) or the route answers 400.
483
+ */
484
+ export interface ReassignRequest {
485
+ cli?: string;
486
+ }
487
+
451
488
  /**
452
489
  * A CoreEvent frame as delivered verbatim over `/ws` — a tagged-JSON object
453
490
  * discriminated on `type` (wicked-core-ts `event_to_json`). The named optional
@@ -1125,6 +1162,21 @@ export interface ConformanceRule {
1125
1162
  obligations?: string[];
1126
1163
  /** The frozen acceptance-criteria text (becomes a claim's `criteria` when the rule decides a gate). */
1127
1164
  criteria?: string;
1165
+ /**
1166
+ * Unix-SECONDS timestamp of when this rule FIRST entered the store — the "added" time the Steering
1167
+ * surface sorts + date-filters on (NOT the latest-edit time), stamped once by the engine on first
1168
+ * create and preserved across updates (api-types 0.23.0).
1169
+ *
1170
+ * WIRED-BUT-PENDING A CORE-TS BUMP: the field exists on the engine's `ConformanceRule`
1171
+ * (wicked-core `conformance.rs`, serialized with `skip_serializing_if = Option::is_none`), but it
1172
+ * landed AFTER the published `core-ts-v0.7.16` this daemon builds against — so a rule served by
1173
+ * the current binding carries NO `created_at`. The daemon passes the field through verbatim
1174
+ * (`listConformanceRules` returns the parsed rows unchanged), so it begins flowing the moment
1175
+ * crew re-pins to a core-ts that includes it — no daemon change needed. ABSENT — never
1176
+ * fabricated — on any rule the engine did not stamp (pre-field rows, and every row from a
1177
+ * pre-bump binding), so a `since`/`until` filter cannot assert an undated rule in range.
1178
+ */
1179
+ created_at?: number;
1128
1180
  }
1129
1181
 
1130
1182
  /** Facet query for `GET /governance/rules/preview`. All fields are optional. */
@@ -1160,6 +1212,21 @@ export interface RuleBrowseQuery {
1160
1212
  * contradict, and picking a winner silently would answer a question the caller didn't ask).
1161
1213
  */
1162
1214
  include_retired?: 'true' | 'false';
1215
+ /**
1216
+ * Inclusive LOWER date bound (api-types 0.23.0): keep only rules with `created_at >= since`.
1217
+ * Unix SECONDS, a non-negative integer (a present-but-non-integer value is a 400). Applied
1218
+ * server-side over the listed rows, alongside the facet filters. A rule with NO `created_at`
1219
+ * is EXCLUDED whenever `since` (or `until`) is set — see {@link ConformanceRule.created_at}: on
1220
+ * a pre-bump core-ts binding NO rule carries the field, so this filter narrows to empty until the
1221
+ * engine surfaces it. Omitted ⇒ no lower bound.
1222
+ */
1223
+ since?: string;
1224
+ /**
1225
+ * Inclusive UPPER date bound (api-types 0.23.0): keep only rules with `created_at <= until`.
1226
+ * Same units/validation/undated-exclusion as {@link RuleBrowseQuery.since}. Omitted ⇒ no upper
1227
+ * bound.
1228
+ */
1229
+ until?: string;
1163
1230
  }
1164
1231
 
1165
1232
  // ── Steering management (STEERING program) ──────────────────────────────────────
@@ -1442,6 +1509,66 @@ export interface ImportEvalCorpusResponse {
1442
1509
  embedded: boolean;
1443
1510
  }
1444
1511
 
1512
+ // ── Eval run history (crew-side EvalRunStore) — the Evals section's real list ───
1513
+
1514
+ /**
1515
+ * One steering type's slice of an eval run's rollup — the same four counts as
1516
+ * {@link GovernanceEvalSummary}, derived from the run's results grouped by `sample.steering_type`.
1517
+ * This is what makes "which steering type carries the gaps" a stored field, not a per-request
1518
+ * recompute over the full results.
1519
+ */
1520
+ export interface EvalRunPerTypeCount {
1521
+ total: number;
1522
+ caught: number;
1523
+ gaps: number;
1524
+ false_positives: number;
1525
+ }
1526
+
1527
+ /**
1528
+ * One PERSISTED eval run — the listable rollup row (`GET /testing/evals`). A run is one
1529
+ * `POST /testing/evals/run` and its report, stamped with WHO ran it, WHAT it ran against, and
1530
+ * WHEN, so the Evals section is a real history instead of a single session-local report that a
1531
+ * reload loses. The per-sample `results` are NOT here — they live on {@link EvalRunDetail} (the
1532
+ * drilldown), so listing the history stays cheap no matter how large a custom corpus is.
1533
+ *
1534
+ * Evals take no repo/project (they judge a STORE, not a workspace), so this is a single GLOBAL
1535
+ * feed per daemon — unlike recon campaign runs, which file into projects.
1536
+ */
1537
+ export interface EvalRunSummary {
1538
+ /** Server-minted run id. */
1539
+ id: string;
1540
+ /** Unix SECONDS the run was recorded (the crew `created_at` convention — see AgentSession). */
1541
+ created_at: number;
1542
+ /** The authenticated actor who ran it. */
1543
+ actor: string;
1544
+ /** The corpus scope (`evals:<name>`), or null for the engine's built-in dev-behaviors corpus. */
1545
+ corpus: string | null;
1546
+ /** The single steering type the run was narrowed to, or null when it ran all seven. */
1547
+ type_filter: SteeringType | null;
1548
+ /** The steering rule store the run was judged against (the daemon's `--db` steering store). */
1549
+ rule_store: string;
1550
+ /** The report's rollup, verbatim ({@link GovernanceEvalSummary}). */
1551
+ summary: GovernanceEvalSummary;
1552
+ /** Per-steering-type rollup, derived from the results — present only for the types the run covered. */
1553
+ per_type: Partial<Record<SteeringType, EvalRunPerTypeCount>>;
1554
+ /** `'facet-only'` when the run degraded to facet matching; null when it ran full-fidelity. */
1555
+ degraded: 'facet-only' | null;
1556
+ }
1557
+
1558
+ /**
1559
+ * One eval run WITH its full per-sample results (`GET /testing/evals/:id`) — the drilldown behind a
1560
+ * history row. `results` is the same verbatim {@link GovernanceEvalResult} array the run's original
1561
+ * `POST /testing/evals/run` returned, so the existing report view renders it unchanged.
1562
+ */
1563
+ export interface EvalRunDetail extends EvalRunSummary {
1564
+ results: GovernanceEvalResult[];
1565
+ }
1566
+
1567
+ /** The `GET /testing/evals` 200 body — the eval run history, newest first. */
1568
+ export interface ListEvalRunsResponse {
1569
+ runs: EvalRunSummary[];
1570
+ }
1571
+
1445
1572
  /**
1446
1573
  * The `POST /testing/recon` request body (api-types 0.15.0) — the Testing page's campaign-recon
1447
1574
  * trigger. `problem` is the recon brief, passed to every launched run VERBATIM (the client owns
@@ -2755,3 +2882,191 @@ export interface DiagnosticsResponse {
2755
2882
  recentErrors: DiagnosticsRecentError[];
2756
2883
  acp: AcpDiagnostics;
2757
2884
  }
2885
+
2886
+ // ── Memory proposal queue (DES-MEM-FACETED-001 §5.0, api-types 0.21.0) ─────────
2887
+
2888
+ /**
2889
+ * A proposal's lifecycle state. A proposal is INERT while `pending` (never recalled/applied);
2890
+ * `approve` promotes its payload to the active store and marks it `approved`, `reject` marks it
2891
+ * `rejected`.
2892
+ */
2893
+ export type ProposalState = 'pending' | 'approved' | 'rejected';
2894
+
2895
+ /**
2896
+ * One entry in the estate proposal queue — a type-generic, inert write agents submit and operators
2897
+ * decide (estate #162). The shape is the estate MCP `proposal.list` wire form verbatim.
2898
+ */
2899
+ export interface Proposal {
2900
+ /** Stable proposal-node id. */
2901
+ id: string;
2902
+ /** `"memory"` | `"policy:<steering_type>"` | future — the router key `approve` promotes by. */
2903
+ kind_type: string;
2904
+ /** The proposed content (a memory body, a policy rule, …). Opaque here; narrowed by `kind_type`. */
2905
+ payload: unknown;
2906
+ /** Agent-declared orthogonal facets (axis → value). */
2907
+ facets: Record<string, string>;
2908
+ /** Run/unit/agent attribution — AUTHORITY-STAMPED by the estate MCP from its launch env, never
2909
+ * taken from the submitter. Empty when the server had no `WICKED_RUN_*` env. */
2910
+ provenance: Record<string, string>;
2911
+ state: ProposalState;
2912
+ /** Unix seconds. */
2913
+ created_at: number;
2914
+ }
2915
+
2916
+ /** `GET /proposals` query filters — both optional; omitting a filter lists across that dimension. */
2917
+ export interface ListProposalsQuery {
2918
+ kind_type?: string;
2919
+ state?: ProposalState;
2920
+ }
2921
+
2922
+ /** `GET /proposals` → 200. */
2923
+ export interface ListProposalsResponse {
2924
+ proposals: Proposal[];
2925
+ }
2926
+
2927
+ /**
2928
+ * The result of landing an approved POLICY proposal as a steering rule (DES-MEM-FACETED-001 §5.2).
2929
+ * estate performs no rules-write for a policy proposal (the AW-11 invariant) — it hands the payload
2930
+ * to crew, the one governed rules-write path, which shapes a `ConformanceRule` and upserts it. Like
2931
+ * the steering-author landing (crew#388) the estate decision (approve) stands regardless, so a
2932
+ * landing that could not complete reports `outcome:"failed"` with a loud, operator-readable `error`
2933
+ * (recoverable by hand via `POST /governance/rules`) rather than turning the approve into a 500.
2934
+ */
2935
+ export interface PolicyLandingResult {
2936
+ /** `landed` = the steering rule is in the store; `failed` = the proposal is approved but no rule
2937
+ * was written — `error` says why. */
2938
+ outcome: 'landed' | 'failed';
2939
+ /** The upserted rule's id (deterministic `proposal:<proposalId>`, idempotent on replay). Present on `landed`. */
2940
+ ruleId?: string;
2941
+ /** The steering type derived from the proposal's `kind_type` (`policy:<type>`). Present on `landed`. */
2942
+ steering_type?: SteeringType;
2943
+ /** Present iff `outcome:"failed"` — the loud reason the rule did not land. */
2944
+ error?: string;
2945
+ }
2946
+
2947
+ /**
2948
+ * `POST /proposals/:id/approve` → 200. A MEMORY proposal is `promoted` (its payload is now an
2949
+ * active memory, `active_id`) and is complete. A POLICY proposal is `handed_off` — its `payload`
2950
+ * (`{ rule, severity }`) is still returned verbatim, and `landing` now reports the steering rule
2951
+ * crew created from it (`landing.outcome:"landed"` with the `ruleId`), or the loud reason it could
2952
+ * not (`landing.outcome:"failed"`). `landing` is absent only from responses served by a daemon
2953
+ * predating the policy→steering landing (forward-additive, DES-MEM-FACETED-001 §5.2).
2954
+ */
2955
+ export type ApproveProposalResponse =
2956
+ | { outcome: 'promoted'; active_id: string }
2957
+ | { outcome: 'handed_off'; payload: unknown; landing?: PolicyLandingResult };
2958
+
2959
+ /** `POST /proposals/:id/reject` → 200. */
2960
+ export interface RejectProposalResponse {
2961
+ ok: true;
2962
+ }
2963
+
2964
+ // ── Memory management (governed-knowledge surface, DES-MEM-FACETED-001, api-types 0.22.0) ──────
2965
+ //
2966
+ // The studio's surface for managing the memories that ALREADY exist in the operator store — the
2967
+ // counterpart to the proposal queue (which decides learnings not yet stored). Backed by the estate
2968
+ // MCP memory tools (memory.recall / memory.coverage / memory.erase) exposed over crew's /api/v1.
2969
+ // The granularity is estate's, surfaced honestly: browse is query-based (no "list all"), and
2970
+ // retire is SUBTREE-scoped (no per-id delete).
2971
+
2972
+ /**
2973
+ * One memory as browsed from the store (`GET /memory`, from estate `memory.recall`).
2974
+ *
2975
+ * estate `memory.recall` is query-based and token-budgeted — there is NO "list all" — and returns
2976
+ * `{ memory_id, scope, content, tier, score }` per item. It does NOT surface per-item `facets`, so
2977
+ * `facets` is presently always `{}` (kept in the shape for forward-compatibility and to mirror
2978
+ * `Proposal.facets`); `score` is the recall relevance score, absent when estate omits it.
2979
+ */
2980
+ export interface MemoryItem {
2981
+ /** Stable memory-node id (estate `memory_id`). */
2982
+ id: string;
2983
+ /** The memory body. */
2984
+ content: string;
2985
+ /** Tier: `working` | `episodic` | `semantic` | `procedural` | `archival`. */
2986
+ tier: string;
2987
+ /** The memory's own hierarchical scope path (slash-separated `kind:id` segments; `""` = root). */
2988
+ scope: string;
2989
+ /** Orthogonal facets (axis → value) the memory is tagged with. Populated by estate `memory.list`
2990
+ * (the management browse) — this is what powers the surface's facet filter. `{}` for an
2991
+ * unfaceted memory (and for a `memory.recall`-sourced item, which carries no facets). */
2992
+ facets: Record<string, string>;
2993
+ /** Relevance score — only present on a `memory.recall` item; `memory.list` (the browse) is not
2994
+ * relevance-ranked, so it is absent there. */
2995
+ score?: number;
2996
+ /**
2997
+ * Unix-SECONDS timestamp of when this memory FIRST entered the store — the "added" time the
2998
+ * governance surface sorts + date-filters on (api-types 0.23.0). Populated from estate
2999
+ * `memory.list`, which returns `created_at` per item; ABSENT — never fabricated — on a memory
3000
+ * whose creation time the store did not report (and on a `memory.recall`-sourced item, which
3001
+ * carries none). Additive: absence is the one spelling of "unknown", so a `since`/`until` filter
3002
+ * cannot assert an undated memory in range.
3003
+ */
3004
+ created_at?: number;
3005
+ }
3006
+
3007
+ /**
3008
+ * `GET /memory` query filters. All optional. The browse itself lists the COMPLETE in-scope set via
3009
+ * estate `memory.list`; `query`, `facets`, and `limit` are applied server-side as post-filters over
3010
+ * that set (they are NOT a relevance query). `scope_prefix` is the only estate-side argument — a
3011
+ * subtree filter where `""`/omitted matches EVERY memory (the same predicate as retire). `query` is
3012
+ * a case-insensitive CONTENT substring match. `facets` is a JSON-encoded object of axis→value
3013
+ * strings; an item is kept only if it carries every pair. `limit` caps the returned ROW count.
3014
+ */
3015
+ export interface ListMemoriesQuery {
3016
+ /** Case-insensitive content substring filter over the complete set. */
3017
+ query?: string;
3018
+ scope_prefix?: string;
3019
+ /** JSON-encoded `Record<string, string>` (axis→value); a malformed value is a 400. */
3020
+ facets?: string;
3021
+ /** Positive integer; caps the returned row count. */
3022
+ limit?: string;
3023
+ /**
3024
+ * Inclusive LOWER date bound (api-types 0.23.0): keep only memories with `created_at >= since`.
3025
+ * Unix SECONDS, a non-negative integer (a present-but-non-integer value is a 400). Applied
3026
+ * server-side over the loaded set, alongside `query`/`facets`. A memory with NO `created_at`
3027
+ * is EXCLUDED whenever `since` (or `until`) is set — an unknown creation time is not asserted
3028
+ * in range. Omitted ⇒ no lower bound.
3029
+ */
3030
+ since?: string;
3031
+ /**
3032
+ * Inclusive UPPER date bound (api-types 0.23.0): keep only memories with `created_at <= until`.
3033
+ * Same units/validation/undated-exclusion as {@link ListMemoriesQuery.since}. Omitted ⇒ no
3034
+ * upper bound.
3035
+ */
3036
+ until?: string;
3037
+ }
3038
+
3039
+ /** `GET /memory` → 200. */
3040
+ export interface ListMemoriesResponse {
3041
+ memories: MemoryItem[];
3042
+ }
3043
+
3044
+ /** `GET /memory/coverage` query — an optional subtree filter (`""`/omitted = global totals). */
3045
+ export interface MemoryCoverageQuery {
3046
+ scope_prefix?: string;
3047
+ }
3048
+
3049
+ /**
3050
+ * `GET /memory/coverage` → 200 (estate `memory.coverage`). Memory-node counts, optionally scoped to
3051
+ * a subtree: `total`, plus per-tier and per-kind breakdowns.
3052
+ */
3053
+ export interface MemoryCoverageResponse {
3054
+ total: number;
3055
+ by_tier: Record<string, number>;
3056
+ by_kind: Record<string, number>;
3057
+ }
3058
+
3059
+ /**
3060
+ * `POST /memory/retire` body. Retire is SUBTREE-scoped, never per-id: estate `memory.erase`
3061
+ * hard-deletes EVERY memory whose scope equals or descends from `scope_prefix`. `scope_prefix` is
3062
+ * required and must be non-empty (estate refuses a total wipe) — the surface must show the operator
3063
+ * the whole subtree it will remove, not a single row.
3064
+ */
3065
+ export interface RetireMemoryBody {
3066
+ scope_prefix: string;
3067
+ }
3068
+
3069
+ /** `POST /memory/retire` → 200. The number of memories the subtree wipe deleted. */
3070
+ export interface RetireMemoryResponse {
3071
+ erased: number;
3072
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-crew-api-types",
3
- "version": "0.20.0",
3
+ "version": "0.25.0",
4
4
  "description": "The wire contract of the wicked-crew daemon's /api/v1 REST surface and /ws CoreEvent frames \u2014 types only, zero runtime",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",