visiq 0.1.0-aarch64-linux → 0.1.2-aarch64-linux

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff880d1b8f59c8f8af6a81d49511545f8addb24612caf6b208336134626eae65
4
- data.tar.gz: 69a3eca3e9b046a707496818c75eea06682499ce1a5bb8fac75bdfc69fdee170
3
+ metadata.gz: 9e978c98b7d7abd26c143537d76eaa6bce5637d1180aeed084b0f31cc262ed02
4
+ data.tar.gz: 36a5bb504f076b8a075475917a0e153e34416ea42d6d294cd9035c60fb5f3a58
5
5
  SHA512:
6
- metadata.gz: 5a046a1c32d4de7ae66b7c320d5a221458a868e10e31e3fc4b5b6f6d47e209cba1ab6d97dab5e116dc700a7f97c039c00b6ebaef3d043da5795d659e5f12679e
7
- data.tar.gz: 9c6dbe1b3fb49b4e4c94d52f6978972ca34512236c60a2712456ff7621ba078c8256d38eded40c7b11e53670387a1b663391c8f34fb23bf2f5a4357858a9d088
6
+ metadata.gz: 7485991f5b8a6d99879bd1b80023cfa0595c2f6af7ccf636f0a00c522ba7a9287a3c3bb89490fbf1c2641c47aa81598f26ed190cf1d9a7af97bfdc1edbe553fc
7
+ data.tar.gz: 2a22cf69137b715a833a05d7215e8ad853594b448287bb9ef59f88f1d7881ac3d51dbf9b24b0ed9590821612a2e35d14b8bb82fff88bf058adf4b96c5ac16796
data/README.md CHANGED
@@ -1,12 +1,17 @@
1
1
  # visiq — VisIQ agent-governance SDK for Ruby
2
2
 
3
- Local, in-process governance decisions for AI agents. ONE compiled Rust core
4
- (Path B) makes the **same** decisions as the shipped TypeScript SDK
5
- (`@visiq/harness`), bound to Ruby through the stdlib `Fiddle` FFI. The engine
3
+ Returns a `permit`, `deny`, `approval_required`, `redact`, `escalate`, or `mask`
4
+ decision for a tool call or retrieval **before your application executes it**
5
+ your code acts on the verdict; this SDK does not block for you. Decisions are made
6
+ in-process by the compiled VisIQ core that every VisIQ SDK shares (the same engine
7
+ behind `@visiq/harness`), bound to Ruby through the stdlib `Fiddle` FFI. The engine
6
8
  ships as **compiled machine code** (closed); the Ruby is thin FFI plumbing only.
7
9
 
8
10
  - **Local & fast** — every decision is in-process, no network.
