@visiq/harness SDK (and its Python peer visiq). The
SDK is pre-1.0 (0.x): there is no wire-compatibility guarantee yet, and
breaking changes may ship in any minor release until v1.0 GA. Pin an exact
version and read the Breaking / Removed entries below before upgrading — see
SDK versioning & compatibility for the full posture.
Canonical source. The registry version history is the authoritative record of
what is live: npmjs.com/package/@visiq/harness.
Check it rather than this page for the current build — these notes are
hand-maintained and have run behind the registry before (
0.2.7 and 0.2.8
published with no entry here). The package’s own CHANGELOG.md lives in the repo
and is not shipped inside the tarball, whose files allowlist is
dist, README.md and LICENSE.0.2.10
Metadata only — no runtime behaviour changed. The package description was rewritten onto one shape shared across the whole VisIQ harness/SDK family (npm, PyPI, Maven Central, RubyGems), so every package now describes itself in the current action-governance / retrieval-governance / audit-trail vocabulary. No API, decision, or wire change — a republish is required only because registry metadata is frozen at publish time.Why this is
0.2.10 and not 0.2.9. The rewrite was authored against
0.2.9, but a concurrent promotion published 0.2.9 from a tree that did not
yet contain it. A published version is immutable, so 0.2.9 on the registry
carries the OLD description permanently and the rewrite needed the next number.
The same collision hit @visiq/openclaw-plugin (0.1.10 → 0.1.11) and
@visiq/claude-code-harness (0.1.5 → 0.1.6). NPM Content Freshness
is the gate that caught it: it rebuilds each would-be-published tarball and
compares its whole content hash against the registry artifact at the same
version, so “edited but not bumped” fails a PR instead of silently no-op’ing at
publish time.0.2.7 and 0.2.8 shipped without an entry on this page. Their contents are in
the git history; this note records the gap rather than reconstructing them.0.2.6
Republish note. The security and compatibility changes below were merged
after
0.2.5 was published (2026-07-12) but no version bump followed, so 0.2.5
on the registry does not contain them. 0.2.6 is the first published build
that ships them. (Versions 0.2.1–0.2.5 are backfilled separately.)Changed
- Fail-closed on an unrecognized retrieval outcome (security). The retrieval
application layer now withholds content — drops the document or returns the
blocked sentinel — on any outcome verb this build does not recognize, instead
of passing it through. This is defense-in-depth behind the engine’s own
fail-closed mapping;
allow/escalatepassthrough is unchanged. An unaware upgrader gets strictly safer behavior. - Every control-plane request now carries
X-VisIQ-SDK(version) andX-VisIQ-Dialect(wire-contract capability) headers. Telemetry only — not load-bearing for any decision. - MUST-UNDERSTAND bundle refuse. A rule bundle that declares a
min_dialectnewer than this SDK speaks is refused wholesale (fail-closed, deny-all) rather than partially applied. Dormant today (min_dialectis1everywhere); it is the forward-compatibility safety net for the first wire-contract bump. The refuse also lives in the shared engine (@visiq/core-wasm ^0.1.3) so every language binding enforces it uniformly.
Removed
- Breaking — the
@visiq/harness/recordsubpath export is removed. The audit layer is now a server-side proof layer only: every action and retrieval decision is automatically signed (Ed25519) and persisted by the backend. No SDK import is required to produce or read receipts — query the dashboard or the REST API instead. The previous types (RecordEnvelope,RecordSource,RecordDecisionPayload,SigningResult,ReceiptVerificationInput) have been deleted from the SDK.
Deprecated
- The
recall_receiptsPostgres view is deprecated in favor of queryingdecision_receiptswithsource = 'recall'for complete, consistent views across all decision sources. The view is retained for backward compatibility and will be removed in a future release.
0.2.0
Added
AgentVendorunion type ('visiq' | 'crowdstrike' | 'intune' | 'sentinelone' | 'unknown').FleetInstance.last_scanned: string | null— ISO timestamp of the last per-instance heartbeat.FleetInstance.agent_vendor: AgentVendor— vendor of the agent reporting heartbeats for the instance.HeartbeatInput { instanceId: string; vendor: AgentVendor }input type forfleet.heartbeat().HeartbeatResponse.instance_id— echoes the heartbeated instance id back to the caller.
Breaking
fleet.heartbeat()now requires aHeartbeatInputargument ({ instanceId, vendor }). Callers that previously invokedfleet.heartbeat()with no arguments must iteratefleet.status().instancesand call once per instance.
Where to look next
Versioning & compatibility
The full pre-1.0 posture, the invariants held even at 0.x, and the v1.0
compatibility window.
SDK Reference
The
visiq() surface, options, framework detection, and error behavior.