Skip to content

Commit fec55fe

Browse files
Illia Pashkovclaude
authored andcommitted
feat: OATR registration + conformance fixtures + discovery endpoint
- Add /.well-known/agent-trust.json endpoint (OATR domain verification) for sint-protocol issuer registration at FransDevelopment/open-agent-trust-registry - Add bridge-iot + bridge-mcp + bridge-ros2 to conformance-tests tsconfig.json so security-iot-fixtures-conformance tests resolve properly - Stage all background agent work: ASI04/ASI05, MQTT session, SPAI polish, conformance fixtures (supply-chain, mqtt-gateway), persistence certs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 476d208 commit fec55fe

31 files changed

Lines changed: 1685 additions & 247 deletions

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ jobs:
6060
- name: Build
6161
run: pnpm run build
6262

63+
- name: Fixture Certification Gate
64+
run: pnpm run cert:fixtures
65+
6366
- name: Typecheck
6467
run: pnpm run typecheck
6568

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,17 +125,20 @@ where each Δ ∈ {0, +1}: human presence detected, trust score below threshold,
125125
| [`@sint/bridge-mcp`](packages/bridge-mcp) | MCP tool call interception and risk classification | 43 |
126126
| [`@sint/bridge-ros2`](packages/bridge-ros2) | ROS 2 topic/service/action interception with physics extraction | 20 |
127127
| [`@sint/bridge-a2a`](packages/bridge-a2a) | Google A2A Protocol bridge for multi-agent coordination | 24 |
128+
| [`@sint/bridge-iot`](packages/bridge-iot) | Generic MQTT/CoAP edge IoT bridge with gateway session interception | 9 |
128129
| [`@sint/bridge-mqtt-sparkplug`](packages/bridge-mqtt-sparkplug) | MQTT Sparkplug profile mapping with industrial command tiering defaults | 8 |
129130
| [`@sint/bridge-opcua`](packages/bridge-opcua) | OPC UA node/method mapping with safety-critical write/call promotion | 6 |
130131
| [`@sint/bridge-open-rmf`](packages/bridge-open-rmf) | Open-RMF fleet/facility mapping for warehouse dispatch workflows | 5 |
131132
| [`@sint/bridge-economy`](packages/bridge-economy) | Economy bridge: balance, budget, trust, billing ports | 55 |
132133
| [`@sint/persistence`](packages/persistence) | Storage interfaces + in-memory/PG/Redis implementations | 26 |
134+
| [`@sint/persistence-postgres`](packages/persistence-postgres) | Production PostgreSQL adapters for ledger, revocation, and rate-limit durability | 13 |
133135
| [`@sint/client`](packages/client) | TypeScript SDK for the Gateway API (delegation, SSE) | 12 |
136+
| [`@sint/sdk`](sdks/typescript) | Zero-dependency public TypeScript SDK aligned to gateway v0.2 contracts | 10 |
134137
| [`@sint/conformance-tests`](packages/conformance-tests) | Security regression suite — all phases | 77 |
135138
| [`@sint/gateway-server`](apps/gateway-server) | Hono HTTP API with approvals, SSE streaming, A2A routes | 57 |
136139
| [`@sint/mcp`](apps/sint-mcp) | Security-first multi-MCP proxy server | 90 |
137140
| [`@sint/dashboard`](apps/dashboard) | Real-time approval dashboard with operator auth | 29 |
138-
| **Total** | **17 packages** | **Workspace-wide conformance suite** |
141+
| **Total** | **20 packages** | **Workspace-wide conformance suite** |
139142

140143
## Quick Start
141144