9
- - **Fails closed (G001)** — malformed input, or a core that can't load, denies.
11
+ - **Fail-open by default (G001 rescope, owner 2026-07-15)** — a harness-internal
12
+ failure (the core can't load, an FFI error) returns a loud fail-open permit;
13
+ set `VISIQ_FAIL_MODE=closed` to block instead. Malformed input and explicit
14
+ policy denials always block.
10
15
  - **Cross-language parity** — reproduces the exact decisions of the TS/Python/…
11
16
  SDKs from the same core, verified against a shared corpus.
12
17
 
data/lib/visiq.rb CHANGED
@@ -2,13 +2,16 @@
2
2
 
3
3
  # VisIQ agent-governance SDK (Ruby) — local, in-process policy decisions.
4
4
  #
5
- # ONE compiled Rust core (Path B) makes the SAME decisions as the shipped
6
- # TypeScript SDK (`@visiq/harness`). This gem is a thin binding over the core's
5
+ # Governance evaluation has ONE source of truth the compiled Rust core and
6
+ # every VisIQ SDK evaluates through it rather than reimplementing the rules, which
7
+ # is what keeps decisions identical across languages; a shared conformance corpus
8
+ # is what enforces that. This gem is a thin binding over the core's
7
9
  # language-neutral C-ABI seam (`visiq_evaluate`/`visiq_free`) via Ruby's stdlib
8
10
  # `Fiddle` — zero runtime gem dependencies. The engine is compiled machine code;
9
11
  # the gem ships the shared library CLOSED (the Ruby is only FFI plumbing, no
10
- # policy). Every decision is local (no network) and fails closed on malformed
11
- # input (G001).
12
+ # policy). Every decision is local (no network); a harness-internal failure is
13
+ # routed by VISIQ_FAIL_MODE (default "open" — see #fail_mode below), while
14
+ # malformed input and explicit policy denials always block (G001 rescope).
12
15
  #
13
16
  # require "visiq"
14
17
  # d = Visiq.gate_action(bundle, tool_name: "wire_transfer", args: { "amount" => 999 }, agent_id: "a")
@@ -20,7 +23,27 @@ require "json"
20
23
  require "rbconfig"
21
24
 
22
25
  module Visiq
23
- VERSION = "0.1.0"
26
+ # 0.1.1 -> 0.1.2 republishes the SAME Ruby source against a REBUILT core.
27
+ #
28
+ # WHY A BUMP IS THE FIX. `sdk-published-freshness.yml` replays the current oracle
29
+ # corpus through each PUBLISHED artifact's own bundled core. The gem at 0.1.1
30
+ # reproduces 133 of 135 vectors: it predates the source-3 named-detector work, so
31
+ # its core never fills `write.data_categories`, a customer rule of the form
32
+ # `mask { "pii" in input.normalized.write.data_categories }` abstains, and the
33
+ # no-coverage floor denies the write instead of masking it. Fail-closed, but wrong
34
+ # — a customer who asked for redaction gets a hard denial (D-WRITE-DENY).
35
+ #
36
+ # The Ruby source needs no change; only a REBUILD does, and `rubygems-publish.yml`
37
+ # compiles the C-ABI core from current source on every publish. Its version guard
38
+ # reads the gemspec (which reads this constant), so an unchanged version is a
39
+ # whole-pipeline no-op — which is exactly why the lane has been red since
40
+ # 2026-08-01 with a landed fix that could never ship. Bumping is the trigger.
41
+ #
42
+ # NOT COUPLED TO THE PYTHON HOLD. visiq-core-rs stays pinned at 0.2.4 for the
43
+ # Semantic-Kernel adapter defect (see its Cargo.toml). That hold gates the PyPI
44
+ # wheel, which ships the core's own version; Ruby and Java version independently
45
+ # and are not implicated. Bumping here does not resume the Python release.
46
+ VERSION = "0.1.2"
24
47
 
25
48
  # Low-level binding to the compiled core over the C-ABI seam.
26
49
  module Core
@@ -86,10 +109,44 @@ module Visiq
86
109
 
87
110
  module_function
88
111
 
112
+ # Error posture (owner decision 2026-07-15, G001 rescope): a harness-internal
113
+ # failure (the compiled core cannot load, an FFI error) is routed by
114
+ # VISIQ_FAIL_MODE — "open" (DEFAULT): return a loud fail-open permit so a
115
+ # VisIQ packaging/outage bug never disrupts the agent; "closed": raise as
116
+ # before. Policy outcomes from a successful evaluation are unaffected.
117
+ def fail_mode
118
+ raw = ENV["VISIQ_FAIL_MODE"].to_s.strip.downcase
119
+ %w[open closed].include?(raw) ? raw : "open"
120
+ end
121
+
122
+ # A non-enforced permit decision naming the failure cause — the fail-open
123
+ # counterpart of the core's decisions, mirrored from the TS runtime.
124
+ def fail_open_decision(operations, cause)
125
+ warn "[VisIQ] FAIL-OPEN (core-error): #{cause} — proceeding UNGOVERNED. " \
126
+ "Set VISIQ_FAIL_MODE=closed to block instead."
127
+ has_action = operations.include?("action") || operations.include?("delegation")
128
+ has_retrieval = operations.include?("retrieval")
129
+ {
130
+ "decision" => "permit",
131
+ "allowed" => true,
132
+ "reason" => "fail-open: #{cause} — proceeding UNGOVERNED (set VISIQ_FAIL_MODE=closed to block instead)",
133
+ "ruleId" => nil,
134
+ "ruleCode" => nil,
135
+ "enforced" => false,
136
+ "action" => has_action ? { "decision" => "permit", "allowed" => true } : { "decision" => nil, "allowed" => true },
137
+ "retrieval" => has_retrieval ? { "action" => "allow" } : { "action" => nil }
138
+ }
139
+ end
140
+
89
141
  # Evaluate one governed agent event against a rules bundle. Returns the
90
142
  # UnifiedDecision hash: {"decision","allowed","action","retrieval"}.
91
143
  def decide(event, bundle)
92
144
  JSON.parse(Core.evaluate_json(JSON.generate(event), JSON.generate(bundle)))
145
+ rescue StandardError, Fiddle::DLError => e
146
+ # Core load / FFI / parse failure — a HARNESS error, never a policy one.
147
+ raise if fail_mode == "closed"
148
+
149
+ fail_open_decision(event["operations"] || [], e.message)
93
150
  end
94
151
 
95
152
  # Gate a tool/action call. Check ["allowed"]; on "mask" apply
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: visiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - VisIQ Labs Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-08 00:00:00.000000000 Z
11
+ date: 2026-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fiddle
@@ -24,10 +24,12 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
- description: ONE compiled Rust core (Path B) that reproduces the shipped TypeScript
28
- SDK's decisions, bound to Ruby via a stdlib Fiddle FFI. Fully local; fails closed
29
- on malformed input (G001). The engine ships as compiled machine code (closed); the
30
- Ruby is thin FFI plumbing only.
27
+ description: VisIQ agent-governance SDK for Ruby returns a permit, deny, approval_required,
28
+ redact, escalate, or mask decision for a tool call or retrieval before your application
29
+ executes it, evaluated in-process by the compiled VisIQ core that every VisIQ SDK
30
+ shares. Installs with no compiler toolchain on macOS and Linux, x86_64 and arm64,
31
+ with no Windows gem; malformed input denies, and core-load failures follow VISIQ_FAIL_MODE,
32
+ which defaults to open.
31
33
  email:
32
34
  - dev@visiqlabs.com
33
35
  executables: []
@@ -65,5 +67,5 @@ requirements: []
65
67
  rubygems_version: 3.5.22
66
68
  signing_key:
67
69
  specification_version: 4
68
- summary: VisIQ agent-governance SDK local, in-process policy decisions.
70
+ summary: VisIQ agent-governance SDK for Ruby
69
71
  test_files: []