@akasecurity/ai-tc-claude-code 0.9.9 → 0.9.11

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/scripts/intro.js CHANGED
@@ -492,7 +492,7 @@ var require_ignore = __commonJS({
492
492
  });
493
493
 
494
494
  // src/intro.ts
495
- import { readFileSync as readFileSync13 } from "fs";
495
+ import { readFileSync as readFileSync15 } from "fs";
496
496
 
497
497
  // ../../packages/schema/src/exception-scope.ts
498
498
  var MINUTE_MS = 6e4;
@@ -20379,13 +20379,11 @@ var FindingGroup = external_exports.object({
20379
20379
  latestDetectedAt: external_exports.iso.datetime(),
20380
20380
  instances: external_exports.array(FindingInstance),
20381
20381
  // Derived from instances' statuses with open-dominates precedence (see
20382
- // buildFindingGroups). Undefined only when no instance carries a status.
20382
+ // foldGroupStatus). Undefined only when no instance carries a status.
20383
20383
  status: FindingStatus.optional(),
20384
- // The distinct people across the WHOLE group, not just the `instances`
20385
- // preview — from the store's whole-group aggregate when it supplies one,
20386
- // else folded from the rows (see buildFindingGroups). Undefined when no
20387
- // instance carries a user, or when the store supplied whole-group folds
20388
- // without one.
20384
+ // The distinct people across the WHOLE group, not just the instances
20385
+ // carried here. Undefined when no instance carries a user, or when the
20386
+ // store supplied whole-group folds without one.
20389
20387
  users: external_exports.array(FindingUser).optional()
20390
20388
  }).meta({ id: "FindingGroup" });