@@ -170,10 +173,24 @@ pnpm --filter @sint/gateway-server dev
170173
- Multi-language SDK starters:
171174
- [`sdks/python/sint_client.py`](sdks/python/sint_client.py)
172175
- [`sdks/go/sintclient/client.go`](sdks/go/sintclient/client.go)
176+
- [`sdks/typescript`](sdks/typescript)
173177
- Benchmark report automation:
174178
- Script: [`scripts/generate-industrial-benchmark-report.mjs`](scripts/generate-industrial-benchmark-report.mjs)
175179
- CI workflow: [`.github/workflows/industrial-benchmark-report.yml`](.github/workflows/industrial-benchmark-report.yml)
176180
- Generated artifacts: [`docs/reports/industrial-benchmark-report.md`](docs/reports/industrial-benchmark-report.md)
181+
- Canonical conformance fixtures (for external interop/certification):
182+
- [`packages/conformance-tests/fixtures/industrial/warehouse-move-equivalence.v1.json`](packages/conformance-tests/fixtures/industrial/warehouse-move-equivalence.v1.json)
183+
- [`packages/conformance-tests/fixtures/industrial/opcua-safety-control.v1.json`](packages/conformance-tests/fixtures/industrial/opcua-safety-control.v1.json)
184+
- [`packages/conformance-tests/fixtures/protocol/well-known-sint.v0.2.example.json`](packages/conformance-tests/fixtures/protocol/well-known-sint.v0.2.example.json)
185+
- [`packages/conformance-tests/fixtures/persistence/postgres-adapter-cert.v1.json`](packages/conformance-tests/fixtures/persistence/postgres-adapter-cert.v1.json)
186+
- [`packages/conformance-tests/fixtures/security/supply-chain-verification.v1.json`](packages/conformance-tests/fixtures/security/supply-chain-verification.v1.json)
187+
- [`packages/conformance-tests/fixtures/iot/mqtt-gateway-session.v1.json`](packages/conformance-tests/fixtures/iot/mqtt-gateway-session.v1.json)
188+
- Fixture gates:
189+
- `pnpm --filter @sint/conformance-tests run test:fixtures`
190+
- `pnpm --filter @sint/bridge-iot run test:fixtures`
191+
- `pnpm --filter @sint/sdk run test:contracts`
192+
- `pnpm --filter @sint/persistence-postgres run test:fixtures`
193+
- `pnpm run cert:fixtures`
177194

178195
## Approval Tiers
179196

