@holonograph/client 0.6.0 → 0.7.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 (3) hide show
  1. package/dist/index.d.ts +814 -319
  2. package/dist/index.js +421 -7
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4108,7 +4108,7 @@ var JUDGE_CONTEXT_SCOPES = [
4108
4108
  "full_generating_prompt"
4109
4109
  ];
4110
4110
  var JudgeContextScopeSchema = external_exports.enum(JUDGE_CONTEXT_SCOPES);
4111
- external_exports.object({
4111
+ var JudgeIdentitySchema = external_exports.object({
4112
4112
 
4113
4113
  rubricHash: external_exports.string().min(1).optional(),
4114
4114
 
@@ -4124,6 +4124,14 @@ function judgeIdentityColumns(identity) {
4124
4124
  if (identity.model !== void 0) columns[JUDGE_MODEL_COLUMN_ID] = identity.model;
4125
4125
  return columns;
4126
4126
  }
4127
+ var JudgeLensIdentityObservationSchema = external_exports.object({
4128
+
4129
+ rubricHash: external_exports.array(external_exports.string().min(1)).optional(),
4130
+
4131
+ contextScope: external_exports.array(external_exports.string().min(1)).optional(),
4132
+
4133
+ model: external_exports.array(external_exports.string().min(1)).optional()
4134
+ });
4127
4135
 
4128
4136
  var CannedMessageRefSchema = external_exports.string().min(1).max(256);
4129
4137
  var ALL_GATE_FAILURE_ACTIONS = ["retry", "flag", "block"];
@@ -4282,7 +4290,7 @@ external_exports.object({
4282
4290
 
4283
4291
  description: external_exports.string().optional(),
4284
4292
 
4285
- surfaces: external_exports.array(SurfaceDeclarationSchema).min(1),
4293
+ surfaces: external_exports.array(SurfaceDeclarationSchema),
4286
4294
 
4287
4295
  routings: external_exports.array(SurfaceRoutingSchema).optional(),
4288
4296
 
@@ -4290,7 +4298,42 @@ external_exports.object({
4290
4298
 
4291
4299
  systemSurfaces: SystemSurfacesSchema.optional()
4292
4300
  });
4301
+ var RESERVED_COLUMN_IDS = new Set([
4302
+
4303
+ "lens_version",
4304
+ "light_source_identifier",
4305
+ "run_mode",
4306
+ "correlation_id",
4307
+ "provenance",
4308
+ "timestamp",
4309
+
4310
+ "light_source_served_model"
4311
+
4312
+ ]);
4293
4313
  var SERVED_MODEL_COLUMN_ID = "light_source_served_model";
4314
+ function normalizeColumnId(colId) {
4315
+ return colId.toLowerCase().replace(/[._-]/g, "");
4316
+ }
4317
+ var CANONICAL_APPARATUS_FACET_IDS = [
4318
+ ...RESERVED_COLUMN_IDS,
4319
+ JUDGE_RUBRIC_HASH_COLUMN_ID,
4320
+ JUDGE_CONTEXT_SCOPE_COLUMN_ID,
4321
+ JUDGE_MODEL_COLUMN_ID
4322
+ ];
4323
+ var NORMALIZED_APPARATUS_FACETS = new Map(
4324
+ CANONICAL_APPARATUS_FACET_IDS.map((id) => [normalizeColumnId(id), id])
4325
+ );
4326
+ new Set(
4327
+ [
4328
+ SERVED_MODEL_COLUMN_ID,
4329
+ JUDGE_RUBRIC_HASH_COLUMN_ID,
4330
+ JUDGE_CONTEXT_SCOPE_COLUMN_ID,
4331
+ JUDGE_MODEL_COLUMN_ID
4332
+ ].map(normalizeColumnId)
4333
+ );
4334
+ function isApparatusFacetSpelling(colId) {
4335
+ return NORMALIZED_APPARATUS_FACETS.has(normalizeColumnId(colId));
4336
+ }
4294
4337
 
4295
4338
  var LightSourceRoleSchema = external_exports.enum(["system", "user", "assistant", "tool"]);
4296
4339
  var LightSourceContentBlockSchema = external_exports.discriminatedUnion("kind", [
@@ -4858,7 +4901,9 @@ var NoiseFloorCalibrationSchema = external_exports.object({
4858
4901
 
4859
4902
  perFixtureDimension: external_exports.array(NoiseFloorPerFixtureDimensionSchema),
4860
4903
 
4861
- perDimensionPooled: external_exports.array(NoiseFloorPerDimensionPooledSchema)
4904
+ perDimensionPooled: external_exports.array(NoiseFloorPerDimensionPooledSchema),
4905
+
4906
+ calibratedUnderJudgeIdentity: JudgeLensIdentityObservationSchema.optional()
4862
4907
  });
4863
4908
  var VarianceDecompositionConfidenceIntervalSchema = external_exports.object({
4864
4909
  lower: external_exports.number().min(0),
@@ -4873,6 +4918,110 @@ var VarianceLensVersionEntrySchema = external_exports.object({
4873
4918
 
4874
4919
  meanScore: external_exports.number()
4875
4920
  });
4921
+ var FloorFreshnessSchema = external_exports.object({
4922
+ state: external_exports.enum(["fresh", "stale", "undeterminable"]),
4923
+
4924
+ comparedFacets: external_exports.array(external_exports.string()),
4925
+
4926
+ changedFacets: external_exports.array(external_exports.string()),
4927
+
4928
+ ambiguousFacets: external_exports.array(external_exports.string())
4929
+ });
4930
+ var PhrasingBandRegionSchema = external_exports.object({
4931
+
4932
+ bandMean: external_exports.number().min(0),
4933
+
4934
+ bandMax: external_exports.number().min(0)
4935
+ });
4936
+ external_exports.object({
4937
+
4938
+ version: external_exports.string().min(1),
4939
+
4940
+ frozenAt: external_exports.string().min(1),
4941
+
4942
+ measuredUnder: external_exports.object({
4943
+ judge: external_exports.string().min(1),
4944
+ rubricVersion: external_exports.string().min(1)
4945
+ }),
4946
+
4947
+ boundaries: external_exports.object({
4948
+
4949
+ ceilingLo: external_exports.number(),
4950
+
4951
+ floorHi: external_exports.number(),
4952
+
4953
+ midMeasuredRange: external_exports.object({ lo: external_exports.number(), hi: external_exports.number() })
4954
+ }),
4955
+ regions: external_exports.object({
4956
+ ceiling: PhrasingBandRegionSchema,
4957
+ mid: PhrasingBandRegionSchema,
4958
+ floor: PhrasingBandRegionSchema
4959
+ })
4960
+ });
4961
+ var FloorRegionSchema = external_exports.object({
4962
+
4963
+ region: external_exports.enum(["ceiling", "mid", "floor"]),
4964
+
4965
+ calibrationRegion: external_exports.enum(["ceiling", "mid", "floor"]).optional(),
4966
+
4967
+ calibrationScoreCount: external_exports.number().int().min(0).optional(),
4968
+
4969
+ bandMean: external_exports.number().min(0),
4970
+
4971
+ bandMax: external_exports.number().min(0),
4972
+
4973
+ bandExtrapolated: external_exports.boolean(),
4974
+
4975
+ calibrationBandExtrapolated: external_exports.boolean().optional(),
4976
+
4977
+ windowStraddlesBoundary: external_exports.boolean().optional(),
4978
+
4979
+ counterfactualSigmaAgentDelta: external_exports.number().nullable(),
4980
+
4981
+ counterfactualUnavailableReason: external_exports.enum(["no_calibration_scores", "calibration_region_degenerate"]).optional(),
4982
+
4983
+ curveProvenance: external_exports.object({
4984
+ version: external_exports.string(),
4985
+ judge: external_exports.string(),
4986
+ rubricVersion: external_exports.string()
4987
+ })
4988
+ });
4989
+ var LensCompositeCorrectionSchema = external_exports.object({
4990
+
4991
+ correctedVarianceLens: external_exports.number().min(0),
4992
+
4993
+ reattributedFromResidual: external_exports.number(),
4994
+
4995
+ compositeGroupCount: external_exports.number().int().min(1),
4996
+
4997
+ bracketedFacets: external_exports.array(external_exports.string()),
4998
+
4999
+ bracketedFacetLevels: external_exports.array(external_exports.object({ facet: external_exports.string(), distinctLevels: external_exports.number().int().min(1) })).optional(),
5000
+
5001
+ conservationHolds: external_exports.boolean(),
5002
+
5003
+ partitionRelationship: external_exports.enum([
5004
+ "degenerate",
5005
+ "identical",
5006
+ "judge-refines-version",
5007
+ "version-refines-judge",
5008
+ "cross-cutting"
5009
+ ])
5010
+ });
5011
+ var ApparatusFacetDriftSchema = external_exports.object({
5012
+ facet: external_exports.string(),
5013
+ basis: external_exports.enum(["reserved-namespace", "declared-control"]),
5014
+
5015
+ control: ControlAttributeSchema.optional()
5016
+ });
5017
+ var ApparatusResidualContaminationSchema = external_exports.object({
5018
+
5019
+ contaminated: external_exports.boolean(),
5020
+
5021
+ driftedFacets: external_exports.array(ApparatusFacetDriftSchema),
5022
+
5023
+ scope: external_exports.enum(["reserved-only", "contract-resolved"]).optional()
5024
+ });
4876
5025
  var VarianceDecompositionSchema = external_exports.object({
4877
5026
  dimensionId: DimensionIdSchema,
4878
5027
 
@@ -4903,7 +5052,17 @@ var VarianceDecompositionSchema = external_exports.object({
4903
5052
 
4904
5053
  sigmaAgentCI: VarianceDecompositionConfidenceIntervalSchema,
4905
5054
 
4906
- caveats: external_exports.array(external_exports.string()).default([])
5055
+ caveats: external_exports.array(external_exports.string()).default([]),
5056
+
5057
+ floorFreshness: FloorFreshnessSchema.optional(),
5058
+
5059
+ floorRegion: FloorRegionSchema.optional(),
5060
+
5061
+ lensCompositeCorrection: LensCompositeCorrectionSchema.optional(),
5062
+
5063
+ apparatusResidualContamination: ApparatusResidualContaminationSchema.optional(),
5064
+
5065
+ decompositionMethodVersion: external_exports.string().optional()
4907
5066
  });
4908
5067
  var LifecycleTransitionStatusSchema = external_exports.enum([
4909
5068
  "draft",
@@ -4952,7 +5111,8 @@ var EvalRecommendationVerdictSchema = external_exports.enum([
4952
5111
  "contaminated",
4953
5112
  "insufficient-n",
4954
5113
  "degenerate",
4955
- "instrument-limited"
5114
+ "instrument-limited",
5115
+ "stale-floor"
4956
5116
  ]);
4957
5117
  var EvalRecommendationCheckSchema = external_exports.object({
4958
5118
  name: external_exports.string().min(1).max(128),
@@ -5368,6 +5528,193 @@ external_exports.object({
5368
5528
  external_exports.enum(["classificationMode"]);
5369
5529
  external_exports.enum(["prefix-match", "absent-defaulted"]);
5370
5530
 
5531
+ var RELIABILITY_DISPOSITIONS = ["flagged", "assessed", "not-applicable"];
5532
+ var ReliabilityDispositionSchema = external_exports.enum(RELIABILITY_DISPOSITIONS);
5533
+ var RELIABILITY_FIRING_STAGES = ["config", "score", "window"];
5534
+ var ReliabilityFiringStageSchema = external_exports.enum(RELIABILITY_FIRING_STAGES);
5535
+ var ReliabilityCorpusFindingSchema = external_exports.object({
5536
+
5537
+ entryId: external_exports.string().min(1),
5538
+
5539
+ failureMode: external_exports.string().min(1),
5540
+
5541
+ disposition: ReliabilityDispositionSchema,
5542
+
5543
+ remediation: external_exports.string().min(1).nullable(),
5544
+
5545
+ firesAt: ReliabilityFiringStageSchema,
5546
+
5547
+ tier: external_exports.literal("deterministic"),
5548
+
5549
+ evidence: external_exports.record(external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])).optional()
5550
+ });
5551
+ external_exports.object({
5552
+
5553
+ corpusVersion: external_exports.string().min(1),
5554
+
5555
+ corpusHash: external_exports.string().min(1),
5556
+
5557
+ findings: external_exports.array(ReliabilityCorpusFindingSchema)
5558
+ });
5559
+ var ReliabilityCorpusEntryRateSchema = external_exports.object({
5560
+ entryId: external_exports.string().min(1),
5561
+
5562
+ evaluated: external_exports.number().int().nonnegative(),
5563
+
5564
+ flagged: external_exports.number().int().nonnegative(),
5565
+
5566
+ assessed: external_exports.number().int().nonnegative(),
5567
+
5568
+ notApplicable: external_exports.number().int().nonnegative(),
5569
+
5570
+ firingRateAmongApplicable: external_exports.number().min(0).max(1).nullable()
5571
+ });
5572
+ var ReliabilityCorpusRatesSchema = external_exports.object({
5573
+ corpusVersion: external_exports.string().min(1),
5574
+ corpusHash: external_exports.string().min(1),
5575
+
5576
+ evaluationCount: external_exports.number().int().nonnegative(),
5577
+ perEntry: external_exports.array(ReliabilityCorpusEntryRateSchema)
5578
+ });
5579
+ var TraceClaimCheckSchema = external_exports.object({
5580
+
5581
+ tool: external_exports.string().min(1),
5582
+
5583
+ invoked: external_exports.boolean(),
5584
+ disposition: external_exports.enum(["corroborated", "contradicted"])
5585
+ });
5586
+ var TRACE_CORROBORATION_DISPOSITIONS = [
5587
+ "contradicted",
5588
+ "corroborated",
5589
+ "no-marker-to-check",
5590
+ "not-applicable"
5591
+ ];
5592
+ var TraceCorroborationDispositionSchema = external_exports.enum(TRACE_CORROBORATION_DISPOSITIONS);
5593
+ var TraceCorroborationSchema = external_exports.object({
5594
+
5595
+ disposition: TraceCorroborationDispositionSchema,
5596
+
5597
+ tier: external_exports.literal("deterministic"),
5598
+
5599
+ claims: external_exports.array(TraceClaimCheckSchema)
5600
+ });
5601
+ var MatchTierSchema = external_exports.discriminatedUnion("kind", [
5602
+
5603
+ external_exports.object({ kind: external_exports.literal("exact") }),
5604
+
5605
+ external_exports.object({ kind: external_exports.literal("normalized") }),
5606
+
5607
+ external_exports.object({ kind: external_exports.literal("fuzzy"), threshold: external_exports.number().min(0).max(1) })
5608
+ ]);
5609
+ var GROUNDING_CLAIM_DISPOSITIONS = [
5610
+ "present-in-scope",
5611
+ "truncated-out",
5612
+ "not-found"
5613
+ ];
5614
+ var GroundingClaimDispositionSchema = external_exports.enum(GROUNDING_CLAIM_DISPOSITIONS);
5615
+ var GroundingClaimCheckSchema = external_exports.object({
5616
+
5617
+ datum: external_exports.string().min(1),
5618
+ disposition: GroundingClaimDispositionSchema,
5619
+
5620
+ matchTier: MatchTierSchema.optional(),
5621
+
5622
+ charOffset: external_exports.number().int().nonnegative().optional()
5623
+ });
5624
+ var GROUNDING_COVERAGE_DISPOSITIONS = [
5625
+ "present-in-scope",
5626
+ "truncated-out",
5627
+ "not-found",
5628
+ "no-marker-to-check",
5629
+ "not-applicable"
5630
+ ];
5631
+ var GroundingCoverageDispositionSchema = external_exports.enum(GROUNDING_COVERAGE_DISPOSITIONS);
5632
+ var GroundingCoverageSchema = external_exports.object({
5633
+ disposition: GroundingCoverageDispositionSchema,
5634
+
5635
+ tier: external_exports.literal("deterministic"),
5636
+
5637
+ claims: external_exports.array(GroundingClaimCheckSchema)
5638
+ });
5639
+ var VERDICT_RELIABILITY_TIERS = ["question", "trust", "review"];
5640
+ var VerdictReliabilityTierSchema = external_exports.enum(VERDICT_RELIABILITY_TIERS);
5641
+ external_exports.object({
5642
+
5643
+ tier: VerdictReliabilityTierSchema,
5644
+
5645
+ drivers: external_exports.array(external_exports.string()),
5646
+
5647
+ trace: TraceCorroborationSchema,
5648
+
5649
+ grounding: GroundingCoverageSchema
5650
+ });
5651
+ var VerdictReliabilityTierTallySchema = external_exports.object({
5652
+ question: external_exports.number().int().nonnegative(),
5653
+ trust: external_exports.number().int().nonnegative(),
5654
+ review: external_exports.number().int().nonnegative(),
5655
+ total: external_exports.number().int().nonnegative()
5656
+ });
5657
+ var FlaggedVerdictSchema = external_exports.object({
5658
+
5659
+ eventId: external_exports.string().min(1),
5660
+
5661
+ correlationId: external_exports.string().min(1).optional(),
5662
+
5663
+ occurredAt: external_exports.string().min(1),
5664
+ surfaceId: external_exports.string().min(1),
5665
+ dimensionId: external_exports.string().min(1),
5666
+
5667
+ drivers: external_exports.array(external_exports.string())
5668
+ });
5669
+ external_exports.object({
5670
+
5671
+ eventCount: external_exports.number().int().nonnegative(),
5672
+
5673
+ tierTally: VerdictReliabilityTierTallySchema,
5674
+
5675
+ flagged: external_exports.array(FlaggedVerdictSchema),
5676
+
5677
+ corpusRates: ReliabilityCorpusRatesSchema
5678
+ });
5679
+ var ESCALATION_REASONS = ["both-checks-not-applicable"];
5680
+ var EscalationReasonSchema = external_exports.enum(ESCALATION_REASONS);
5681
+ external_exports.object({
5682
+
5683
+ targetEventId: external_exports.string().min(1),
5684
+ surfaceId: external_exports.string().min(1),
5685
+ dimensionId: external_exports.string().min(1),
5686
+
5687
+ reason: EscalationReasonSchema
5688
+ });
5689
+ var JudgeVerdictSchema = external_exports.object({
5690
+
5691
+ score: external_exports.number().optional(),
5692
+
5693
+ passed: external_exports.boolean()
5694
+ });
5695
+ external_exports.object({
5696
+
5697
+ targetEventId: external_exports.string().min(1),
5698
+ surfaceId: external_exports.string().min(1),
5699
+ dimensionId: external_exports.string().min(1),
5700
+
5701
+ blind: external_exports.literal(true),
5702
+
5703
+ firstVerdict: JudgeVerdictSchema,
5704
+
5705
+ secondVerdict: JudgeVerdictSchema,
5706
+
5707
+ secondJudge: JudgeIdentitySchema,
5708
+
5709
+ secondJudgeInstrumentVersion: external_exports.string().min(1)
5710
+ });
5711
+ external_exports.object({
5712
+ escalatedCount: external_exports.number().int().nonnegative(),
5713
+ agreeCount: external_exports.number().int().nonnegative(),
5714
+ disagreeCount: external_exports.number().int().nonnegative(),
5715
+ agreementRate: external_exports.number().min(0).max(1).nullable()
5716
+ });
5717
+
5371
5718
  var HolonographGradeAfterReportError = class extends Error {
5372
5719
  constructor() {
5373
5720
  super(
@@ -6290,12 +6637,22 @@ var HolonographClient = class {
6290
6637
 
6291
6638
  onUnknownColumn;
6292
6639
 
6640
+ onUnknownColumnExplicit;
6641
+
6642
+ unknownColumnDeprecationWarned = false;
6643
+
6293
6644
  declaredColumns;
6294
6645
 
6295
6646
  warnedColumns = new Set();
6296
6647
 
6297
6648
  refreshedColumnsOnce = false;
6298
6649
 
6650
+ onCoverageDivergence;
6651
+
6652
+ coverageDivergenceChecked = false;
6653
+
6654
+ emitNonBlocking;
6655
+
6299
6656
  messages;
6300
6657
 
6301
6658
  contract;
@@ -6330,6 +6687,9 @@ var HolonographClient = class {
6330
6687
  this.lensVersion = options.lensVersion;
6331
6688
  this.substrate = options.substrate;
6332
6689
  this.onUnknownColumn = isHttpOptions(options) ? options.onUnknownColumn ?? "warn" : "ignore";
6690
+ this.onUnknownColumnExplicit = isHttpOptions(options) && options.onUnknownColumn !== void 0;
6691
+ this.onCoverageDivergence = isHttpOptions(options) ? options.onCoverageDivergence ?? "warn" : "ignore";
6692
+ this.emitNonBlocking = isHttpOptions(options) && options.emit?.mode !== void 0 && options.emit.mode !== "sync";
6333
6693
  this.messages = { create: (req) => this.messagesCreate(req) };
6334
6694
  this.contract = { register: (c) => this.registerContract(c) };
6335
6695
  this.availability = { mark: (req, opts) => this.markAvailability(req, opts) };
@@ -6426,14 +6786,31 @@ var HolonographClient = class {
6426
6786
  (k) => k !== SERVED_MODEL_COLUMN_ID && !k.startsWith(JUDGE_RESERVED_COLUMN_NAMESPACE_PREFIX)
6427
6787
  );
6428
6788
  if (keys.length === 0) return;
6789
+ const apparatusSpellArounds = keys.filter((k) => isApparatusFacetSpelling(k));
6790
+ const substrateKeys = keys.filter((k) => !isApparatusFacetSpelling(k));
6791
+ if (apparatusSpellArounds.length > 0) {
6792
+ if (this.onUnknownColumn === "throw") {
6793
+ throw new Error(
6794
+ `Holonograph: substrate column(s) collide with apparatus-owned lens identity: ${apparatusSpellArounds.join(", ")}. These normalize to columns the apparatus stamps itself (read the 'judge.*' / 'light_source_served_model' columns) \u2014 remove them from your substrate. (onUnknownColumn: 'throw')`
6795
+ );
6796
+ }
6797
+ const toWarn2 = apparatusSpellArounds.filter((k) => !this.warnedColumns.has(k));
6798
+ if (toWarn2.length > 0) {
6799
+ for (const k of toWarn2) this.warnedColumns.add(k);
6800
+ console.warn(
6801
+ `Holonograph: substrate column(s) collide with apparatus-owned lens identity: ${toWarn2.join(", ")}. The apparatus stamps its own identity ('judge.*', 'light_source_served_model'); a substrate look-alike is not read as an axis \u2014 read the apparatus-stamped columns instead. (onUnknownColumn: 'throw' to block, 'ignore' to silence.)`
6802
+ );
6803
+ }
6804
+ }
6805
+ if (substrateKeys.length === 0) return;
6429
6806
  const declared = await this.fetchDeclaredColumns();
6430
6807
  if (declared === null || declared.size === 0) return;
6431
- let unknown = keys.filter((k) => !declared.has(k));
6808
+ let unknown = substrateKeys.filter((k) => !declared.has(k));
6432
6809
  if (unknown.length > 0 && !this.refreshedColumnsOnce) {
6433
6810
  this.refreshedColumnsOnce = true;
6434
6811
  const refreshed = await this.fetchDeclaredColumns(true);
6435
6812
  if (refreshed === null || refreshed.size === 0) return;
6436
- unknown = keys.filter((k) => !refreshed.has(k));
6813
+ unknown = substrateKeys.filter((k) => !refreshed.has(k));
6437
6814
  }
6438
6815
  if (unknown.length === 0) return;
6439
6816
  if (this.onUnknownColumn === "throw") {
@@ -6447,6 +6824,42 @@ var HolonographClient = class {
6447
6824
  console.warn(
6448
6825
  `Holonograph: substrate column(s) declared in no surface contract: ${toWarn.join(", ")}. They are still emitted, but the lens won't recognize them \u2014 declare them on the contract or fix the typo. (onUnknownColumn: 'throw' to block, 'ignore' to silence.)`
6449
6826
  );
6827
+ if (!this.onUnknownColumnExplicit && !this.unknownColumnDeprecationWarned) {
6828
+ this.unknownColumnDeprecationWarned = true;
6829
+ console.warn(
6830
+ `Holonograph: DEPRECATION \u2014 the default onUnknownColumn will change from 'warn' to 'throw' in the next @holonograph/client major, so an undeclared substrate column will be REJECTED rather than logged. Declare your columns on the surface contract, or set onUnknownColumn: 'warn' explicitly to keep warn-and-continue. (This notice fires once.)`
6831
+ );
6832
+ }
6833
+ }
6834
+
6835
+ async maybeSurfaceCoverageDivergence() {
6836
+ const getEmission = this.transport.getEmission?.bind(this.transport);
6837
+ if (this.onCoverageDivergence === "ignore" || this.emitNonBlocking || // never block the fast-resolve emit modes
6838
+ this.coverageDivergenceChecked || getEmission === void 0) {
6839
+ return;
6840
+ }
6841
+ this.coverageDivergenceChecked = true;
6842
+ const audit = await getEmission().catch(() => void 0);
6843
+ if (audit === void 0) return;
6844
+ const undeclared = [];
6845
+ const missing = [];
6846
+ const apparatus = [];
6847
+ for (const surface of audit.surfaces) {
6848
+ for (const col of surface.undeclaredObserved) undeclared.push(`${surface.surfaceId}.${col}`);
6849
+ for (const row of surface.columns) {
6850
+ if (row.verdict === "missing") missing.push(`${surface.surfaceId}.${row.columnId}`);
6851
+ }
6852
+ for (const col of surface.apparatusObserved) apparatus.push(`${surface.surfaceId}.${col}`);
6853
+ }
6854
+ if (undeclared.length === 0 && missing.length === 0) return;
6855
+ const parts = [];
6856
+ if (undeclared.length > 0) parts.push(`emitted-but-undeclared: ${undeclared.join(", ")}`);
6857
+ if (missing.length > 0) {
6858
+ parts.push(`declared-but-never-emitted (missing): ${missing.join(", ")}`);
6859
+ }
6860
+ console.warn(
6861
+ `Holonograph: declared-vs-emitted coverage divergence \u2014 ${parts.join("; ")}. See GET /holonograph/emission for the full audit` + (apparatus.length > 0 ? ` (apparatus columns observed: ${apparatus.join(", ")})` : "") + `. (onCoverageDivergence: 'ignore' to silence.)`
6862
+ );
6450
6863
  }
6451
6864
  async registerContract(contract) {
6452
6865
  if (typeof this.transport.postContract !== "function") {
@@ -6550,6 +6963,7 @@ var HolonographClient = class {
6550
6963
  });
6551
6964
  await this.validateSubstrateColumns(event.substrate?.columns);
6552
6965
  await this.transport.appendEvent(event);
6966
+ await this.maybeSurfaceCoverageDivergence();
6553
6967
  if (callResult.observerRecords && callResult.observerRecords.length > 0) {
6554
6968
  const siblingCohortTags = baseCohortTags;
6555
6969
  for (const observerRecord of callResult.observerRecords) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holonograph/client",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "TypeScript HTTP client for a Holonograph lens. Send messages through the lens and report scored outcomes back to it.",
5
5
  "license": "MIT",
6
6
  "type": "module",