@securecoms/agent-bridge 0.9.0 → 0.11.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.
- package/dist/bin.js +386 -68
- package/dist/bridge-agent.d.ts +74 -0
- package/dist/index.js +386 -68
- package/package.json +1 -1
package/dist/bridge-agent.d.ts
CHANGED
|
@@ -674,6 +674,58 @@ export declare class BridgeAgent {
|
|
|
674
674
|
* the other enclaves in the set.
|
|
675
675
|
*/
|
|
676
676
|
private refreshChannelMeta;
|
|
677
|
+
/** Cache for the server-side enclave enumeration (see enclavesToCover). */
|
|
678
|
+
private enclaveEnumCache;
|
|
679
|
+
/** Enclaves whose channel listing failed on the NEWEST sweep (audit HIGH:
|
|
680
|
+
* skip-one deleted the sweep's partial-coverage signal — observations_stale
|
|
681
|
+
* is a global max, so one healthy enclave masked a failed one). Surfaced on
|
|
682
|
+
* health() so partial coverage is never silent. */
|
|
683
|
+
private sweepEnclavesFailed;
|
|
684
|
+
/** Enclave ids whose channel listing has EVER succeeded this process, seeded
|
|
685
|
+
* with HOME (home is always expected to list; without the seed, a home
|
|
686
|
+
* failure right after a restart would read as "never succeeded" and slip
|
|
687
|
+
* through the expected-gap branch — weaker than the old abort-on-failure).
|
|
688
|
+
* A failure of a member of this set is a REGRESSION and degrades health; a
|
|
689
|
+
* failure of a never-succeeded enclave (partner: tenant-scoped 404, permanent
|
|
690
|
+
* pending backend authz) is an EXPECTED gap — reported, not degrading, or
|
|
691
|
+
* every federated agent would peg degraded forever. */
|
|
692
|
+
private readonly enclaveListEverSucceeded;
|
|
693
|
+
/** Warn-once-per-failure-streak, keyed by enclave id (cleared on success):
|
|
694
|
+
* a permanently-404ing partner enclave must not log 1440 lines a day. */
|
|
695
|
+
private readonly enclaveListWarned;
|
|
696
|
+
private static readonly ENCLAVE_ENUM_TTL_MS;
|
|
697
|
+
private enclaveEnumWarned;
|
|
698
|
+
/**
|
|
699
|
+
* C1 (split-brain Task 3): every enclave this agent must COVER — for the
|
|
700
|
+
* self-heal sweep and for channel-meta refresh alike. ONE helper on purpose:
|
|
701
|
+
* these two call sites had drifted (refreshChannelMeta looped home+learned,
|
|
702
|
+
* selfHealSweep looped nothing), and the drift is exactly what left both
|
|
703
|
+
* production agents with zero recovery coverage in their second enclave.
|
|
704
|
+
*
|
|
705
|
+
* The set is SERVER enumeration ∪ home ∪ store-learned:
|
|
706
|
+
*
|
|
707
|
+
* - SERVER (`GET /api/v1/enclaves`, membership-scoped, federated included)
|
|
708
|
+
* is the authoritative source. The store CANNOT be: channel_meta's only
|
|
709
|
+
* writers are listChannels itself (circular — you learn enclave B by
|
|
710
|
+
* having already listed B) and the receive pump's successfully-decrypted
|
|
711
|
+
* loop, and a FORKED agent decrypts nothing, so the agent that most needs
|
|
712
|
+
* sweeping in enclave B is precisely the one whose store never learned B.
|
|
713
|
+
* - home + learned stay in the union as the degraded-mode floor: if the
|
|
714
|
+
* enumeration endpoint is down, we sweep what we can rather than nothing,
|
|
715
|
+
* and we warn (once) so the gap is diagnosable.
|
|
716
|
+
*
|
|
717
|
+
* The server result is cached for ENCLAVE_ENUM_TTL_MS so per-ingest-cycle
|
|
718
|
+
* callers (refreshChannelMeta) do not add an HTTP round-trip per cycle;
|
|
719
|
+
* membership changes are picked up within one TTL, which matches the sweep
|
|
720
|
+
* cadence this exists to serve.
|
|
721
|
+
*
|
|
722
|
+
* ⚠️ Residual gap, stated: the enumeration RETURNS cross-tenant partner
|
|
723
|
+
* enclaves, but `list_channels_in_enclave` is tenant-scoped and 404s them
|
|
724
|
+
* under this agent's bearer — so a partner enclave in this set still yields
|
|
725
|
+
* no channels. Callers must treat a per-enclave listing failure as skip-one,
|
|
726
|
+
* never abort-all. Closing that needs backend authz work, not daemon work.
|
|
727
|
+
*/
|
|
728
|
+
private enclavesToCover;
|
|
677
729
|
/** A live roster for a channel, or undefined if missing OR expired past the TTL. */
|
|
678
730
|
private freshRoster;
|
|
679
731
|
/**
|
|
@@ -799,6 +851,12 @@ export declare class BridgeAgent {
|
|
|
799
851
|
rate_limited: number;
|
|
800
852
|
/** Cumulative inbound rows acked-and-dropped because they were provably past-epoch undecryptable (forward-secrecy secret gone). */
|
|
801
853
|
permanently_skipped: number;
|
|
854
|
+
/** SDK-6: cumulative rows ack-drained via QUARANTINE, distinct from the
|
|
855
|
+
* same-group past-epoch permanently_skipped drain. */
|
|
856
|
+
quarantine_drained: number;
|
|
857
|
+
/** SDK-6: cumulative rows ack-drained because their group_id is RETIRED for
|
|
858
|
+
* the channel (superseded fork-loser traffic). */
|
|
859
|
+
retired_drained: number;
|
|
802
860
|
/** Track 5: cumulative artifact_share messages where download/decrypt/digest failed (fail-soft — acked, no redeliver). */
|
|
803
861
|
failed_attachments: number;
|
|
804
862
|
/** 2026-07-03 latency triage: delivery pings received on the WS stream.
|
|
@@ -836,6 +894,12 @@ export declare class BridgeAgent {
|
|
|
836
894
|
degraded: boolean;
|
|
837
895
|
/** M6: per-channel observations, newest sweep. Read from cache; no I/O. */
|
|
838
896
|
channels: ChannelObservation[];
|
|
897
|
+
/** C1: enclaves whose channel listing failed on the newest sweep. Non-empty
|
|
898
|
+
* means partial coverage — those enclaves' channels were NOT probed. A
|
|
899
|
+
* PREVIOUSLY-SUCCEEDING (or home) entry also flips `degraded`; a
|
|
900
|
+
* never-succeeded entry (partner enclave, tenant-scoped 404) is reported
|
|
901
|
+
* here without degrading. */
|
|
902
|
+
sweep_enclaves_failed: string[];
|
|
839
903
|
/** Optional memory-adapter counters (e.g. Hermes provider); present only when the active provider exposes stats(). */
|
|
840
904
|
hermes_no_session?: number;
|
|
841
905
|
hermes_skipped?: number;
|
|
@@ -882,9 +946,19 @@ export declare class BridgeAgent {
|
|
|
882
946
|
filteredRoomMessages: number;
|
|
883
947
|
rateLimitedSends: number;
|
|
884
948
|
permanentlySkipped: number;
|
|
949
|
+
/** SDK-6: cumulative rows ack-drained via QUARANTINE, distinct from the
|
|
950
|
+
* same-group past-epoch permanentlySkipped drain. */
|
|
951
|
+
quarantineDrained: number;
|
|
952
|
+
/** SDK-6: cumulative rows ack-drained because their group_id is RETIRED for
|
|
953
|
+
* the channel (superseded fork-loser traffic). */
|
|
954
|
+
retiredDrained: number;
|
|
885
955
|
welcomeRequestsSent: number;
|
|
886
956
|
/** Track 5: cumulative artifact_share failures (download/decrypt/digest). */
|
|
887
957
|
failedAttachments: number;
|
|
958
|
+
/** SDK-6: bridge build id, so a /v1/metrics reading captured across a daemon
|
|
959
|
+
* restart can be attributed to a version — counters are process-lifetime
|
|
960
|
+
* and zero on restart (spec §5.5). */
|
|
961
|
+
build: string;
|
|
888
962
|
};
|
|
889
963
|
close(): Promise<void>;
|
|
890
964
|
}
|