apps/gateway-server/src/routes/discovery.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ import {
2424
export function discoveryRoutes(): Hono {
2525
const app = new Hono();
2626

27+
// OATR domain verification — proves ownership of sint-protocol public key
28+
// Required by FransDevelopment/open-agent-trust-registry CI pipeline
29+
app.get("/.well-known/agent-trust.json", (c) => {
30+
return c.json({
31+
issuer_id: "sint-protocol",
32+
public_key_fingerprint: "sint-registry-2026-04",
33+
});
34+
});
35+
2736
app.get("/.well-known/sint.json", (c) => {
2837
return c.json({
2938
name: "SINT Protocol",

apps/sint-mcp/__tests__/integration.test.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ function createIntegrationSetup() {
4040
content: [{ type: "text", text: `FS:${params.name}:ok` }],
4141
}) } as unknown as Client;
4242

43-
const shellClient = { callTool: async (params: any) => ({
44-
content: [{ type: "text", text: `SHELL:${params.name}:ok` }],
43+
const plannerClient = { callTool: async (params: any) => ({
44+
content: [{ type: "text", text: `PLANNER:${params.name}:ok` }],
4545
}) } as unknown as Client;
4646

4747
const dbClient = { callTool: async (params: any) => ({
@@ -60,12 +60,12 @@ function createIntegrationSetup() {
6060
{ policy: { maxTier: "T2_act" } },
6161
);
6262

63-
// Shell server (requires approval for all)
63+
// Planner server (requires approval for all non-observe actions)
6464
downstream.addConnectedClient(
65-
"shell",
66-
shellClient,
65+
"planner",
66+
plannerClient,
6767
[
68-
{ name: "run", description: "Run a command", inputSchema: { type: "object" } },
68+
{ name: "runPlan", description: "Execute a prepared plan", inputSchema: { type: "object" } },
6969
],
7070
{ policy: { requireApproval: true } },
7171
);
@@ -108,7 +108,7 @@ describe("Integration: Full SINT MCP Flow", () => {
108108
"filesystem__deleteFile",
109109
"filesystem__readFile",
110110
"filesystem__writeFile",
111-
"shell__run",
111+
"planner__runPlan",
112112
]);
113113
});
114114

@@ -139,21 +139,21 @@ describe("Integration: Full SINT MCP Flow", () => {
139139
expect(result.result!.content[0]!.text).toBe("DB:query:ok");
140140
});
141141

142-
it("shell server with requireApproval forces escalation", async () => {
142+
it("requireApproval server forces escalation", async () => {
143143
const { enforcer, approvalQueue } = createIntegrationSetup();
144144

145-
const parsed = parseNamespace("shell__run");
146-
const enforcePromise = enforcer.enforce(parsed!, { command: "ls -la" });
145+
const parsed = parseNamespace("planner__runPlan");
146+
const enforcePromise = enforcer.enforce(parsed!, { task: "pick-and-place" });
147147

148148
// Wait for the approval to be enqueued
149149
await new Promise((r) => setTimeout(r, 50));
150150

151151
const pending = approvalQueue.getPending();
152152
expect(pending.length).toBeGreaterThan(0);
153153

154-
// The pending request should reference the shell server
154+
// The pending request should reference the requireApproval server
155155
const req = pending[0]!;
156-
expect(req.request.resource).toBe("mcp://shell/run");
156+
expect(req.request.resource).toBe("mcp://planner/runPlan");
157157

158158
// Approve it
159159
approvalQueue.resolve(req.requestId, {
@@ -164,14 +164,14 @@ describe("Integration: Full SINT MCP Flow", () => {
164164
const result = await enforcePromise;
165165
expect(result.allowed).toBe(true);
166166
expect(result.approvalRequestId).toBeDefined();
167-
expect(result.result!.content[0]!.text).toBe("SHELL:run:ok");
167+
expect(result.result!.content[0]!.text).toBe("PLANNER:runPlan:ok");
168168
});
169169

170-
it("shell server denied when operator denies", async () => {
170+
it("requireApproval server denied when operator denies", async () => {
171171
const { enforcer, approvalQueue } = createIntegrationSetup();
172172

173-
const parsed = parseNamespace("shell__run");
174-
const enforcePromise = enforcer.enforce(parsed!, { command: "rm -rf /" });
173+
const parsed = parseNamespace("planner__runPlan");
174+
const enforcePromise = enforcer.enforce(parsed!, { task: "restricted-operation" });
175175

176176
await new Promise((r) => setTimeout(r, 50));
177177

@@ -285,9 +285,9 @@ describe("Integration: Full SINT MCP Flow", () => {
285285
expect(fsConfig).toBeDefined();
286286
expect(fsConfig!.policy?.maxTier).toBe("T2_act");
287287

288-
const shellConfig = downstream.getServerConfig("shell");
289-
expect(shellConfig).toBeDefined();
290-
expect(shellConfig!.policy?.requireApproval).toBe(true);
288+
const plannerConfig = downstream.getServerConfig("planner");
289+
expect(plannerConfig).toBeDefined();
290+
expect(plannerConfig!.policy?.requireApproval).toBe(true);
291291

292292
const dbConfig = downstream.getServerConfig("database");
293293
expect(dbConfig).toBeDefined();

docs/CONFORMANCE_CERTIFICATION_MATRIX_v0.2.md

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,25 @@
22

33
This matrix tracks canonical fixture coverage for major interoperability paths.
44

5-
| Path | Protocol Surface | Canonical Fixture | Expected Outcome |
6-
|---|---|---|---|
7-
| MCP tool call interception | `@sint/bridge-mcp` + gateway | `packages/conformance-tests/src/bridge-mcp-regression.test.ts` | Correct tiering, denial on invalid token, ledger evidence |
8-
| A2A delegated task path | `@sint/bridge-a2a` + gateway | `packages/conformance-tests/src/phase4-regression.test.ts` | Unauthorized denied, physical tasks escalated |
9-
| ROS 2 physical command path | `@sint/bridge-ros2` + gateway | `packages/conformance-tests/src/bridge-ros2-regression.test.ts` | Constraint enforcement, T2/T3 escalation deterministic |
10-
| MQTT Sparkplug command path | `@sint/bridge-mqtt-sparkplug` + gateway | `packages/conformance-tests/src/industrial-interoperability.test.ts` | Equivalent approval behavior vs ROS2/RMF route |
11-
| OPC UA control path | `@sint/bridge-opcua` + gateway | `packages/bridge-opcua/__tests__/opcua-resource-mapper.test.ts` | Safety-critical writes/calls elevated |
12-
| Open-RMF dispatch path | `@sint/bridge-open-rmf` + gateway | `packages/conformance-tests/src/industrial-interoperability.test.ts` | Dispatch actions mapped to T2 escalation |
13-
| Revocation under load | token store + gateway | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | No T2/T3 fail-open after revocation |
14-
| Stale corridor envelope | gateway execution envelope checks | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | Deterministic deny on stale/mismatch corridor |
15-
| Safety-zone breach | geofence + constraint checker | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | Deterministic deny when crossing safety boundary |
16-
| Model swap guardrail | token `modelConstraints` + request runtime model metadata | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | Deny on non-allowlisted runtime model |
17-
| Multi-fleet conflict | Open-RMF `override` + quorum escalation | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | T3 escalation with attached approval quorum |
18-
| Edge central-control fail-closed | edge control-plane hooks + gateway | `packages/conformance-tests/src/edge-mode-conformance.test.ts` | T0/T1 local pass; T2/T3 denied offline, escalated online |
19-
| v0 client compatibility | token/request gateway path | `packages/conformance-tests/src/backward-compatibility-v0-clients.test.ts` | Legacy payloads remain valid without new optional fields |
5+
| Path | Protocol Surface | Canonical Fixture | Validation Test | Expected Outcome |
6+
|---|---|---|---|---|
7+
| MCP tool call interception | `@sint/bridge-mcp` + gateway | `packages/conformance-tests/src/bridge-mcp-regression.test.ts` | `packages/conformance-tests/src/bridge-mcp-regression.test.ts` | Correct tiering, denial on invalid token, ledger evidence |
8+
| A2A delegated task path | `@sint/bridge-a2a` + gateway | `packages/conformance-tests/src/phase4-regression.test.ts` | `packages/conformance-tests/src/phase4-regression.test.ts` | Unauthorized denied, physical tasks escalated |
9+
| ROS 2 physical command path | `@sint/bridge-ros2` + gateway | `packages/conformance-tests/src/bridge-ros2-regression.test.ts` | `packages/conformance-tests/src/bridge-ros2-regression.test.ts` | Constraint enforcement, T2/T3 escalation deterministic |
10+
| MQTT Sparkplug command path | `@sint/bridge-mqtt-sparkplug` + gateway | `packages/conformance-tests/fixtures/industrial/warehouse-move-equivalence.v1.json` | `packages/conformance-tests/src/canonical-fixtures-conformance.test.ts` | Equivalent approval behavior vs ROS2/RMF route |
11+
| OPC UA control path | `@sint/bridge-opcua` + gateway | `packages/conformance-tests/fixtures/industrial/opcua-safety-control.v1.json` | `packages/conformance-tests/src/canonical-fixtures-conformance.test.ts` | Safety-critical writes/calls elevated |
12+
| Open-RMF dispatch path | `@sint/bridge-open-rmf` + gateway | `packages/conformance-tests/fixtures/industrial/warehouse-move-equivalence.v1.json` | `packages/conformance-tests/src/canonical-fixtures-conformance.test.ts` | Dispatch actions mapped to T2 escalation |
13+
| Revocation under load | token store + gateway | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | No T2/T3 fail-open after revocation |
14+
| Stale corridor envelope | gateway execution envelope checks | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | Deterministic deny on stale/mismatch corridor |
15+
| Safety-zone breach | geofence + constraint checker | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | Deterministic deny when crossing safety boundary |
16+
| Model swap guardrail | token `modelConstraints` + request runtime model metadata | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | Deny on non-allowlisted runtime model |
17+
| Multi-fleet conflict | Open-RMF `override` + quorum escalation | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts` | T3 escalation with attached approval quorum |
18+
| Edge central-control fail-closed | edge control-plane hooks + gateway | `packages/conformance-tests/src/edge-mode-conformance.test.ts` | `packages/conformance-tests/src/edge-mode-conformance.test.ts` | T0/T1 local pass; T2/T3 denied offline, escalated online |
19+
| v0 client compatibility | token/request gateway path | `packages/conformance-tests/src/backward-compatibility-v0-clients.test.ts` | `packages/conformance-tests/src/backward-compatibility-v0-clients.test.ts` | Legacy payloads remain valid without new optional fields |
20+
| TypeScript SDK gateway contract | `@sint/sdk` + gateway REST | `packages/conformance-tests/fixtures/protocol/well-known-sint.v0.2.example.json`, `packages/conformance-tests/fixtures/industrial/warehouse-move-equivalence.v1.json` | `sdks/typescript/src/__tests__/client.test.ts` | Request metadata generation, header contract, and endpoint payloads stay in sync with v0.2 |
21+
| PostgreSQL persistence adapter contract | `@sint/persistence-postgres` | `packages/conformance-tests/fixtures/persistence/postgres-adapter-cert.v1.json` | `packages/persistence-postgres/src/__tests__/certification-fixtures.test.ts` | Ledger chain mapping, revocation checks, and rate-limit increments are deterministic |
22+
| ASI04 supply-chain runtime verification | `@sint/gate-policy-gateway` (`DefaultSupplyChainVerifier`) | `packages/conformance-tests/fixtures/security/supply-chain-verification.v1.json` | `packages/conformance-tests/src/security-iot-fixtures-conformance.test.ts` | Fingerprint/allowlist mismatch is denied pre-execution; bridge mismatch emits warning and remains fail-safe |
23+
| MQTT IoT session fail-closed forwarding | `@sint/bridge-iot` + gateway | `packages/conformance-tests/fixtures/iot/mqtt-gateway-session.v1.json` | `packages/conformance-tests/src/security-iot-fixtures-conformance.test.ts`, `packages/bridge-iot/__tests__/mqtt-session.test.ts` | T2/T3 pre-approval paths are blocked from execution; only `allow` forwards publish/subscribe |
2024

2125
## Operational Certification Artifacts
2226

@@ -26,3 +30,23 @@ This matrix tracks canonical fixture coverage for major interoperability paths.
2630
- Benchmark report outputs:
2731
- `docs/reports/industrial-benchmark-report.json`
2832
- `docs/reports/industrial-benchmark-report.md`
33+
34+
## Canonical Fixture Pack (v0.2)
35+
36+
- Warehouse cross-bridge equivalence fixture:
37+
- `packages/conformance-tests/fixtures/industrial/warehouse-move-equivalence.v1.json`
38+
- OPC UA industrial-cell safety fixture:
39+
- `packages/conformance-tests/fixtures/industrial/opcua-safety-control.v1.json`
40+
- Well-known discovery contract fixture:
41+
- `packages/conformance-tests/fixtures/protocol/well-known-sint.v0.2.example.json`
42+
- PostgreSQL persistence adapter fixture:
43+
- `packages/conformance-tests/fixtures/persistence/postgres-adapter-cert.v1.json`
44+
- Supply-chain runtime verification fixture:
45+
- `packages/conformance-tests/fixtures/security/supply-chain-verification.v1.json`
46+
- MQTT session certification fixture:
47+
- `packages/conformance-tests/fixtures/iot/mqtt-gateway-session.v1.json`
48+
- Executable fixture conformance gate:
49+
- `pnpm --filter @sint/conformance-tests run test:fixtures`
50+
- `pnpm --filter @sint/bridge-iot run test:fixtures`
51+
- `pnpm --filter @sint/sdk run test:contracts`
52+
- `pnpm --filter @sint/persistence-postgres run test:fixtures`

docs/RELEASE_NOTES_v0.2.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,26 @@
2525
- SDK starters added:
2626
- `sdks/python/sint_client.py`
2727
- `sdks/go/sintclient/client.go`
28+
- `sdks/typescript` (`@sint/sdk`) contract-aligned with gateway v0.2
2829
- Added industrial interoperability conformance fixture:
2930
- `packages/conformance-tests/src/industrial-interoperability.test.ts`
3031
- Added industrial benchmark scenario fixture set:
3132
- `packages/conformance-tests/src/industrial-benchmark-scenarios.test.ts`
33+
- Added canonical industrial certification fixtures:
34+
- `packages/conformance-tests/fixtures/industrial/warehouse-move-equivalence.v1.json`
35+
- `packages/conformance-tests/fixtures/industrial/opcua-safety-control.v1.json`
36+
- `packages/conformance-tests/src/canonical-fixtures-conformance.test.ts`
37+
- Added protocol/persistence certification fixtures:
38+
- `packages/conformance-tests/fixtures/protocol/well-known-sint.v0.2.example.json`
39+
- `packages/conformance-tests/fixtures/persistence/postgres-adapter-cert.v1.json`
40+
- `packages/persistence-postgres/src/__tests__/certification-fixtures.test.ts`
41+
- Added security/IoT certification fixtures:
42+
- `packages/conformance-tests/fixtures/security/supply-chain-verification.v1.json`
43+
- `packages/conformance-tests/fixtures/iot/mqtt-gateway-session.v1.json`
44+
- `packages/conformance-tests/src/security-iot-fixtures-conformance.test.ts`
45+
- Hardened `@sint/bridge-iot` session semantics:
46+
- MQTT publish/subscribe now execute only on gateway `allow`
47+
- T2/T3 `escalate` responses are fail-closed until approval resolution
3248
- Added edge and compatibility conformance fixtures:
3349
- `packages/conformance-tests/src/edge-mode-conformance.test.ts`
3450
- `packages/conformance-tests/src/backward-compatibility-v0-clients.test.ts`

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"typecheck": "turbo run typecheck",
1212
"clean": "turbo run clean",
1313
"demo": "pnpm --filter @sint/conformance-tests exec vitest run src/e2e-demo.test.ts --reporter=verbose",
14+
"cert:fixtures": "pnpm --filter ./packages/policy-gateway build && pnpm --filter ./packages/conformance-tests run test:fixtures && pnpm --filter ./packages/bridge-iot run test:fixtures && pnpm --filter ./sdks/typescript run test:contracts && pnpm --filter ./packages/persistence-postgres run test:fixtures",
1415
"benchmark:industrial": "pnpm --filter @sint/conformance-tests exec vitest run src/industrial-interoperability.test.ts src/industrial-benchmark-scenarios.test.ts --reporter=verbose",
1516
"benchmark:report": "node ./scripts/generate-industrial-benchmark-report.mjs"
1617
},

0 commit comments

Comments
 (0)