witnora

Sandbox Adapter Kit v0.2

Sandbox Adapter Kit turns the local Sandbox Conformance Harness into an integration contract that another team can implement, test, and publish to the Witnora Hosted Control Plane without granting production write access.

Run the reference conformance suite

External teams should start with the single-package onboarding path:

npx witnora@latest sandbox init
npx witnora@latest sandbox certify --adapter ./witnora.sandbox.mjs

This writes one dependency-free adapter template and runs the v0.2 conformance suite bundled inside agentcert. It does not require the unpublished @agentcert/onegent-runtime package or an Witnora source checkout.

npm run onegent:sandbox-conformance

Output:

.onegent/sandbox-conformance/sandbox-adapter-conformance.json

A passing report uses schemaVersion: "agentcert.sandbox_adapter_conformance.v0.2". The package ships sandbox-adapter-conformance.schema.json for independent validation.

Implement a third-party SandboxSystem

Use createSandboxSystemAdapter() so the safety declaration and synthetic seed validation cannot be accidentally weakened:

const system = createSandboxSystemAdapter({
  name: "customer-sandbox",
  allowedTargetSystems: ["CustomerSandboxCRM"],
  handlers: {
    createTenant,
    deleteTenant,
    resetTenant,
    seedTenant,
    hasTenant,
    snapshotTenant,
    adapterForTenant,
  },
});

const report = await runSandboxAdapterConformanceSuite({ system });

The runnable template is examples/onegent/sandbox-system-adapter-template.mjs. The suite actively checks the adapter contract, all ten v0.1 safety controls, the full tenant lifecycle, and temporary-tenant cleanup.

Temporary tenants

Every harness tenant receives a one-hour lease by default. The maximum default lease is 24 hours. Services can shorten these values, renew an active lease, run deterministic cleanup, or close the harness and delete all remaining tenants:

const harness = createSandboxCertificationHarness({
  system,
  tenantTtlMs: 15 * 60_000,
  maxTenantTtlMs: 60 * 60_000,
});

const lease = await harness.createTenant({ id: "pilot-42", synthetic: true });
await harness.renewTenant(lease.tenantId, 10 * 60_000);
await harness.cleanupExpiredTenants();
await harness.close();

The in-process timer is a safety net, not a distributed scheduler. A hosted adapter should also enforce expiry in its own durable store so cleanup survives process restarts.

Stripe Test Mode read-only reference

createStripeTestModeReadOnlyAdapter() demonstrates the first vendor boundary. It:

const stripe = createStripeTestModeReadOnlyAdapter({
  restrictedApiKey: process.env.STRIPE_RESTRICTED_TEST_KEY!,
});

const snapshot = await stripe.retrievePaymentIntent("pi_...");

This adapter does not create, confirm, capture, cancel, or refund payments. The restricted key must grant only the Stripe read permission required by the selected method. See Stripe’s official API key guidance and PaymentIntent retrieval API. The public npx witnora@latest sandbox stripe-readonly workflow and its evidence boundary are documented in Bounded Vendor Sandbox Egress v0.4.

Publish conformance evidence

The CLI can create a hosted run, upload a manifest-complete evidence bundle, and complete the run:

export WITNORA_PROJECT_ID="your-project-id"
export WITNORA_API_KEY="your-scoped-api-key"
export WITNORA_BASE_URL="https://witnora.com"

onegent-runtime sandbox-conformance --push

For external users, the supported public command is:

npx witnora@latest onboard --project your-project-id
npx witnora@latest sandbox push --adapter ./witnora.sandbox.mjs

The API key needs runs:write and evidence:write. The key is read only from the environment and is never accepted as a CLI flag or written into evidence. Programmatic callers can use uploadSandboxCertificationReport() with an injected fetch implementation.

What conformance proves

What conformance does not prove

The intended progression remains: local synthetic adapter, official vendor test mode read-only, official vendor sandbox with narrowly approved writes, production read-only shadow, then a manually approved low-limit canary.