20391
20389
  var FindingStats = external_exports.object({
@@ -20414,20 +20412,30 @@ var FindingFacets = external_exports.object({
20414
20412
  // counted under no value.
20415
20413
  status: external_exports.array(FindingFacetItem),
20416
20414
  // Host tool (attributes.tool_name). Present only on the instance-level
20417
- // reads, which can filter by it; the grouped read omits the dimension
20415
+ // reads, which can filter by it; the type-level read omits the dimension
20418
20416
  // because a group spans tools.
20419
20417
  tool: external_exports.array(FindingFacetItem).optional()
20420
20418
  }).meta({ id: "FindingFacets" });
20421
- var ListGroupedFindingsQuery = external_exports.object({
20419
+ var FindingTypeSummary = FindingGroup.omit({ instances: true, match: true }).meta({
20420
+ id: "FindingTypeSummary"
20421
+ });
20422
+ var MAX_FINDING_TYPES_LIMIT = 100;
20423
+ var ListFindingTypesQuery = external_exports.object({
20422
20424
  // NOTE: severity filters by Severity (critical/high/medium/low), not by
20423
- // FindingAction.
20425
+ // FindingAction. It narrows TYPES: a type's severity is the one its newest
20426
+ // firing version carries, and this list pages types.
20427
+ //
20428
+ // That is NOT a claim the findings of a type share it. A rule can hold several
20429
+ // definition versions at different severities, so a type kept by this filter
20430
+ // can hold findings that individually do not match — see totals.findings on
20431
+ // ListFindingTypesResponse, which counts them all.
20424
20432
  severity: external_exports.array(Severity).optional(),
20425
20433
  subtype: external_exports.array(external_exports.string()).optional(),
20426
20434
  provider: external_exports.array(FindingProvider).optional(),
20427
20435
  action: external_exports.array(FindingAction).optional(),
20428
- // Matches a group's DERIVED status (see FindingGroup.status), not its
20429
- // individual instances' — so a filtered group's Status column always reads
20430
- // one of the requested values.
20436
+ // Matches a type's DERIVED status (see FindingGroup.status), not its
20437
+ // individual findings' — so a filtered row's status always reads one of the
20438
+ // requested values.
20431
20439
  status: external_exports.array(FindingStatus).optional(),
20432
20440
  q: external_exports.string().optional(),
20433
20441
  // Scope to findings whose event carries this session id (the Activity page's
@@ -20437,23 +20445,37 @@ var ListGroupedFindingsQuery = external_exports.object({
20437
20445
  // from a time-scoped page (Activity's range) can carry that scope. Absent
20438
20446
  // means all time — this list has no default window.
20439
20447
  from: external_exports.iso.datetime().optional(),
20440
- // A group or instance id that must appear in the page even when the cursor
20441
- // has already advanced past its sort position. This is what keeps the
20442
- // Findings page's one-shot ?finding= deep link resolving once the list
20443
- // paginates: the target group is appended out of sort order rather than
20444
- // scanning forward for it. Never affects totals, facets or the cursor.
20448
+ // A RULE id that must appear in the page even when the cursor has already
20449
+ // advanced past its sort position. This is what keeps the selected type
20450
+ // visible in the list once it paginates: the target is appended out of sort
20451
+ // order rather than scanned forward for. Never affects totals, facets or the
20452
+ // cursor. Unlike the grouped read this replaces, it names a rule only — an
20453
+ // instance id is resolved by `findingInstance`, which is a primary-key seek
20454
+ // and so is not bounded by what any page happens to hold.
20445
20455
  includeId: external_exports.string().optional(),
20446
- groupBy: external_exports.literal("type").optional(),
20447
- limit: external_exports.coerce.number().int().min(1).max(100).optional(),
20456
+ limit: external_exports.coerce.number().int().min(1).max(MAX_FINDING_TYPES_LIMIT).optional(),
20448
20457
  cursor: external_exports.string().optional()
20449
20458
  });
20450
- var ListGroupedFindingsResponse = external_exports.object({
20459
+ var ListFindingTypesResponse = external_exports.object({
20451
20460
  totals: external_exports.object({
20461
+ // Findings belonging to the matching TYPES — not findings that each match
20462
+ // the filters. The filters here select types, so a type that survives
20463
+ // contributes its whole instanceCount.
20464
+ //
20465
+ // `status` is the one exception, narrowed per finding via
20466
+ // countInstancesByStatus. `severity`, `provider` and `action` are not, so
20467
+ // this can exceed what the instance read reports for the same filters: a
20468
+ // rule whose severity moved between versions is kept on its newest and
20469
+ // still counts its older findings. Narrowing the other three needs
20470
+ // per-dimension counts the aggregate does not carry today.
20452
20471
  findings: external_exports.number().int().nonnegative(),
20453
- groups: external_exports.number().int().nonnegative()
20472
+ // Counts TYPES, which is the unit this read pages. The instance read's
20473
+ // own totals count findings; the two deliberately answer different
20474
+ // questions and are never summed.
20475
+ types: external_exports.number().int().nonnegative()
20454
20476
  }),
20455
20477
  facets: FindingFacets,
20456
- items: external_exports.array(FindingGroup),
20478
+ items: external_exports.array(FindingTypeSummary),
20457
20479
  nextCursor: external_exports.string().nullable(),
20458
20480
  // Present only on session-scoped queries (`sessionId` set): per ruleId, how
20459
20481
  // many times that rule fired in the session's persisted transcript. Findings
@@ -20461,7 +20483,7 @@ var ListGroupedFindingsResponse = external_exports.object({
20461
20483
  // every firing, so the two numbers legitimately differ — this map lets a
20462
20484
  // session-scoped view show both.
20463
20485
  sessionFirings: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()).optional()
20464
- }).meta({ id: "ListGroupedFindingsResponse" });
20486
+ }).meta({ id: "ListFindingTypesResponse" });
20465
20487
  var ApplyFindingActionRequest = external_exports.object({
20466
20488
  // 'quarantined' is system-assigned (see FindingAction) — clients may not set
20467
20489
  // it, so it is excluded from the request contract. The mapping helper
@@ -20490,12 +20512,13 @@ var FindingInstanceDetail = FindingInstance.extend({
20490
20512
  var MAX_FLAT_FINDINGS_LIMIT = 200;
20491
20513
  var ListFindingInstancesQuery = external_exports.object({
20492
20514
  severity: external_exports.array(Severity).optional(),
20493
- // Rule ids, the same vocabulary the grouped list's `subtype` carries.
20515
+ // Rule ids, the same vocabulary the types list's `subtype` carries. Pinning
20516
+ // ONE of them is how the master/detail view scopes its right-hand panel.
20494
20517
  subtype: external_exports.array(external_exports.string()).optional(),
20495
20518
  provider: external_exports.array(FindingProvider).optional(),
20496
20519
  action: external_exports.array(FindingAction).optional(),
20497
20520
  // Matches each instance's OWN derived status (deriveFindingStatus), unlike
20498
- // the grouped query's group-level fold.
20521
+ // the types query's type-level fold.
20499
20522
  status: external_exports.array(FindingStatus).optional(),
20500
20523
  // Exact host-tool names (attributes.tool_name, e.g. 'Bash'). A real filter,
20501
20524
  // where the free-text `q` can only match the rendered "via Bash" label.
@@ -20512,37 +20535,46 @@ var ListFindingInstancesQuery = external_exports.object({
20512
20535
  });
20513
20536
  var ListFindingInstancesResponse = external_exports.object({
20514
20537
  // Instances matching the filters across the whole scope, not just this
20515
- // page — cursor-independent, like the grouped list's totals.
20538
+ // page — cursor-independent, like the types list's totals.
20516
20539
  totals: external_exports.object({ findings: external_exports.number().int().nonnegative() }),
20517
- // Counts in INSTANCES here, where the grouped response counts groups. Each
20540
+ // Counts in INSTANCES here, where the types response counts types. Each
20518
20541
  // dimension still excludes its own filter.
20519
20542
  facets: FindingFacets,
20520
20543
  items: external_exports.array(FindingInstanceDetail),
20521
20544
  nextCursor: external_exports.string().nullable()
20522
20545
  }).meta({ id: "ListFindingInstancesResponse" });
20523
- var FindingLocationFile = external_exports.object({
20524
- // Empty when the instances carried no file path (a prompt or a tool call
20525
- // with no file attribution).
20526
- file: external_exports.string(),
20527
- instanceCount: external_exports.number().int().nonnegative(),
20528
- maxSeverity: Severity,
20529
- latestDetectedAt: external_exports.iso.datetime(),
20530
- // Folded from the instances' derived statuses with the same
20531
- // open-dominates precedence a group uses.
20532
- status: FindingStatus.optional(),
20533
- // Distinct rules seen at this location, capped — the row shows them as
20534
- // chips, and the count is what conveys scale.
20535
- ruleIds: external_exports.array(external_exports.string())
20536
- }).meta({ id: "FindingLocationFile" });
20537
- var FindingLocationRepo = external_exports.object({
20546
+ var FindingLocationSummary = external_exports.object({
20547
+ // Opaque, stable, minted from the pair by encodeLocationId. It exists
20548
+ // because a location's identity is two values and a URL param carries one:
20549
+ // `?loc=` names a location the way `?rule=` names a type. Only ever compared
20550
+ // for EQUALITY — the page's selection check, this read's `includeId`, the
20551
+ // client's page dedupe — never decoded, and never a sort key.
20552
+ id: external_exports.string(),
20538
20553
  /** Empty when the instances carried no repo attribute. */
20539
20554
  repo: external_exports.string(),
20555
+ // Empty when the instances carried no file path (a prompt, or a tool call
20556
+ // with no file attribution). Both halves empty is a real location — usually
20557
+ // the largest one in a store — and is selectable like any other.
20558
+ file: external_exports.string(),
20540
20559
  instanceCount: external_exports.number().int().nonnegative(),
20560
+ // The WORST severity present, not the first row's. It is this list's primary
20561
+ // sort key, so it is also what explains why a row is where it is, and it is
20562
+ // how a reader decides what to open without opening everything.
20541
20563
  maxSeverity: Severity,
20542
20564
  latestDetectedAt: external_exports.iso.datetime(),
20565
+ // Folded from the instances' derived statuses with the same open-dominates
20566
+ // precedence a group uses, so it answers "is anything left to do here" and
20567
+ // not much more: a location holding 1 open among 40 resolved reads like one
20568
+ // holding 40 open. That loss is accepted — the panel beside this list
20569
+ // carries each finding's own status, and instanceCount sits next to the
20570
+ // badge.
20543
20571
  status: FindingStatus.optional(),
20544
- files: external_exports.array(FindingLocationFile)
20545
- }).meta({ id: "FindingLocationRepo" });
20572
+ // Every distinct rule seen at this location, UNCAPPED — so the length is a
20573
+ // tally rather than a sample and a row can say how many there are. Bounded
20574
+ // by the ruleset, not by the store. The view bounds what it DISPLAYS.
20575
+ ruleIds: external_exports.array(external_exports.string())
20576
+ }).meta({ id: "FindingLocationSummary" });
20577
+ var MAX_FINDING_LOCATIONS_LIMIT = 100;
20546
20578
  var ListFindingLocationsQuery = external_exports.object({
20547
20579
  severity: external_exports.array(Severity).optional(),
20548
20580
  subtype: external_exports.array(external_exports.string()).optional(),
@@ -20555,18 +20587,42 @@ var ListFindingLocationsQuery = external_exports.object({
20555
20587
  q: external_exports.string().optional(),
20556
20588
  sessionId: external_exports.string().optional(),
20557
20589
  from: external_exports.iso.datetime().optional(),
20558
- limit: external_exports.coerce.number().int().min(1).max(500).optional()
20590
+ // A LOCATION id (see FindingLocationSummary.id) that must appear in the page
20591
+ // even when the cursor has already advanced past its sort position — the
20592
+ // counterpart of ListFindingTypesQuery.includeId, and needed far more often
20593
+ // here. Selecting a row pushes the URL, which re-renders the server and resets
20594
+ // the client's page cache to page 0; with distinct (repo, file) pairs running
20595
+ // into the thousands, a selection sitting off page 0 is the ordinary case
20596
+ // rather than a deep-link corner. Never affects totals, facets or the cursor.
20597
+ includeId: external_exports.string().optional(),
20598
+ limit: external_exports.coerce.number().int().min(1).max(MAX_FINDING_LOCATIONS_LIMIT).optional(),
20599
+ cursor: external_exports.string().optional()
20559
20600
  });
20560
20601
  var ListFindingLocationsResponse = external_exports.object({
20561
20602
  totals: external_exports.object({
20603
+ // Findings matching the filters across the whole scope. Unlike the types
20604
+ // read's same-named field this needs no caveat: the filters here narrow
20605
+ // per finding, so this is the sum of every row's instanceCount.
20562
20606
  findings: external_exports.number().int().nonnegative(),
20563
- repos: external_exports.number().int().nonnegative(),
20564
- files: external_exports.number().int().nonnegative()
20607
+ // Counts LOCATIONS, the unit this read pages — the number the paginator
20608
+ // states. The facets beside it count FINDINGS (see below); a surface
20609
+ // showing both says which is which.
20610
+ locations: external_exports.number().int().nonnegative()
20565
20611
  }),
20566
- /** Sorted by max severity, then most recent. */
20567
- items: external_exports.array(FindingLocationRepo),
20568
- /** Whether `limit` truncated the repo list. */
20569
- hasMore: external_exports.boolean()
20612
+ // Counts in FINDINGS, where the types response counts types, each dimension
20613
+ // still excluding its own filter. Deliberately not locations: counting those
20614
+ // needs a set of location keys per dimension per value — memory tracking the
20615
+ // store times the vocabulary, in a read whose scan promises flat memory —
20616
+ // and the cheap per-location version is not an approximation but WRONG. A
20617
+ // location holding {claudecode, block} and {codex, warn} would survive
20618
+ // provider=claudecode AND action=warn, under which no single finding
20619
+ // matches, so the facet would contradict the instanceCount this whole view
20620
+ // rests on. Findings also keep the toolbar in the same unit as the page
20621
+ // tally and the panel it sits above.
20622
+ facets: FindingFacets,
20623
+ /** Sorted by max severity, then most recent, then (repo, file). */
20624
+ items: external_exports.array(FindingLocationSummary),
20625
+ nextCursor: external_exports.string().nullable()
20570
20626
  }).meta({ id: "ListFindingLocationsResponse" });
20571
20627
 
20572
20628
  // ../../packages/schema/src/zod/meta.ts
@@ -21731,6 +21787,14 @@ var ControlPlaneErrorBody = external_exports.object({
21731
21787
  message: external_exports.string().optional()
21732
21788
  }).optional()
21733
21789
  });
21790
+ var RemoteFailureKind = external_exports.enum([
21791
+ "unauthorized",
21792
+ "forbidden",
21793
+ "route-absent",
21794
+ "invalid-request",
21795
+ "rejected",
21796
+ "unreachable"
21797
+ ]);
21734
21798
  var AttachDeviceRequest = external_exports.object({
21735
21799
  // This machine's own continuity id, so re-attaching ROTATES the credential
21736
21800
  // on one machine record instead of producing a second one. Client-minted
@@ -21792,6 +21856,26 @@ var AttachTokenResponse = external_exports.union([
21792
21856
  AttachTokenExpired,
21793
21857
  external_exports.object({ status: printable(64) })
21794
21858
  ]);
21859
+ var DeviceCommandKind = external_exports.enum(["shares_rescan"]);
21860
+ var DeviceCommand = external_exports.object({
21861
+ id: printable(128).min(1),
21862
+ kind: DeviceCommandKind,
21863
+ issuedAt: printable(64).min(1),
21864
+ expiresAt: printable(64).min(1)
21865
+ }).strict();
21866
+ var DeviceCommandPollResponse = external_exports.object({ command: DeviceCommand.nullable() });
21867
+ var DeviceCommandFailureReason = external_exports.enum(["scan_failed", "no_projects", "expired"]);
21868
+ var DeviceCommandAckBody = external_exports.discriminatedUnion("outcome", [
21869
+ external_exports.object({
21870
+ outcome: external_exports.literal("reported"),
21871
+ projectsScanned: external_exports.number().int().nonnegative()
21872
+ }).strict(),
21873
+ external_exports.object({
21874
+ outcome: external_exports.literal("failed"),
21875
+ reason: DeviceCommandFailureReason,
21876
+ projectsScanned: external_exports.number().int().nonnegative()
21877
+ }).strict()
21878
+ ]);
21795
21879
 
21796
21880
  // ../../packages/schema/src/zod/registry.ts
21797
21881
  var Namespace = external_exports.string().regex(/^[a-z][a-z0-9-]*$/);
@@ -21958,7 +22042,7 @@ var PackManifest = external_exports.object({
21958
22042
  }).meta({ id: "PackManifest" });
21959
22043
 
21960
22044
  // ../../packages/schema/src/zod/detection.ts
21961
- var OriginEnum = external_exports.enum(["library"]).meta({ id: "OriginEnum" });
22045
+ var OriginEnum = external_exports.enum(["library", "custom"]).meta({ id: "OriginEnum" });
21962
22046
  var DetectionFilterEnum = external_exports.enum(["all", "library", "custom", "customized", "updates"]);
21963
22047
  var LibraryStateEnum = external_exports.enum(["new", "imported", "update"]).meta({ id: "LibraryStateEnum" });
21964
22048
  var DetectionCounts = external_exports.object({
@@ -22153,8 +22237,9 @@ var Event = external_exports.object({
22153
22237
  metadata: EventMetadata.optional()
22154
22238
  }).meta({ id: "Event" });
22155
22239
  var IngestEvent = Event.meta({ id: "IngestEvent" });
22240
+ var INGEST_BATCH_MAX = 100;
22156
22241
  var IngestBatch = external_exports.object({
22157
- events: external_exports.array(IngestEvent).min(1).max(100),
22242
+ events: external_exports.array(IngestEvent).min(1).max(INGEST_BATCH_MAX),
22158
22243
  // Dedup policy for this batch. Id-dedup ALWAYS applies. 'content-hash'
22159
22244
  // additionally rejects any event whose contentHash the store has already
22160
22245
  // recorded — for re-runnable bulk ingest (worktree scan, transcript
@@ -22280,6 +22365,225 @@ var PatchInstalledPackRequest = external_exports.object({
22280
22365
  message: "At least one field must be provided"
22281
22366
  }).meta({ id: "PatchInstalledPackRequest" });
22282
22367
 
22368
+ // ../../packages/schema/src/zod/policy.ts
22369
+ var PolicyScope = external_exports.enum(["global", "repo", "user"]).meta({ id: "PolicyScope" });
22370
+ var PolicyTarget = external_exports.union([external_exports.object({ ruleId: external_exports.string() }), external_exports.object({ category: DetectionCategory })]).meta({ id: "PolicyTarget" });
22371
+ var PolicyKind = external_exports.enum(["builtin", "custom"]).meta({ id: "PolicyKind" });
22372
+ var PolicyProvenance = external_exports.enum(["builtin", "authored"]).meta({ id: "PolicyProvenance" });
22373
+ var Policy = external_exports.object({
22374
+ id: external_exports.guid(),
22375
+ scope: PolicyScope,
22376
+ target: PolicyTarget,
22377
+ action: ActionTaken,
22378
+ enabled: external_exports.boolean().default(true),
22379
+ customKeywords: external_exports.array(external_exports.string()).optional(),
22380
+ // Display name — optional so older policy rows without name still parse.
22381
+ // Added for the findings API (policy.name column migration).
22382
+ name: external_exports.string().optional(),
22383
+ // Whether an AUTHORED policy governs this row's target — not a claim about
22384
+ // which row this is. A producer that collapses several rows onto one target
22385
+ // must carry the marker onto whichever row survives, or the collapse decides
22386
+ // the answer; a survivor may therefore be a built-in expansion still marked
22387
+ // 'authored' because an authored sibling targeted the same thing.
22388
+ // Optional so an older producer — and an older on-disk cache — still parses;
22389
+ // absent reads as 'builtin', which is the behaviour that predates the field.
22390
+ //
22391
+ // Deliberately NOT `kind`/PolicyKind: that name and that enum answer which
22392
+ // built-in archetype catalog entry a policy is, which every catalog surface
22393
+ // reads and which a caller may state. This one is a statement the PRODUCER
22394
+ // of a bundle makes about a row, and only the bundle builder ever stamps it
22395
+ // — the CRUD routes neither accept nor set it.
22396
+ //
22397
+ // A device consumes this in exactly one direction: an 'authored' policy
22398
+ // arriving from a control plane marks the rules it targets as not
22399
+ // locally re-assignable. That can only ever ADD a refusal, never relax one,
22400
+ // which is what makes it safe to honour from an unsigned cache — the same
22401
+ // test `prohibitedModels` passes and `reversibleRuleIds` fails.
22402
+ provenance: PolicyProvenance.optional()
22403
+ }).meta({ id: "Policy" });
22404
+ var PolicyBundle = external_exports.object({
22405
+ version: external_exports.string(),
22406
+ policies: external_exports.array(Policy),
22407
+ // Rules from the installed marketplace packs (snapshotted by the
22408
+ // control plane). The plugin registers these in addition to its bundled
22409
+ // packs. Optional so older backends — and older on-disk caches — that omit
22410
+ // the field still parse; consumers read `bundle.rules ?? []`.
22411
+ rules: external_exports.array(Rule).optional(),
22412
+ // When true, `rules` IS the complete effective ruleset and the runtime must
22413
+ // NOT merge its compiled-in bundled packs — the standalone gateway sets this
22414
+ // after reading the user's installed snapshot (installed_packs, enabled
22415
+ // packs only), which is how detection updates stay manual: new bundled
22416
+ // rules run only after the user applies the pack update. Absent/false keeps
22417
+ // the historical composition (bundled packs + rules) — older caches.
22418
+ rulesComplete: external_exports.boolean().optional(),
22419
+ // Active detection exceptions, evaluation subset only (see
22420
+ // ExceptionBundleEntry). Optional so older bundle producers — and older
22421
+ // on-disk caches — that omit the field still parse; consumers read
22422
+ // `bundle.exceptions ?? []`.
22423
+ exceptions: external_exports.array(ExceptionBundleEntry).optional(),
22424
+ // Rule ids whose pack is assigned a REVERSIBLE archetype (Redact & Vault).
22425
+ // A second axis over the same `redact` action, carried beside the policies
22426
+ // rather than on them: nothing writes ruleId-targeted policies to disk, so
22427
+ // widening Policy itself would change a persisted shape to express something
22428
+ // only the in-memory bundle needs. Optional so an older producer — or an
22429
+ // older on-disk cache — still parses; consumers read `?? []` and get the
22430
+ // pre-existing one-way behaviour, which is the safe direction to default.
22431
+ reversibleRuleIds: external_exports.array(external_exports.string()).optional(),
22432
+ // Installed pack version, keyed by ruleId, for rules in `rules` that came
22433
+ // from a versioned installed pack. Optional so older backends — and older
22434
+ // on-disk caches — that omit the field still parse; consumers fall back to
22435
+ // the rule's own spec version. NOT the bundle version above — see
22436
+ // installedRuleset's ruleVersions for the source of truth.
22437
+ ruleVersions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
22438
+ // Model ids (the raw `model` string a harness reports, e.g.
22439
+ // `claude-opus-4-1`) the tenant has PROHIBITED. The plugin refuses to switch
22440
+ // a session onto one (PreModelSwitch) and refuses a turn that would run on
22441
+ // one (UserPromptSubmit). Optional so an older backend — and an older
22442
+ // on-disk cache — still parses; consumers read `?? []`, which is the
22443
+ // unenforced behaviour that predates this field and the safe direction to
22444
+ // default.
22445
+ //
22446
+ // Ids, not display names: the governance decision is keyed on the exact
22447
+ // string the harness reports (`model_status_override.versionId` in the
22448
+ // control plane), so no name resolution stands between the decision and the
22449
+ // comparison.
22450
+ prohibitedModels: external_exports.array(external_exports.string()).optional(),
22451
+ customKeywords: external_exports.array(external_exports.string()),
22452
+ fetchedAt: external_exports.iso.datetime()
22453
+ }).meta({ id: "PolicyBundle" });
22454
+ var POLICY_BUNDLE_SHAPE_ID = [
22455
+ ...Object.keys(PolicyBundle.shape),
22456
+ ...Object.keys(Policy.shape).map((key) => `policies.${key}`),
22457
+ ...PolicyTarget.options.flatMap((member) => "shape" in member ? Object.keys(member.shape) : []).map((key) => `policies.target.${key}`),
22458
+ ...Object.keys(ExceptionBundleEntry.shape).map((key) => `exceptions.${key}`)
22459
+ ].sort().join(",");
22460
+ var OBSERVE_ONLY_CATEGORIES = ["config"];
22461
+ var ENFORCEABLE_CATEGORIES = DetectionCategory.options.filter((c) => !OBSERVE_ONLY_CATEGORIES.includes(c));
22462
+ var CATEGORY_PEAK_SEVERITY = {
22463
+ secret: "critical",
22464
+ financial: "critical",
22465
+ // core-financial/credit-card
22466
+ code_flaw: "critical",
22467
+ pii: "high",
22468
+ phi: "high",
22469
+ custom: "high",
22470
+ // user-defined; conservative
22471
+ code_context: "low",
22472
+ config: "low"
22473
+ // observe-only; floors to monitor regardless
22474
+ };
22475
+ function severityFloorPolicy(category) {
22476
+ if (OBSERVE_ONLY_CATEGORIES.includes(category)) return "monitor";
22477
+ const peak = CATEGORY_PEAK_SEVERITY[category];
22478
+ return peak === "critical" || peak === "high" ? "warn" : "monitor";
22479
+ }
22480
+ var KNOWN_BUILTIN_IDS = ["monitor", "warn", "redact", "vault", "block"];
22481
+ var BuiltinPolicyId = external_exports.enum(KNOWN_BUILTIN_IDS).meta({ id: "BuiltinPolicyId" });
22482
+ var RedactFallback = BuiltinPolicyId.extract(["monitor", "warn", "block"]).meta({
22483
+ id: "RedactFallback"
22484
+ });
22485
+ var BUILTIN_POLICY_SPECS = {
22486
+ monitor: {
22487
+ name: "Monitor",
22488
+ action: "log",
22489
+ reversible: false,
22490
+ description: "Log every match for audit. The request is allowed through untouched."
22491
+ },
22492
+ warn: {
22493
+ name: "Warn",
22494
+ action: "warn",
22495
+ reversible: false,
22496
+ description: "Allow the request, but warn the user inline before it is sent."
22497
+ },
22498
+ redact: {
22499
+ name: "Redact",
22500
+ action: "redact",
22501
+ reversible: false,
22502
+ description: "Strip the matched value from the request and destroy it, then continue. What was removed cannot be recovered."
22503
+ },
22504
+ vault: {
22505
+ name: "Redact & Vault",
22506
+ action: "redact",
22507
+ reversible: true,
22508
+ description: "Strip the matched value from the request and keep an encrypted, recoverable copy in the local vault, leaving a pointer in its place. Needs the vault consent granted under Settings; without it this behaves as Redact."
22509
+ },
22510
+ block: {
22511
+ name: "Block",
22512
+ action: "block",
22513
+ reversible: false,
22514
+ description: "Refuse the request entirely whenever any rule in this detection matches."
22515
+ }
22516
+ };
22517
+ function builtinPolicyToAction(id) {
22518
+ return BUILTIN_POLICY_SPECS[id].action;
22519
+ }
22520
+ var PALETTE_WEAKEST_FIRST = [
22521
+ ...new Set(KNOWN_BUILTIN_IDS.map(builtinPolicyToAction))
22522
+ ];
22523
+ var BELOW_PALETTE = ACTION_TAKEN_KEYS.filter(
22524
+ (action) => !PALETTE_WEAKEST_FIRST.includes(action)
22525
+ );
22526
+ var ACTION_STRENGTH_ORDER = [
22527
+ ...BELOW_PALETTE,
22528
+ ...PALETTE_WEAKEST_FIRST
22529
+ ];
22530
+ var PackPolicyFloor = external_exports.object({
22531
+ /**
22532
+ * The weakest archetype the device may assign. Stated as a BuiltinPolicyId
22533
+ * rather than a raw ActionTaken because that is the vocabulary the user
22534
+ * picks from — a floor a UI cannot name is one it cannot explain.
22535
+ */
22536
+ floor: BuiltinPolicyId,
22537
+ /**
22538
+ * True when the organization AUTHORED a policy governing this pack rather
22539
+ * than stating a minimum: it gave the answer, so the pack is not
22540
+ * re-assignable locally in either direction.
22541
+ */
22542
+ locked: external_exports.boolean()
22543
+ }).describe("PackPolicyFloor");
22544
+ var CATEGORY_EXPRESSIBLE_IDS = KNOWN_BUILTIN_IDS.filter(
22545
+ (id) => !BUILTIN_POLICY_SPECS[id].reversible
22546
+ );
22547
+ var CATEGORY_INEXPRESSIBLE_IDS = KNOWN_BUILTIN_IDS.filter(
22548
+ (id) => BUILTIN_POLICY_SPECS[id].reversible
22549
+ );
22550
+ var CategoryPolicyId = external_exports.enum(CATEGORY_EXPRESSIBLE_IDS).meta({ id: "CategoryPolicyId" });
22551
+ var DEFAULT_ACTIONS = Object.fromEntries(
22552
+ DetectionCategory.options.map((c) => [c, builtinPolicyToAction(severityFloorPolicy(c))])
22553
+ );
22554
+ var BUILTIN_POLICIES = Object.fromEntries(
22555
+ KNOWN_BUILTIN_IDS.map((id) => [id, { id, ...BUILTIN_POLICY_SPECS[id] }])
22556
+ );
22557
+ var UsedByItem = external_exports.object({
22558
+ id: external_exports.string(),
22559
+ name: external_exports.string(),
22560
+ ruleCount: external_exports.number().int().nonnegative(),
22561
+ enabled: external_exports.boolean()
22562
+ }).meta({ id: "UsedByItem" });
22563
+ var PolicyListItem = external_exports.object({
22564
+ id: external_exports.string(),
22565
+ kind: PolicyKind,
22566
+ name: external_exports.string(),
22567
+ enabled: external_exports.boolean(),
22568
+ usedByCount: external_exports.number().int().nonnegative()
22569
+ }).meta({ id: "PolicyListItem" });
22570
+ var ListPoliciesResponse = external_exports.object({ items: external_exports.array(PolicyListItem) }).meta({ id: "ListPoliciesResponse" });
22571
+ var PolicyDetail = external_exports.object({
22572
+ specVersion: external_exports.literal(1),
22573
+ id: external_exports.string(),
22574
+ kind: PolicyKind,
22575
+ name: external_exports.string(),
22576
+ enabled: external_exports.boolean(),
22577
+ description: external_exports.string(),
22578
+ usedBy: external_exports.array(UsedByItem)
22579
+ }).meta({ id: "PolicyDetail" });
22580
+ var PolicyStatsResponse = external_exports.object({
22581
+ policies: external_exports.number().int().nonnegative(),
22582
+ builtin: external_exports.number().int().nonnegative(),
22583
+ custom: external_exports.number().int().nonnegative(),
22584
+ detectionsGoverned: external_exports.number().int().nonnegative()
22585
+ }).meta({ id: "PolicyStatsResponse" });
22586
+
22283
22587
  // ../../packages/schema/src/zod/vault.ts
22284
22588
  var CATEGORY_ALTERNATION = DetectionCategory.options.join("|");
22285
22589
  var POINTER_TOKEN_PATTERN = new RegExp(
@@ -22316,6 +22620,14 @@ var VaultEntry = external_exports.object({
22316
22620
  // How many times this value has been detected on this machine — the reuse
22317
22621
  // signal the vault dashboard reads. Distinct from VaultDeref.pointerCount.
22318
22622
  occurrenceCount: external_exports.number().int().nonnegative(),
22623
+ // True when a PERSON asked for this value to be replaced — the surfaced-
22624
+ // secrets strike — rather than a pack enforcing its assignment. One value is
22625
+ // one row however many paths vault it, so this is what tells a policy sweep
22626
+ // that the row carries somebody's own instruction and not just an assignment
22627
+ // that has since been lowered. STICKY and MONOTONIC: a later automatic
22628
+ // vaulting of the same value must never clear it — what the user said about
22629
+ // the value does not expire.
22630
+ userAuthorized: external_exports.boolean(),
22319
22631
  firstSeen: external_exports.string(),
22320
22632
  lastSeen: external_exports.string()
22321
22633
  });
@@ -22431,7 +22743,7 @@ var VaultConsent = external_exports.object({
22431
22743
  });
22432
22744
 
22433
22745
  // ../../packages/schema/src/zod/local.ts
22434
- var WORKSPACE_SETTINGS_SPEC_VERSION = 6;
22746
+ var WORKSPACE_SETTINGS_SPEC_VERSION = 7;
22435
22747
  var RunMode = external_exports.enum(["standalone", "attached"]);
22436
22748
  var ControlPlaneConnection = external_exports.object({
22437
22749
  endpoint: external_exports.string().min(1),
@@ -22472,6 +22784,19 @@ var WorkspaceSettings = external_exports.object({
22472
22784
  vaultKeyCustody: VaultKeyCustody.default("file"),
22473
22785
  // How a pointer renders in assistant prose on screen (see VaultInlineReveal).
22474
22786
  vaultInlineReveal: VaultInlineReveal.default("masked"),
22787
+ // What a `redact` policy degrades to on a FIELD the host cannot rewrite in
22788
+ // place. Not a handling policy: the policy has already resolved to redact,
22789
+ // and this only says what happens when the host offers no channel to carry it
22790
+ // out — Antigravity's PreToolUse has no updatedInput at all, and Codex and
22791
+ // Claude Code decline to mask a field that EXECUTES because masking would
22792
+ // change what runs. Per FIELD rather than per host, so a host that can
22793
+ // rewrite some inputs keeps true redaction on those.
22794
+ //
22795
+ // Spelled in the built-in policy vocabulary rather than as a fresh enum, so
22796
+ // an attached machine's merge is `strongerAction` over the one action ladder
22797
+ // and no second rank order exists to drift from it. 'deny' is a host wire
22798
+ // word and stays out of the stored value.
22799
+ redactFallback: RedactFallback.default("warn"),
22475
22800
  // Absent until /aka:setup completes; its presence is what "onboarded" means.
22476
22801
  onboardedAt: external_exports.iso.datetime().optional(),
22477
22802
  // Records that the user consented to sending findings to the model API for
@@ -22479,10 +22804,12 @@ var WorkspaceSettings = external_exports.object({
22479
22804
  // Absent until granted; a stale payloadVersion means the consent no longer
22480
22805
  // covers the current payload and must be re-granted.
22481
22806
  modelJudgeConsent: ModelJudgeConsent.optional(),
22482
- // Records that the user consented to sending the activity already recorded on
22483
- // this machine to the deployment it is attached to, along with the payload
22484
- // shape and the endpoint they agreed to. Absent until granted, and a grant for
22485
- // a different endpoint or an older payload no longer counts.
22807
+ // Records that the user consented to the DEFERRED send — the outbox — along
22808
+ // with the payload shape and the endpoint they agreed to. Since payload v3
22809
+ // that covers the pre-attach backlog AND undelivered captures alike, and both
22810
+ // carry prompt/reply/tool-output text in `content`; the key name predates
22811
+ // both widenings. Absent until granted, and a grant for a different endpoint
22812
+ // or an older payload no longer counts.
22486
22813
  historySyncConsent: HistorySyncConsent.optional()
22487
22814
  });
22488
22815
 
@@ -22495,8 +22822,12 @@ var ManagedSettingKey = external_exports.enum([
22495
22822
  "vaultKeyCustody",
22496
22823
  "vaultInlineReveal",
22497
22824
  "modelJudgeConsent",
22498
- "dataSharesInPlace"
22825
+ "dataSharesInPlace",
22826
+ "redactFallback"
22499
22827
  ]).meta({ id: "ManagedSettingKey" });
22828
+ function isManagedSettingKey(value) {
22829
+ return ManagedSettingKey.safeParse(value).success;
22830
+ }
22500
22831
  var ManagedSettingsValues = external_exports.object({
22501
22832
  runMode: external_exports.enum(["standalone", "attached"]).optional(),
22502
22833
  controlPlane: external_exports.object({
@@ -22508,7 +22839,8 @@ var ManagedSettingsValues = external_exports.object({
22508
22839
  vaultKeyCustody: external_exports.enum(["file", "keychain"]).optional(),
22509
22840
  vaultInlineReveal: external_exports.enum(["masked", "full", "off"]).optional(),
22510
22841
  modelJudgeConsent: external_exports.boolean().optional(),
22511
- dataSharesInPlace: external_exports.boolean().optional()
22842
+ dataSharesInPlace: external_exports.boolean().optional(),
22843
+ redactFallback: RedactFallback.optional()
22512
22844
  }).meta({ id: "ManagedSettingsValues" });
22513
22845
  var ManagedSettings = external_exports.object({
22514
22846
  specVersion: external_exports.number().int().positive().default(MANAGED_SETTINGS_SPEC_VERSION),
@@ -22520,173 +22852,28 @@ var ManagedSettings = external_exports.object({
22520
22852
  // Which of those the user may not change. A key here with no matching value
22521
22853
  // freezes whatever the user last chose; a value with no lock is a DEFAULT
22522
22854
  // the user may still override. The two are separable on purpose.
22523
- lockedFields: external_exports.array(ManagedSettingKey).default([])
22524
- }).meta({ id: "ManagedSettings" });
22525
-
22526
- // ../../packages/schema/src/zod/policy.ts
22527
- var PolicyScope = external_exports.enum(["global", "repo", "user"]).meta({ id: "PolicyScope" });
22528
- var PolicyTarget = external_exports.union([external_exports.object({ ruleId: external_exports.string() }), external_exports.object({ category: DetectionCategory })]).meta({ id: "PolicyTarget" });
22529
- var Policy = external_exports.object({
22530
- id: external_exports.guid(),
22531
- scope: PolicyScope,
22532
- target: PolicyTarget,
22533
- action: ActionTaken,
22534
- enabled: external_exports.boolean().default(true),
22535
- customKeywords: external_exports.array(external_exports.string()).optional(),
22536
- // Display name — optional so older policy rows without name still parse.
22537
- // Added for the findings API (policy.name column migration).
22538
- name: external_exports.string().optional()
22539
- }).meta({ id: "Policy" });
22540
- var PolicyBundle = external_exports.object({
22541
- version: external_exports.string(),
22542
- policies: external_exports.array(Policy),
22543
- // Rules from the installed marketplace packs (snapshotted by the
22544
- // control plane). The plugin registers these in addition to its bundled
22545
- // packs. Optional so older backends — and older on-disk caches — that omit
22546
- // the field still parse; consumers read `bundle.rules ?? []`.
22547
- rules: external_exports.array(Rule).optional(),
22548
- // When true, `rules` IS the complete effective ruleset and the runtime must
22549
- // NOT merge its compiled-in bundled packs — the standalone gateway sets this
22550
- // after reading the user's installed snapshot (installed_packs, enabled
22551
- // packs only), which is how detection updates stay manual: new bundled
22552
- // rules run only after the user applies the pack update. Absent/false keeps
22553
- // the historical composition (bundled packs + rules) — older caches.
22554
- rulesComplete: external_exports.boolean().optional(),
22555
- // Active detection exceptions, evaluation subset only (see
22556
- // ExceptionBundleEntry). Optional so older bundle producers — and older
22557
- // on-disk caches — that omit the field still parse; consumers read
22558
- // `bundle.exceptions ?? []`.
22559
- exceptions: external_exports.array(ExceptionBundleEntry).optional(),
22560
- // Rule ids whose pack is assigned a REVERSIBLE archetype (Redact & Vault).
22561
- // A second axis over the same `redact` action, carried beside the policies
22562
- // rather than on them: nothing writes ruleId-targeted policies to disk, so
22563
- // widening Policy itself would change a persisted shape to express something
22564
- // only the in-memory bundle needs. Optional so an older producer — or an
22565
- // older on-disk cache — still parses; consumers read `?? []` and get the
22566
- // pre-existing one-way behaviour, which is the safe direction to default.
22567
- reversibleRuleIds: external_exports.array(external_exports.string()).optional(),
22568
- // Installed pack version, keyed by ruleId, for rules in `rules` that came
22569
- // from a versioned installed pack. Optional so older backends — and older
22570
- // on-disk caches — that omit the field still parse; consumers fall back to
22571
- // the rule's own spec version. NOT the bundle version above — see
22572
- // installedRuleset's ruleVersions for the source of truth.
22573
- ruleVersions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
22574
- // Model ids (the raw `model` string a harness reports, e.g.
22575
- // `claude-opus-4-1`) the tenant has PROHIBITED. The plugin refuses to switch
22576
- // a session onto one (PreModelSwitch) and refuses a turn that would run on
22577
- // one (UserPromptSubmit). Optional so an older backend — and an older
22578
- // on-disk cache — still parses; consumers read `?? []`, which is the
22579
- // unenforced behaviour that predates this field and the safe direction to
22580
- // default.
22581
22855
  //
22582
- // Ids, not display names: the governance decision is keyed on the exact
22583
- // string the harness reports (`model_status_override.versionId` in the
22584
- // control plane), so no name resolution stands between the decision and the
22585
- // comparison.
22586
- prohibitedModels: external_exports.array(external_exports.string()).optional(),
22587
- customKeywords: external_exports.array(external_exports.string()),
22588
- fetchedAt: external_exports.iso.datetime()
22589
- }).meta({ id: "PolicyBundle" });
22590
- var OBSERVE_ONLY_CATEGORIES = ["config"];
22591
- var ENFORCEABLE_CATEGORIES = DetectionCategory.options.filter((c) => !OBSERVE_ONLY_CATEGORIES.includes(c));
22592
- var CATEGORY_PEAK_SEVERITY = {
22593
- secret: "critical",
22594
- financial: "critical",
22595
- // core-financial/credit-card
22596
- code_flaw: "critical",
22597
- pii: "high",
22598
- phi: "high",
22599
- custom: "high",
22600
- // user-defined; conservative
22601
- code_context: "low",
22602
- config: "low"
22603
- // observe-only; floors to monitor regardless
22604
- };
22605
- function severityFloorPolicy(category) {
22606
- if (OBSERVE_ONLY_CATEGORIES.includes(category)) return "monitor";
22607
- const peak = CATEGORY_PEAK_SEVERITY[category];
22608
- return peak === "critical" || peak === "high" ? "warn" : "monitor";
22609
- }
22610
- var PolicyKind = external_exports.enum(["builtin", "custom"]).meta({ id: "PolicyKind" });
22611
- var KNOWN_BUILTIN_IDS = ["monitor", "warn", "redact", "vault", "block"];
22612
- var BuiltinPolicyId = external_exports.enum(KNOWN_BUILTIN_IDS).meta({ id: "BuiltinPolicyId" });
22613
- var BUILTIN_POLICY_SPECS = {
22614
- monitor: {
22615
- name: "Monitor",
22616
- action: "log",
22617
- reversible: false,
22618
- description: "Log every match for audit. The request is allowed through untouched."
22619
- },
22620
- warn: {
22621
- name: "Warn",
22622
- action: "warn",
22623
- reversible: false,
22624
- description: "Allow the request, but warn the user inline before it is sent."
22625
- },
22626
- redact: {
22627
- name: "Redact",
22628
- action: "redact",
22629
- reversible: false,
22630
- description: "Strip the matched value from the request and destroy it, then continue. What was removed cannot be recovered."
22631
- },
22632
- vault: {
22633
- name: "Redact & Vault",
22634
- action: "redact",
22635
- reversible: true,
22636
- description: "Strip the matched value from the request and keep an encrypted, recoverable copy in the local vault, leaving a pointer in its place. Needs the vault consent granted under Settings; without it this behaves as Redact."
22637
- },
22638
- block: {
22639
- name: "Block",
22640
- action: "block",
22641
- reversible: false,
22642
- description: "Refuse the request entirely whenever any rule in this detection matches."
22856
+ // Parsed as NAMES rather than as the enum, and split below: a name this
22857
+ // build does not know is dropped from the locked set and reported, never a
22858
+ // reason to refuse the file. The same shape reaches an older build whenever
22859
+ // an administrator locks a key a newer build added, and refusing it there
22860
+ // ran that build entirely unmanaged — every pin and lock gone — on exactly
22861
+ // the fleets most likely to carry a version skew. A name outside the enum
22862
+ // is still never HONOURED: the lockable set stays explicit above.
22863
+ lockedFields: external_exports.array(external_exports.string()).default([])
22864
+ }).transform(({ lockedFields, ...rest }) => {
22865
+ const known = [];
22866
+ const unknown2 = [];
22867
+ for (const name of lockedFields) {
22868
+ if (isManagedSettingKey(name)) known.push(name);
22869
+ else unknown2.push(name);
22643
22870
  }
22644
- };
22645
- function builtinPolicyToAction(id) {
22646
- return BUILTIN_POLICY_SPECS[id].action;
22647
- }
22648
- var CATEGORY_EXPRESSIBLE_IDS = KNOWN_BUILTIN_IDS.filter(
22649
- (id) => !BUILTIN_POLICY_SPECS[id].reversible
22650
- );
22651
- var CATEGORY_INEXPRESSIBLE_IDS = KNOWN_BUILTIN_IDS.filter(
22652
- (id) => BUILTIN_POLICY_SPECS[id].reversible
22653
- );
22654
- var CategoryPolicyId = external_exports.enum(CATEGORY_EXPRESSIBLE_IDS).meta({ id: "CategoryPolicyId" });
22655
- var DEFAULT_ACTIONS = Object.fromEntries(
22656
- DetectionCategory.options.map((c) => [c, builtinPolicyToAction(severityFloorPolicy(c))])
22657
- );
22658
- var BUILTIN_POLICIES = Object.fromEntries(
22659
- KNOWN_BUILTIN_IDS.map((id) => [id, { id, ...BUILTIN_POLICY_SPECS[id] }])
22660
- );
22661
- var UsedByItem = external_exports.object({
22662
- id: external_exports.string(),
22663
- name: external_exports.string(),
22664
- ruleCount: external_exports.number().int().nonnegative(),
22665
- enabled: external_exports.boolean()
22666
- }).meta({ id: "UsedByItem" });
22667
- var PolicyListItem = external_exports.object({
22668
- id: external_exports.string(),
22669
- kind: PolicyKind,
22670
- name: external_exports.string(),
22671
- enabled: external_exports.boolean(),
22672
- usedByCount: external_exports.number().int().nonnegative()
22673
- }).meta({ id: "PolicyListItem" });
22674
- var ListPoliciesResponse = external_exports.object({ items: external_exports.array(PolicyListItem) }).meta({ id: "ListPoliciesResponse" });
22675
- var PolicyDetail = external_exports.object({
22676
- specVersion: external_exports.literal(1),
22677
- id: external_exports.string(),
22678
- kind: PolicyKind,
22679
- name: external_exports.string(),
22680
- enabled: external_exports.boolean(),
22681
- description: external_exports.string(),
22682
- usedBy: external_exports.array(UsedByItem)
22683
- }).meta({ id: "PolicyDetail" });
22684
- var PolicyStatsResponse = external_exports.object({
22685
- policies: external_exports.number().int().nonnegative(),
22686
- builtin: external_exports.number().int().nonnegative(),
22687
- custom: external_exports.number().int().nonnegative(),
22688
- detectionsGoverned: external_exports.number().int().nonnegative()
22689
- }).meta({ id: "PolicyStatsResponse" });
22871
+ return {
22872
+ ...rest,
22873
+ lockedFields: known,
22874
+ ...unknown2.length > 0 ? { unknownLockedFields: unknown2 } : {}
22875
+ };
22876
+ }).meta({ id: "ManagedSettings" });
22690
22877
 
22691
22878
  // ../../packages/schema/src/zod/project-files.ts
22692
22879
  var ProjectFileInput = external_exports.object({
@@ -22803,7 +22990,11 @@ var FindingsTimeseriesPoint = external_exports.object({
22803
22990
  timestamp: external_exports.iso.date(),
22804
22991
  critical: external_exports.number().int().nonnegative(),
22805
22992
  high: external_exports.number().int().nonnegative(),
22806
- medium: external_exports.number().int().nonnegative()
22993
+ medium: external_exports.number().int().nonnegative(),
22994
+ // Optional and additive, so a producer written against the earlier
22995
+ // three-series contract keeps validating. A consumer plotting it resolves the
22996
+ // absent case itself — the chart point requires a number.
22997
+ low: external_exports.number().int().nonnegative().optional()
22807
22998
  }).meta({ id: "FindingsTimeseriesPoint" });
22808
22999
  var FindingsTimeseriesResponse = external_exports.object({
22809
23000
  range: TimeRange,
@@ -22829,6 +23020,10 @@ var ResolvedFeedItem = external_exports.object({
22829
23020
  findingKey: external_exports.string(),
22830
23021
  ruleId: external_exports.string(),
22831
23022
  severity: Severity,
23023
+ // Repository slug, and the file path RELATIVE to it. The pair is what
23024
+ // identifies the file: a bare path matches the same name in every repo.
23025
+ // Optional and additive; empty when the event carried no repo.
23026
+ repo: external_exports.string().optional(),
22832
23027
  path: external_exports.string(),
22833
23028
  // ISO-8601 datetime (matches FindingInstance.detectedAt / the rest of the
22834
23029
  // findings domain). The reader `.toISOString()`s the DB epoch-ms values.
@@ -22927,10 +23122,12 @@ var DismissRecommendedActionResponse = external_exports.object({ id: external_ex
22927
23122
  var RecommendedActionIdParam = external_exports.object({ id: external_exports.string() });
22928
23123
 
22929
23124
  // ../../packages/schema/src/zod/settings-action.ts
23125
+ var HistorySyncConsentChoice = external_exports.enum(["granted", "revoked", "unchanged"]).meta({ id: "HistorySyncConsentChoice" });
23126
+ var ModelJudgeConsentChoice = external_exports.enum(["granted", "revoked", "unchanged"]).meta({ id: "ModelJudgeConsentChoice" });
22930
23127
  var SaveSettingsInput = external_exports.object({
22931
23128
  historicalAccess: external_exports.string(),
22932
- modelJudgeConsent: external_exports.boolean(),
22933
- historySyncConsent: external_exports.boolean(),
23129
+ modelJudgeConsent: ModelJudgeConsentChoice,
23130
+ historySyncConsent: HistorySyncConsentChoice,
22934
23131
  vaultConsent: external_exports.string(),
22935
23132
  vaultInlineReveal: external_exports.string()
22936
23133
  });
@@ -23063,8 +23260,8 @@ import { execFileSync } from "child_process";
23063
23260
  var USE_SHELL = process.platform === "win32";
23064
23261
 
23065
23262
  // ../../packages/plugin-sdk/src/config.ts
23066
- import { existsSync as existsSync7 } from "fs";
23067
- import { join as join12 } from "path";
23263
+ import { existsSync as existsSync8 } from "fs";
23264
+ import { join as join14 } from "path";
23068
23265
 
23069
23266
  // ../../packages/persistence/src/attached-derived.ts
23070
23267
  import { rmSync } from "fs";
@@ -23087,8 +23284,8 @@ import {
23087
23284
  import { threadId } from "worker_threads";
23088
23285
 
23089
23286
  // ../../packages/persistence/src/database.ts
23090
- import { randomUUID as randomUUID10 } from "crypto";
23091
- import { join as join4, sep } from "path";
23287
+ import { randomUUID as randomUUID11 } from "crypto";
23288
+ import { dirname as dirname2, join as join7, sep } from "path";
23092
23289
  import { DatabaseSync } from "node:sqlite";
23093
23290
 
23094
23291
  // ../../packages/persistence/src/ids.ts
@@ -23104,6 +23301,20 @@ var STAGED_NAME_SUFFIX = `.bak${SNAPSHOT_STAGING_SUFFIX}`;
23104
23301
 
23105
23302
  // ../../packages/persistence/src/repositories/activity.ts
23106
23303
  var LIVE_ACTIVITY_WINDOW_MS = 30 * 6e4;
23304
+ var DB_EVENT_TYPE_TO_KIND = {
23305
+ session: "session",
23306
+ prompt: "prompt",
23307
+ response: "response",
23308
+ tool_call: "tool",
23309
+ hook: "hook",
23310
+ detection: "detection",
23311
+ share: "share",
23312
+ permission: "permission",
23313
+ commit: "commit",
23314
+ error: "error",
23315
+ active: "active"
23316
+ };
23317
+ var TIMELINE_EVENT_TYPES = Object.keys(DB_EVENT_TYPE_TO_KIND).map((kind) => `'${kind}'`).join(", ");
23107
23318
  var DEFAULT_HARNESS = HARNESS.ClaudeCode;
23108
23319
 
23109
23320
  // ../../packages/persistence/src/repositories/exceptions.ts
@@ -23117,15 +23328,75 @@ var ACTIVE_REVEAL_GRANT_PREDICATE = `capability = 'reveal_to_model'
23117
23328
  AND conditions IS NULL
23118
23329
  AND ${ACTIVE_PREDICATE}`;
23119
23330
 
23331
+ // ../../packages/persistence/src/repositories/resolution-sql.ts
23332
+ function latestResolutionColumnSql(column, findingsAlias) {
23333
+ return `(
23334
+ SELECT fr.${column} FROM finding_resolution fr
23335
+ WHERE fr.finding_key = ${findingsAlias}.finding_key
23336
+ ORDER BY fr.created_at DESC, fr.rowid DESC
23337
+ LIMIT 1
23338
+ )`;
23339
+ }
23340
+ function latestResolutionStatusSql(findingsAlias) {
23341
+ return latestResolutionColumnSql("status", findingsAlias);
23342
+ }
23343
+
23344
+ // ../../packages/persistence/src/repositories/findings.ts
23345
+ var FINDING_ROW_COLUMNS_SQL = `f.id AS id, d.rule_id AS rule_id, d.category AS category,
23346
+ d.severity AS severity, f.masked_match AS masked_match,
23347
+ f.action_taken AS action_taken, f.confidence AS confidence,
23348
+ e.started_at AS occurred_at,
23349
+ e.source_tool AS source_tool,
23350
+ e.repo AS repo,
23351
+ e.file_path AS file,
23352
+ e.tool_name AS tool_name,
23353
+ f.audit_event_id AS event_id, e.root_session_id AS session_id,
23354
+ e.event_type AS kind, f.finding_key AS finding_key,
23355
+ ${latestResolutionStatusSql("f")} AS latest_status`;
23356
+
23120
23357
  // ../../packages/persistence/src/repositories/history-sync.ts
23121
23358
  var STRUCTURAL_EVENT_TYPES = ["session", "llm_call", "tool_call"];
23122
23359
  var TYPE_LIST = STRUCTURAL_EVENT_TYPES.map((t) => `'${t}'`).join(", ");
23360
+ var OUTBOX_CAPTURE_EVENT_TYPES = ["prompt", "response", "tool_use"];
23361
+ var CAPTURE_TYPE_LIST = OUTBOX_CAPTURE_EVENT_TYPES.map((t) => `'${t}'`).join(", ");
23123
23362
 
23124
23363
  // ../../packages/persistence/src/repositories/installed-packs.ts
23125
- import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
23364
+ import { createHash as createHash2, randomUUID as randomUUID4 } from "crypto";
23365
+
23366
+ // ../../packages/persistence/src/policy-floor.ts
23367
+ import { readFileSync as readFileSync5 } from "fs";
23368
+ import { join as join6 } from "path";
23369
+
23370
+ // ../../packages/persistence/src/local-layout.ts
23371
+ import { renameSync as renameSync3 } from "fs";
23372
+ import { mkdir } from "fs/promises";
23373
+ import { homedir } from "os";
23374
+ import { join as join4 } from "path";
23375
+
23376
+ // ../../packages/persistence/src/settings.ts
23377
+ import { readFileSync as readFileSync4 } from "fs";
23378
+ import { join as join5 } from "path";
23379
+
23380
+ // ../../packages/persistence/src/file-lock.ts
23381
+ import { randomUUID as randomUUID3 } from "crypto";
23382
+ import {
23383
+ closeSync,
23384
+ existsSync as existsSync2,
23385
+ openSync,
23386
+ readFileSync as readFileSync2,
23387
+ rmSync as rmSync5,
23388
+ statSync as statSync3,
23389
+ writeFileSync as writeFileSync2
23390
+ } from "fs";
23391
+ import { hostname as hostname3 } from "os";
23392
+ var PARK = new Int32Array(new SharedArrayBuffer(4));
23393
+
23394
+ // ../../packages/persistence/src/managed-settings.ts
23395
+ import { readFileSync as readFileSync3 } from "fs";
23396
+ import { posix, win32 } from "path";
23126
23397
 
23127
23398
  // ../../packages/persistence/src/repositories/inventory-assets.ts
23128
- import { randomUUID as randomUUID4 } from "crypto";
23399
+ import { randomUUID as randomUUID5 } from "crypto";
23129
23400
  var VALID_HARNESS_IDS = new Set(HarnessId.options);
23130
23401
  var HARNESS_LABELS = {
23131
23402
  [HARNESS.ClaudeCode]: "Claude Code",
@@ -23143,16 +23414,16 @@ var TITLE_NEEDLES = {
23143
23414
  };
23144
23415
 
23145
23416
  // ../../packages/persistence/src/repositories/policies.ts
23146
- import { randomUUID as randomUUID5 } from "crypto";
23417
+ import { randomUUID as randomUUID6 } from "crypto";
23147
23418
 
23148
23419
  // ../../packages/persistence/src/repositories/project-files.ts
23149
- import { randomUUID as randomUUID6 } from "crypto";
23420
+ import { randomUUID as randomUUID7 } from "crypto";
23150
23421
 
23151
23422
  // ../../packages/persistence/src/repositories/resolutions.ts
23152
- import { randomUUID as randomUUID7 } from "crypto";
23423
+ import { randomUUID as randomUUID8 } from "crypto";
23153
23424
 
23154
23425
  // ../../packages/persistence/src/repositories/secret-vault.ts
23155
- import { randomUUID as randomUUID8 } from "crypto";
23426
+ import { randomUUID as randomUUID9 } from "crypto";
23156
23427
 
23157
23428
  // ../../packages/persistence/src/repositories/security.ts
23158
23429
  var SCAN_COVERAGE = {
@@ -23167,53 +23438,35 @@ var SCAN_COVERAGE = {
23167
23438
  };
23168
23439
 
23169
23440
  // ../../packages/persistence/src/repositories/shares.ts
23170
- import { randomUUID as randomUUID9 } from "crypto";
23441
+ import { randomUUID as randomUUID10 } from "crypto";
23171
23442
 
23172
- // ../../packages/persistence/src/file-lock.ts
23173
- import { randomUUID as randomUUID11 } from "crypto";
23174
- import {
23175
- closeSync,
23176
- existsSync as existsSync2,
23177
- openSync,
23178
- readFileSync as readFileSync2,
23179
- rmSync as rmSync5,
23180
- statSync as statSync3,
23181
- writeFileSync as writeFileSync2
23182
- } from "fs";
23183
- import { hostname as hostname3 } from "os";
23184
- var PARK = new Int32Array(new SharedArrayBuffer(4));
23443
+ // ../../packages/persistence/src/database.ts
23444
+ var CAPTURE_GRAIN = new Set(EventKind.options);
23185
23445
 
23186
- // ../../packages/persistence/src/finding-key.ts
23446
+ // ../../packages/persistence/src/egress-wire.ts
23187
23447
  import { createHash as createHash3 } from "crypto";
23188
23448
 
23449
+ // ../../packages/persistence/src/finding-key.ts
23450
+ import { createHash as createHash4 } from "crypto";
23451
+
23189
23452
  // ../../packages/persistence/src/fingerprint.ts
23190
23453
  import { createHmac, randomBytes } from "crypto";
23191
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
23192
- import { join as join5 } from "path";
23454
+ import { existsSync as existsSync3, readFileSync as readFileSync6 } from "fs";
23455
+ import { join as join8 } from "path";
23193
23456
  import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
23194
23457
 
23195
- // ../../packages/persistence/src/history-preview.ts
23458
+ // ../../packages/persistence/src/history-backfill.ts
23196
23459
  import { existsSync as existsSync4 } from "fs";
23197
- import { join as join6 } from "path";
23198
- import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
23460
+ import { join as join9 } from "path";
23199
23461
 
23200
- // ../../packages/persistence/src/local-layout.ts
23201
- import { renameSync as renameSync3 } from "fs";
23202
- import { mkdir } from "fs/promises";
23203
- import { homedir } from "os";
23204
- import { join as join7 } from "path";
23205
-
23206
- // ../../packages/persistence/src/managed-settings.ts
23207
- import { readFileSync as readFileSync4 } from "fs";
23208
- import { posix, win32 } from "path";
23209
-
23210
- // ../../packages/persistence/src/settings.ts
23211
- import { readFileSync as readFileSync5 } from "fs";
23212
- import { join as join8 } from "path";
23462
+ // ../../packages/persistence/src/history-preview.ts
23463
+ import { existsSync as existsSync5 } from "fs";
23464
+ import { join as join10 } from "path";
23465
+ import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
23213
23466
 
23214
23467
  // ../../packages/persistence/src/store-symlinks.ts
23215
- import { existsSync as existsSync5, lstatSync as lstatSync3, readlinkSync, realpathSync, statSync as statSync4 } from "fs";
23216
- import { dirname as dirname2, join as join9, resolve } from "path";
23468
+ import { existsSync as existsSync6, lstatSync as lstatSync3, readlinkSync, realpathSync, statSync as statSync4 } from "fs";
23469
+ import { dirname as dirname3, join as join11, resolve } from "path";
23217
23470
 
23218
23471
  // ../../packages/persistence/src/vault/crypto.ts
23219
23472
  import {
@@ -23227,15 +23480,15 @@ import {
23227
23480
  // ../../packages/persistence/src/vault/key-provider.ts
23228
23481
  import { execFileSync as execFileSync2 } from "child_process";
23229
23482
  import { randomBytes as randomBytes2 } from "crypto";
23230
- import { chmodSync as chmodSync3, readFileSync as readFileSync6, renameSync as renameSync4, rmSync as rmSync6, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
23231
- import { join as join10 } from "path";
23483
+ import { chmodSync as chmodSync3, readFileSync as readFileSync7, renameSync as renameSync4, rmSync as rmSync6, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
23484
+ import { join as join12 } from "path";
23232
23485
 
23233
23486
  // ../../packages/persistence/src/vault/vault.ts
23234
23487
  import { randomBytes as randomBytes3, randomUUID as randomUUID12 } from "crypto";
23235
23488
 
23236
23489
  // ../../packages/persistence/src/warn-era-cap.ts
23237
- import { existsSync as existsSync6, writeFileSync as writeFileSync4 } from "fs";
23238
- import { join as join11 } from "path";
23490
+ import { existsSync as existsSync7, writeFileSync as writeFileSync4 } from "fs";
23491
+ import { join as join13 } from "path";
23239
23492
 
23240
23493
  // ../../packages/plugin-sdk/src/provider-env.ts
23241
23494
  var booleanish = external_exports.string().optional().transform((v) => {
@@ -23256,9 +23509,9 @@ var providerEnvShape = {
23256
23509
  var ProviderEnvSchema = external_exports.object(providerEnvShape);
23257
23510
 
23258
23511
  // ../../packages/plugin-sdk/src/config-inventory.ts
23259
- import { readdirSync as readdirSync2, readFileSync as readFileSync8, realpathSync as realpathSync2, statSync as statSync7 } from "fs";
23512
+ import { readdirSync as readdirSync2, readFileSync as readFileSync9, realpathSync as realpathSync2, statSync as statSync7 } from "fs";
23260
23513
  import { homedir as homedir2 } from "os";
23261
- import { basename as basename3, join as join14 } from "path";
23514
+ import { basename as basename3, join as join16 } from "path";
23262
23515
 
23263
23516
  // ../../packages/detections/src/egress/registry.ts
23264
23517
  var EXTRACTOR_VERSION = "1";
@@ -24016,24 +24269,20 @@ var CPU_CORROBORATION_SHARE = 0.2;
24016
24269
  var CORROBORATION_FLOOR_MS = BUDGET_MS * CPU_CORROBORATION_SHARE;
24017
24270
 
24018
24271
  // ../../packages/plugin-sdk/src/repo.ts
24019
- import { existsSync as existsSync8, readFileSync as readFileSync7, statSync as statSync6 } from "fs";
24020
- import { basename as basename2, dirname as dirname3, isAbsolute, join as join13, sep as sep2 } from "path";
24272
+ import { existsSync as existsSync9, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
24273
+ import { basename as basename2, dirname as dirname4, isAbsolute, join as join15, sep as sep2 } from "path";
24021
24274
 
24022
24275
  // ../../packages/plugin-sdk/src/events.ts
24023
- import { createHash as createHash4, randomUUID as randomUUID13 } from "crypto";
24276
+ import { createHash as createHash5, randomUUID as randomUUID13 } from "crypto";
24024
24277
 
24025
24278
  // ../../packages/plugin-sdk/src/isolated-scan.ts
24026
- import { existsSync as existsSync9 } from "fs";
24279
+ import { existsSync as existsSync10 } from "fs";
24027
24280
  import { fileURLToPath } from "url";
24028
24281
  import { Worker } from "worker_threads";
24029
24282
 
24030
- // ../../packages/plugin-sdk/src/ignore-layers.ts
24031
- var import_ignore = __toESM(require_ignore(), 1);
24032
- import { readFileSync as readFileSync9 } from "fs";
24033
- import { join as join15 } from "path";
24034
-
24035
- // ../../packages/plugin-sdk/src/inventory-resolver.ts
24036
- import { arch, hostname as hostname4, platform, release } from "os";
24283
+ // ../../packages/plugin-sdk/src/host-floor.ts
24284
+ import { readFileSync as readFileSync11 } from "fs";
24285
+ import { join as join18 } from "path";
24037
24286
 
24038
24287
  // ../../packages/plugin-sdk/src/model-governance.ts
24039
24288
  import {
@@ -24045,20 +24294,46 @@ import {
24045
24294
  readSync,
24046
24295
  writeFileSync as writeFileSync5
24047
24296
  } from "fs";
24048
- import { join as join16 } from "path";
24297
+ import { join as join17 } from "path";
24049
24298
  var TAIL_BYTES = 256 * 1024;
24050
24299
 
24300
+ // ../../packages/plugin-sdk/src/host-floor.ts
24301
+ var HOST_FEATURE = {
24302
+ ModelSwitch: "model-switch",
24303
+ VaultPointerDisplay: "vault-pointer-display"
24304
+ };
24305
+ var HOST_FLOORS = {
24306
+ [HOST_FEATURE.ModelSwitch]: {
24307
+ label: "model-switch protection",
24308
+ hookEvents: ["PreModelSwitch", "PostModelSwitch"],
24309
+ since: "2.1.251"
24310
+ },
24311
+ [HOST_FEATURE.VaultPointerDisplay]: {
24312
+ label: "vault pointer display",
24313
+ hookEvents: ["MessageDisplay"],
24314
+ since: "2.1.152"
24315
+ }
24316
+ };
24317
+
24318
+ // ../../packages/plugin-sdk/src/ignore-layers.ts
24319
+ var import_ignore = __toESM(require_ignore(), 1);
24320
+ import { readFileSync as readFileSync12 } from "fs";
24321
+ import { join as join19 } from "path";
24322
+
24323
+ // ../../packages/plugin-sdk/src/inventory-resolver.ts
24324
+ import { arch, hostname as hostname4, platform, release } from "os";
24325
+
24051
24326
  // ../../packages/plugin-sdk/src/nudge.ts
24052
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "fs";
24053
- import { join as join17 } from "path";
24327
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
24328
+ import { join as join20 } from "path";
24054
24329
 
24055
24330
  // ../../packages/plugin-sdk/src/paths.ts
24056
24331
  import { readdirSync as readdirSync3, realpathSync as realpathSync3 } from "fs";
24057
- import { basename as basename4, dirname as dirname4, sep as sep3 } from "path";
24332
+ import { basename as basename4, dirname as dirname5, sep as sep3 } from "path";
24058
24333
 
24059
24334
  // ../../packages/plugin-sdk/src/project-files.ts
24060
- import { existsSync as existsSync10, readdirSync as readdirSync4 } from "fs";
24061
- import { basename as basename5, join as join18 } from "path";
24335
+ import { existsSync as existsSync11, readdirSync as readdirSync4 } from "fs";
24336
+ import { basename as basename5, join as join21 } from "path";
24062
24337
 
24063
24338
  // ../../packages/plugin-sdk/src/provider-env-antigravity.ts
24064
24339
  var optionalBaseUrl2 = external_exports.preprocess((v) => {
@@ -24094,11 +24369,11 @@ var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
24094
24369
 
24095
24370
  // ../../packages/plugin-sdk/src/throttle.ts
24096
24371
  import { mkdirSync as mkdirSync4, statSync as statSync8, writeFileSync as writeFileSync7 } from "fs";
24097
- import { join as join19 } from "path";
24372
+ import { join as join22 } from "path";
24098
24373
 
24099
24374
  // ../../packages/setup-wizard/src/remediation/rotation-checklist.ts
24100
24375
  import { writeFileSync as writeFileSync8 } from "fs";
24101
- import { join as join20 } from "path";
24376
+ import { join as join23 } from "path";
24102
24377
 
24103
24378
  // ../../packages/setup-wizard/src/triage/merge.ts
24104
24379
  var RANK = Object.fromEntries(
@@ -24106,9 +24381,9 @@ var RANK = Object.fromEntries(
24106
24381
  );
24107
24382
 
24108
24383
  // ../../packages/setup-wizard/src/triage/plan-file.ts
24109
- import { mkdtempSync, readFileSync as readFileSync12, rmdirSync, rmSync as rmSync7, writeFileSync as writeFileSync9 } from "fs";
24384
+ import { mkdtempSync, readFileSync as readFileSync14, rmdirSync, rmSync as rmSync7, writeFileSync as writeFileSync9 } from "fs";
24110
24385
  import { tmpdir } from "os";
24111
- import { basename as basename6, dirname as dirname5, join as join21 } from "path";
24386
+ import { basename as basename6, dirname as dirname6, join as join24 } from "path";
24112
24387
  var SuppressionEntrySchema = external_exports.object({
24113
24388
  ruleId: external_exports.string(),
24114
24389
  category: DetectionCategory,
@@ -24251,7 +24526,7 @@ function buildIntroCard(manifest2, verified) {
24251
24526
  var manifestPath = process.argv[2];
24252
24527
  var manifest = {};
24253
24528
  try {
24254
- manifest = JSON.parse(readFileSync13(manifestPath ?? "", "utf8"));
24529
+ manifest = JSON.parse(readFileSync15(manifestPath ?? "", "utf8"));
24255
24530
  } catch {
24256
24531
  }
24257
24532
  process.stdout.write(show(fenced(buildIntroCard(manifest))));