@sunaiva/gate 1.0.0 → 1.1.2
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/BUSINESS_LICENSE.md +70 -0
- package/CHANGELOG.md +254 -0
- package/LICENSE +0 -0
- package/README.md +451 -67
- package/README.md.bak-v1.0.0-stale-MIT +59 -0
- package/SUPPORT.md +75 -0
- package/TIER_DEFINITIONS.md +161 -0
- package/dist/config/defaults.d.ts +22 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +56 -8
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/loader.d.ts +0 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +23 -5
- package/dist/config/loader.js.map +1 -1
- package/dist/engine/backend-client.d.ts +58 -0
- package/dist/engine/backend-client.d.ts.map +1 -0
- package/dist/engine/backend-client.js +287 -0
- package/dist/engine/backend-client.js.map +1 -0
- package/dist/engine/hmac-verifier.d.ts +52 -0
- package/dist/engine/hmac-verifier.d.ts.map +1 -0
- package/dist/engine/hmac-verifier.js +159 -0
- package/dist/engine/hmac-verifier.js.map +1 -0
- package/dist/engine/immutability.d.ts +59 -0
- package/dist/engine/immutability.d.ts.map +1 -0
- package/dist/engine/immutability.js +129 -0
- package/dist/engine/immutability.js.map +1 -0
- package/dist/engine/pattern-matcher.d.ts +13 -0
- package/dist/engine/pattern-matcher.d.ts.map +1 -1
- package/dist/engine/pattern-matcher.js +85 -17
- package/dist/engine/pattern-matcher.js.map +1 -1
- package/dist/engine/rule-engine.d.ts +62 -1
- package/dist/engine/rule-engine.d.ts.map +1 -1
- package/dist/engine/rule-engine.js +224 -12
- package/dist/engine/rule-engine.js.map +1 -1
- package/dist/engine/session-state.d.ts +0 -0
- package/dist/engine/session-state.d.ts.map +1 -1
- package/dist/engine/session-state.js +8 -2
- package/dist/engine/session-state.js.map +1 -1
- package/dist/engine/ship-confidence-gate.d.ts +232 -0
- package/dist/engine/ship-confidence-gate.d.ts.map +1 -0
- package/dist/engine/ship-confidence-gate.js +768 -0
- package/dist/engine/ship-confidence-gate.js.map +1 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.js +293 -2
- package/dist/rules/categories.json +0 -0
- package/dist/rules/presets.json +0 -0
- package/dist/rules/rules.json +132 -64
- package/dist/tools/audit.d.ts +6 -0
- package/dist/tools/audit.d.ts.map +1 -1
- package/dist/tools/audit.js +43 -6
- package/dist/tools/audit.js.map +1 -1
- package/dist/tools/bypass.d.ts +0 -0
- package/dist/tools/bypass.d.ts.map +1 -1
- package/dist/tools/bypass.js +50 -6
- package/dist/tools/bypass.js.map +1 -1
- package/dist/tools/export-attestation.d.ts +45 -0
- package/dist/tools/export-attestation.d.ts.map +1 -0
- package/dist/tools/export-attestation.js +152 -0
- package/dist/tools/export-attestation.js.map +1 -0
- package/dist/tools/rules.d.ts +0 -0
- package/dist/tools/rules.d.ts.map +0 -0
- package/dist/tools/rules.js +0 -0
- package/dist/tools/rules.js.map +0 -0
- package/dist/tools/ship-confidence.d.ts +17 -0
- package/dist/tools/ship-confidence.d.ts.map +1 -0
- package/dist/tools/ship-confidence.js +42 -0
- package/dist/tools/ship-confidence.js.map +1 -0
- package/dist/tools/update.d.ts +0 -0
- package/dist/tools/update.d.ts.map +1 -1
- package/dist/tools/update.js +45 -9
- package/dist/tools/update.js.map +1 -1
- package/dist/tools/validate.d.ts +0 -0
- package/dist/tools/validate.d.ts.map +1 -1
- package/dist/tools/validate.js +56 -4
- package/dist/tools/validate.js.map +1 -1
- package/dist/types/backend.d.ts +69 -0
- package/dist/types/backend.d.ts.map +1 -0
- package/dist/types/backend.js +18 -0
- package/dist/types/backend.js.map +1 -0
- package/package.json +83 -65
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Tier Definitions — `@sunaiva/gate`
|
|
2
|
+
|
|
3
|
+
Feature scope of each tier for the Sunaiva Gate product line. The MCP server
|
|
4
|
+
itself (`@sunaiva/gate` on npm) is free forever and is the top-of-funnel into
|
|
5
|
+
the paid tiers. Paid tiers are tied to the **dashboard subscription** + the
|
|
6
|
+
premium rule backend.
|
|
7
|
+
|
|
8
|
+
> **Pricing**: current pricing is the single source of truth at
|
|
9
|
+
> **https://sunaivacore.io/pricing** — owned by the Sunaiva MCP Command lane,
|
|
10
|
+
> aligned to the Sunaiva Core marketplace pricing model (MCP subscription
|
|
11
|
+
> floor + per-call x402 + skill bundle). This file documents **feature scope
|
|
12
|
+
> per tier** only. Dollar figures intentionally NOT embedded here so the npm
|
|
13
|
+
> package never ships stale pricing.
|
|
14
|
+
|
|
15
|
+
> **Free tier** (no signup) runs the full constitutional rule set locally on
|
|
16
|
+
> your machine. Paid tiers add the hosted dashboard, premium rule evaluation,
|
|
17
|
+
> audit aggregation, and team features. Without a paid tier the gate still
|
|
18
|
+
> enforces every constitutional rule deterministically — you just don't get
|
|
19
|
+
> the dashboard, premium rules, or team views.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Free — `@sunaiva/gate` (npm package, no signup)
|
|
24
|
+
|
|
25
|
+
- **Price**: free forever
|
|
26
|
+
- **License**: BUSL-1.1 wrapper (Change Date `2030-05-10` → Apache-2.0)
|
|
27
|
+
- **Scope**:
|
|
28
|
+
- All 32 constitutional rules evaluated locally (cannot be disabled per the immutability guard)
|
|
29
|
+
- All 68 premium rule slots present but marked `[server-side]` placeholders (no evaluation — requires Pro+)
|
|
30
|
+
- Local audit log at `~/.sunaiva/audit/audit.jsonl`
|
|
31
|
+
- 5 presets (Minimal / Essential / Developer-Safety / Financial-Protection / Full-Suite)
|
|
32
|
+
- Kill-switch (`DISABLE_SUNAIVA_GATE=1`) and dry-run (`SUNAIVA_GATE_DRY_RUN=1`)
|
|
33
|
+
- All 6 MCP tools (`validate_action`, `log_bypass`, `get_rules`, `update_rules`, `get_audit_log`, `ship_confidence_check`)
|
|
34
|
+
- **Support**: best-effort email per `SUPPORT.md`
|
|
35
|
+
- **SLA**: none
|
|
36
|
+
- **Use case**: solo developer running Claude Code / Cursor / Windsurf / Copilot locally and wanting a deterministic safety layer
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Starter
|
|
41
|
+
|
|
42
|
+
Everything in Free, plus:
|
|
43
|
+
|
|
44
|
+
- **Hosted dashboard** — real-time validation activity, audit log search/filter/export, rules manager UI, per-agent integration cards (see `LOVABLE_DASHBOARD_PROMPT.md` in this directory for the spec)
|
|
45
|
+
- **Metered validations per month** (Free tier is locally unmetered; Starter introduces backend-evaluated premium rules with a budget)
|
|
46
|
+
- **Curated subset of premium rules** active — server-side evaluation via `https://mcp.sunaivacore.io/v1/gatehooks` (token-authenticated)
|
|
47
|
+
- **1 connected agent** (Claude Code OR Cursor OR Windsurf OR Copilot — one at a time)
|
|
48
|
+
- **Short-window audit log retention** (see pricing page for current tier limits)
|
|
49
|
+
- **Single user seat**
|
|
50
|
+
- **Email support** with 2 business-day target response
|
|
51
|
+
|
|
52
|
+
**Best for**: solo developers who want the dashboard view + a curated subset of premium rules
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Pro (recommended default)
|
|
57
|
+
|
|
58
|
+
Everything in Starter, plus:
|
|
59
|
+
|
|
60
|
+
- **Higher metered validation budget**
|
|
61
|
+
- **All 68 premium rules** active
|
|
62
|
+
- **5 connected agents** (any mix of Claude Code, Cursor, Windsurf, Copilot, Aider, Codex, Zed)
|
|
63
|
+
- **BYOK support** — bring your own Gemini / Anthropic / OpenRouter API key for the LLM portion of Gate 2 (semantic analysis); or stay on the included Managed Gemini Flash
|
|
64
|
+
- **Mid-window audit log retention**
|
|
65
|
+
- **CSV export** of audit log with all metadata
|
|
66
|
+
- **Webhook support** — POST validation events to your own endpoint
|
|
67
|
+
- **Multiple user seats** (shared dashboard, individual API keys)
|
|
68
|
+
- **Email support** with 1 business-day target response
|
|
69
|
+
|
|
70
|
+
**Best for**: small teams (1-3 developers) with a shared rule set + audit trail need
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Power
|
|
75
|
+
|
|
76
|
+
Everything in Pro, plus:
|
|
77
|
+
|
|
78
|
+
- **Even higher validation budget**
|
|
79
|
+
- **Custom rules** — author your own detection patterns with severity, category, enforcement type; replicated to all team members
|
|
80
|
+
- **Cross-session severity escalation** — warn-first-block-on-repeat state machine persists across sessions, not just per-session
|
|
81
|
+
- **Long-window audit log retention**
|
|
82
|
+
- **Audit log export to S3 / GCS / Azure Blob** on schedule
|
|
83
|
+
- **Larger team seat allocation**
|
|
84
|
+
- **Priority email support** with same-business-day acknowledgement
|
|
85
|
+
- **Sandbox endpoint** for testing rule changes before pushing to production
|
|
86
|
+
|
|
87
|
+
**Best for**: small-to-mid engineering teams (4-10 developers) with custom rule requirements
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Enterprise — contact sales
|
|
92
|
+
|
|
93
|
+
Everything in Power, plus:
|
|
94
|
+
|
|
95
|
+
- **Unlimited validations**
|
|
96
|
+
- **Self-hosted deployment option** (private dashboard + private rule backend; air-gapped if required)
|
|
97
|
+
- **SSO / SAML** via Okta, Azure AD, Google Workspace
|
|
98
|
+
- **Audit log retention**: indefinite, with archive-to-cold-storage policy options
|
|
99
|
+
- **Cryptographic audit export** with HMAC-signed verdicts, byte-compatible with the [`sunaiva-ship-confidence`](https://sunaivacore.io/products/ship-confidence) skill — feeds straight into Ship-Confidence GREEN/RED gates
|
|
100
|
+
- **Large team seat allocation** in the base tier; larger volumes priced per-seat
|
|
101
|
+
- **Custom integration support** — IDE plugins, CI/CD hooks, custom MCP host integration
|
|
102
|
+
- **Dedicated Slack / Teams channel** for support; SLA per the master services agreement
|
|
103
|
+
- **EU AI Act compliance dossier** as an add-on (see [`sunaiva-validation`](https://sunaivacore.io/products/validation) for the Article 9 / 12 / 14 / 15 mapping)
|
|
104
|
+
- **Contractual data-handling commitments** (GDPR DPA, regional data residency)
|
|
105
|
+
|
|
106
|
+
**Engagement**: email `support@sunaiva.ai` with subject `[sales] Enterprise inquiry` to start the conversation. Pricing is quoted per-engagement on the call.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Tier comparison at a glance
|
|
111
|
+
|
|
112
|
+
| Feature | Free | Starter | Pro | Power | Enterprise |
|
|
113
|
+
|---|---|---|---|---|---|
|
|
114
|
+
| 32 constitutional rules (local) | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
115
|
+
| 68 premium rules (server-eval) | — | curated subset | All 68 | All 68 + custom | All 68 + custom |
|
|
116
|
+
| Hosted dashboard | — | ✓ | ✓ | ✓ | ✓ (self-host option) |
|
|
117
|
+
| Validations / month | unmetered (local only) | metered | metered (higher) | metered (highest) | unlimited |
|
|
118
|
+
| Connected agents | unmetered | 1 | 5 | larger team | unlimited |
|
|
119
|
+
| Audit log retention | local only (your disk) | short | mid | long | indefinite |
|
|
120
|
+
| Custom rules | — | — | — | ✓ | ✓ |
|
|
121
|
+
| BYOK (Gemini/Anthropic/OpenRouter) | N/A (no LLM call from free) | — | ✓ | ✓ | ✓ |
|
|
122
|
+
| User seats | 1 (local) | 1 | multiple | larger team | up to enterprise tier |
|
|
123
|
+
| Webhook | — | — | ✓ | ✓ | ✓ |
|
|
124
|
+
| CSV export | — | — | ✓ | ✓ | ✓ |
|
|
125
|
+
| Custom rule packs | — | — | — | ✓ | ✓ |
|
|
126
|
+
| Cross-session severity escalation | per-session | per-session | per-session | ✓ | ✓ |
|
|
127
|
+
| Audit log cloud export | — | — | — | ✓ | ✓ |
|
|
128
|
+
| Sandbox endpoint | — | — | — | ✓ | ✓ |
|
|
129
|
+
| Cryptographic audit export | — | — | — | — | ✓ |
|
|
130
|
+
| SSO / SAML | — | — | — | — | ✓ |
|
|
131
|
+
| Self-hosted option | — | — | — | — | ✓ |
|
|
132
|
+
| EU AI Act compliance dossier | — | — | — | add-on | included |
|
|
133
|
+
| Support response time | best-effort | 2 business days | 1 business day | same business day | dedicated channel + MSA SLA |
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## What is NOT in any tier
|
|
138
|
+
|
|
139
|
+
To set buyer expectations clearly:
|
|
140
|
+
|
|
141
|
+
- **Code review / static analysis** — the gate enforces ACTION-level rules at runtime. It is not a code reviewer. Pair with `sunaiva-ship-confidence` for shipped-artifact verification.
|
|
142
|
+
- **AI model training / fine-tuning** — out of scope. The gate is an enforcement layer, not a model provider.
|
|
143
|
+
- **Network firewall / WAF** — out of scope. The gate operates at the MCP tool-call layer (PreToolUse / PostToolUse / SessionStart events), not the HTTP layer.
|
|
144
|
+
- **Endpoint detection & response (EDR)** — out of scope. Not a host-based security agent.
|
|
145
|
+
- **Production incident response** — out of scope. The gate prevents incidents; it does not respond to them.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Upgrade / downgrade
|
|
150
|
+
|
|
151
|
+
- Self-service: upgrade Starter → Pro → Power via dashboard billing settings (Stripe-managed)
|
|
152
|
+
- Self-service: downgrade with proration via the same flow
|
|
153
|
+
- Enterprise: contractual; transitions handled per the master services agreement
|
|
154
|
+
- **Cancellations**: refund per Stripe's standard policy. Audit logs export to local disk on cancellation (no data lock-in)
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
*Source of truth for pricing: https://sunaivacore.io/pricing — owned by the
|
|
159
|
+
Sunaiva MCP Command lane, aligned to the canonical Sunaiva Core marketplace
|
|
160
|
+
pricing model (MCP subscription floor + per-call x402 + skill bundle).
|
|
161
|
+
This file is feature-scope only.*
|
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default configuration values for @sunaiva/gate
|
|
2
|
+
* Default configuration values for @sunaiva/gate.
|
|
3
|
+
*
|
|
4
|
+
* The active_rules list defaults to the full constitutional set
|
|
5
|
+
* (every rule with `enforcement: "constitutional"` in rules.json).
|
|
6
|
+
* This guarantees that even a user with no on-disk config gets the
|
|
7
|
+
* full local enforcement layer out of the box. Constitutional rules
|
|
8
|
+
* cannot be disabled via `update_rules` (enforced by B4's immutability
|
|
9
|
+
* guard) — they are listed here for explicitness and so that the in-
|
|
10
|
+
* memory config matches the on-disk default that getConfig() writes.
|
|
11
|
+
*
|
|
12
|
+
* To keep this list in sync with rules/rules.json, see
|
|
13
|
+
* `scripts/verify-bundle.js` which asserts that every constitutional
|
|
14
|
+
* rule ID appears in DEFAULT_CONFIG.active_rules at pack time.
|
|
3
15
|
*/
|
|
4
16
|
export declare const CONFIG_DIR: string;
|
|
5
17
|
export declare const CONFIG_PATH: string;
|
|
6
18
|
export declare const AUDIT_LOG_PATH: string;
|
|
19
|
+
/**
|
|
20
|
+
* Every constitutional rule ID (enforcement === "constitutional") shipped
|
|
21
|
+
* in rules/rules.json. Kept as a frozen array so it can be referenced
|
|
22
|
+
* by B4's immutability guard and by the bundle-verify script.
|
|
23
|
+
*
|
|
24
|
+
* UPDATE PROCEDURE: when rules.json gains a new constitutional rule,
|
|
25
|
+
* add its ID here. The verify-bundle script will flag a mismatch.
|
|
26
|
+
*/
|
|
27
|
+
export declare const CONSTITUTIONAL_RULE_IDS: readonly string[];
|
|
7
28
|
export declare const DEFAULT_CONFIG: GateConfig;
|
|
8
29
|
export declare const MANAGED_API_BASE = "https://api.sunaiva.ai/v1/gate";
|
|
9
30
|
export interface ModelConfig {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,eAAO,MAAM,UAAU,QAA8B,CAAC;AACtD,eAAO,MAAM,WAAW,QAAuC,CAAC;AAChE,eAAO,MAAM,cAAc,QAAkC,CAAC;AAE9D;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAiCnD,CAAC;AAEH,eAAO,MAAM,cAAc,EAAE,UAS5B,CAAC;AAEF,eAAO,MAAM,gBAAgB,mCAAmC,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;IACpD,KAAK,EAAE,WAAW,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB"}
|
package/dist/config/defaults.js
CHANGED
|
@@ -1,20 +1,68 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default configuration values for @sunaiva/gate
|
|
2
|
+
* Default configuration values for @sunaiva/gate.
|
|
3
|
+
*
|
|
4
|
+
* The active_rules list defaults to the full constitutional set
|
|
5
|
+
* (every rule with `enforcement: "constitutional"` in rules.json).
|
|
6
|
+
* This guarantees that even a user with no on-disk config gets the
|
|
7
|
+
* full local enforcement layer out of the box. Constitutional rules
|
|
8
|
+
* cannot be disabled via `update_rules` (enforced by B4's immutability
|
|
9
|
+
* guard) — they are listed here for explicitness and so that the in-
|
|
10
|
+
* memory config matches the on-disk default that getConfig() writes.
|
|
11
|
+
*
|
|
12
|
+
* To keep this list in sync with rules/rules.json, see
|
|
13
|
+
* `scripts/verify-bundle.js` which asserts that every constitutional
|
|
14
|
+
* rule ID appears in DEFAULT_CONFIG.active_rules at pack time.
|
|
3
15
|
*/
|
|
4
16
|
import { homedir } from "os";
|
|
5
17
|
import { join } from "path";
|
|
6
18
|
export const CONFIG_DIR = join(homedir(), ".sunaiva");
|
|
7
19
|
export const CONFIG_PATH = join(CONFIG_DIR, "gate-config.json");
|
|
8
20
|
export const AUDIT_LOG_PATH = join(CONFIG_DIR, "audit.jsonl");
|
|
21
|
+
/**
|
|
22
|
+
* Every constitutional rule ID (enforcement === "constitutional") shipped
|
|
23
|
+
* in rules/rules.json. Kept as a frozen array so it can be referenced
|
|
24
|
+
* by B4's immutability guard and by the bundle-verify script.
|
|
25
|
+
*
|
|
26
|
+
* UPDATE PROCEDURE: when rules.json gains a new constitutional rule,
|
|
27
|
+
* add its ID here. The verify-bundle script will flag a mismatch.
|
|
28
|
+
*/
|
|
29
|
+
export const CONSTITUTIONAL_RULE_IDS = Object.freeze([
|
|
30
|
+
"cmp-002",
|
|
31
|
+
"com-001",
|
|
32
|
+
"com-002",
|
|
33
|
+
"com-005",
|
|
34
|
+
"com-006",
|
|
35
|
+
"com-007",
|
|
36
|
+
"com-009",
|
|
37
|
+
"com-011",
|
|
38
|
+
"dat-001",
|
|
39
|
+
"dat-002",
|
|
40
|
+
"dat-004",
|
|
41
|
+
"dat-010",
|
|
42
|
+
"fin-001",
|
|
43
|
+
"fin-002",
|
|
44
|
+
"fin-003",
|
|
45
|
+
"fin-004",
|
|
46
|
+
"fin-008",
|
|
47
|
+
"fin-009",
|
|
48
|
+
"gov-001",
|
|
49
|
+
"gov-002",
|
|
50
|
+
"gov-004",
|
|
51
|
+
"gov-005",
|
|
52
|
+
"gov-006",
|
|
53
|
+
"gov-008",
|
|
54
|
+
"gov-012",
|
|
55
|
+
"know-009",
|
|
56
|
+
"sec-001",
|
|
57
|
+
"sec-002",
|
|
58
|
+
"sec-004",
|
|
59
|
+
"sec-006",
|
|
60
|
+
"sec-010",
|
|
61
|
+
"sec-011",
|
|
62
|
+
]);
|
|
9
63
|
export const DEFAULT_CONFIG = {
|
|
10
64
|
api_key: "",
|
|
11
|
-
active_rules: [
|
|
12
|
-
"fin-001",
|
|
13
|
-
"gov-001",
|
|
14
|
-
"gov-002",
|
|
15
|
-
"dat-001",
|
|
16
|
-
"gov-008",
|
|
17
|
-
],
|
|
65
|
+
active_rules: [...CONSTITUTIONAL_RULE_IDS],
|
|
18
66
|
active_preset: "minimal",
|
|
19
67
|
enforcement_mode: "enforce",
|
|
20
68
|
model: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACtD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAChE,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB,MAAM,CAAC,MAAM,CAAC;IACtE,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,UAAU;IACV,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,OAAO,EAAE,EAAE;IACX,YAAY,EAAE,CAAC,GAAG,uBAAuB,CAAC;IAC1C,aAAa,EAAE,SAAS;IACxB,gBAAgB,EAAE,SAAS;IAC3B,KAAK,EAAE;QACL,QAAQ,EAAE,SAAS;KACpB;IACD,cAAc,EAAE,cAAc;CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC"}
|
package/dist/config/loader.d.ts
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAQA,OAAO,EAA2C,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAGzF,wBAAgB,SAAS,IAAI,UAAU,CAiBtC;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAGhD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C"}
|
package/dist/config/loader.js
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config loader. Constitutional rule IDs are RE-MERGED into active_rules
|
|
3
|
+
* on every load — see `enforceConstitutionalActive` in immutability.ts.
|
|
4
|
+
* This means a user can hand-edit `~/.sunaiva/gate-config.json` to remove
|
|
5
|
+
* constitutional rules and the next runtime load will simply re-add them
|
|
6
|
+
* (in-memory only — the on-disk file is left untouched).
|
|
7
|
+
*/
|
|
1
8
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
2
9
|
import { CONFIG_DIR, CONFIG_PATH, DEFAULT_CONFIG } from "./defaults.js";
|
|
10
|
+
import { enforceConstitutionalActive } from "../engine/immutability.js";
|
|
3
11
|
export function getConfig() {
|
|
12
|
+
let loaded;
|
|
4
13
|
try {
|
|
5
|
-
if (existsSync(CONFIG_PATH))
|
|
6
|
-
|
|
14
|
+
if (existsSync(CONFIG_PATH)) {
|
|
15
|
+
loaded = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
saveConfig(DEFAULT_CONFIG);
|
|
19
|
+
loaded = { ...DEFAULT_CONFIG };
|
|
20
|
+
}
|
|
7
21
|
}
|
|
8
|
-
catch {
|
|
9
|
-
|
|
10
|
-
|
|
22
|
+
catch {
|
|
23
|
+
saveConfig(DEFAULT_CONFIG);
|
|
24
|
+
loaded = { ...DEFAULT_CONFIG };
|
|
25
|
+
}
|
|
26
|
+
// ALWAYS re-merge constitutional active_rules — user tampering of the
|
|
27
|
+
// on-disk file cannot disable a constitutional rule.
|
|
28
|
+
return enforceConstitutionalActive(loaded);
|
|
11
29
|
}
|
|
12
30
|
export function saveConfig(cfg) {
|
|
13
31
|
mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAmB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAmB,MAAM,eAAe,CAAC;AACzF,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAExE,MAAM,UAAU,SAAS;IACvB,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,cAAc,CAAC,CAAC;YAC3B,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,CAAC,cAAc,CAAC,CAAC;QAC3B,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;IACjC,CAAC;IAED,sEAAsE;IACtE,qDAAqD;IACrD,OAAO,2BAA2B,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAe;IACxC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,SAAS,EAAE,CAAC,YAAY,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend client for the Sunaiva Gate premium tier.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - POST to `<backend_url>` for each premium (`[server-side]`) rule.
|
|
6
|
+
* - Fail-OPEN for the *customer*: any backend failure (network, timeout,
|
|
7
|
+
* 5xx, 401, missing token) results in the rule being SKIPPED, never
|
|
8
|
+
* a customer-side block. A Sunaiva outage MUST NOT take down a
|
|
9
|
+
* customer's agent pipeline.
|
|
10
|
+
* - Emit a once-per-process stderr notice when premium rules are skipped
|
|
11
|
+
* because no API token is configured. Subsequent skips in the same
|
|
12
|
+
* process are silent.
|
|
13
|
+
* - One retry with 500ms backoff on 5xx / network error (per spec).
|
|
14
|
+
* - Request timeout default 3000ms, env-overridable.
|
|
15
|
+
* - Track audit counters: every skipped rule appears in
|
|
16
|
+
* `BackendEvalResult.skipped_rule_ids` with a status code in
|
|
17
|
+
* `BackendRuleResult.status` (e.g. `skipped_premium`, `skipped_auth`)
|
|
18
|
+
* so the audit ledger can record exactly why a rule was deferred.
|
|
19
|
+
*
|
|
20
|
+
* What this module does NOT do:
|
|
21
|
+
* - It does NOT decide whether to call the backend at all. That is the
|
|
22
|
+
* caller's job (rule-engine.ts checks rule.backend_required + URL).
|
|
23
|
+
* - It does NOT block. The returned result is informational; the caller
|
|
24
|
+
* turns matched=true with severity=block into a customer-side block.
|
|
25
|
+
* - It does NOT mutate global state apart from the once-per-process
|
|
26
|
+
* stderr flag.
|
|
27
|
+
*/
|
|
28
|
+
import { BackendClientOptions, BackendEvalResult } from "../types/backend.js";
|
|
29
|
+
/**
|
|
30
|
+
* Reset the once-per-process notice flag. Test-only — wired so that test
|
|
31
|
+
* fixtures can assert that the notice fires on the first call but not on
|
|
32
|
+
* subsequent calls within the same process.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resetPremiumSkippedNotice(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Returns true iff the once-per-process notice was emitted. Test-only.
|
|
37
|
+
*/
|
|
38
|
+
export declare function wasPremiumSkippedNoticeShown(): boolean;
|
|
39
|
+
export declare class BackendClient {
|
|
40
|
+
private readonly url;
|
|
41
|
+
private readonly apiToken;
|
|
42
|
+
private readonly timeoutMs;
|
|
43
|
+
private readonly fetchImpl;
|
|
44
|
+
constructor(options?: BackendClientOptions);
|
|
45
|
+
/** True iff the client has an API token configured. */
|
|
46
|
+
isConfigured(): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Evaluate a list of premium rules against `inputText`. Returns one
|
|
49
|
+
* BackendRuleResult per requested rule. Never throws; backend errors
|
|
50
|
+
* become `skipped_*` statuses so the caller can fail-OPEN gracefully.
|
|
51
|
+
*/
|
|
52
|
+
evaluate(ruleIds: string[], inputText: string, context?: Record<string, unknown>): Promise<BackendEvalResult>;
|
|
53
|
+
/** Single-rule call with retry + timeout. */
|
|
54
|
+
private evaluateOne;
|
|
55
|
+
/** Single HTTP call. Returns a tagged outcome — never throws on HTTP. */
|
|
56
|
+
private callOnce;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=backend-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend-client.d.ts","sourceRoot":"","sources":["../../src/engine/backend-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EAOlB,MAAM,qBAAqB,CAAC;AAM7B;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAEtD;AA0CD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,GAAE,oBAAyB;IAkB9C,uDAAuD;IACvD,YAAY,IAAI,OAAO;IAIvB;;;;OAIG;IACG,QAAQ,CACZ,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,iBAAiB,CAAC;IA8C7B,6CAA6C;YAC/B,WAAW;IAgEzB,yEAAyE;YAC3D,QAAQ;CAiFvB"}
|