Goal
Implement runContractSuite(baseUrl, apiKey) in the /testing subpath of @codespar/session-contract. Add a contract-managed.test.ts file gated on CONTRACT_API_KEY. Wire the /testing conditional export in package.json. Add the managed-leg CI step to the codespar-core workflow — behind a prerequisite checklist that must be satisfied before the step is enabled.
Context
The session contract package needs a reusable test helper that any downstream consumer can call to verify their implementation against the published types. runContractSuite encodes the full behavioral contract — streaming event variants, tool execution, send/receive, connection listing, and session close — so that both the OSS SDK and the managed endpoint can be validated with the same logic.
The /testing subpath uses the "development" export condition so production bundlers never pull vitest into user bundles.
The managed CI leg (contract-managed.test.ts) fires only on main and only after a dedicated contract-test org is provisioned with storage-level isolation. The OSS leg (codespar/codespar#95) ships first; the managed leg follows once backend prerequisites are confirmed.
runContractSuite validates the baseUrl argument before issuing any request to prevent API key exfiltration via misconfigured environment variables in downstream CI consumers.
Acceptance Criteria
Prerequisites before the managed CI leg is enabled
The CI step must remain commented out or disabled until all four are confirmed by the backend team:
- A dedicated contract-test org is provisioned in the managed backend with storage-level isolation from production tenants (separate org record, not just a separate API key on a shared org).
CONTRACT_API_KEY is scoped to sessions:create, sessions:execute, sessions:close only.
- The contract-test org's session data is purged on a daily schedule.
- npm provenance (
--provenance) is confirmed active for the @codespar/session-contract publish step.
Validation
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(git rev-parse --show-toplevel)"
PKG_DIR="$REPO_ROOT/packages/session-contract"
echo "=== Build session-contract ==="
pnpm --filter @codespar/session-contract build
echo "=== Verify /testing export present in package.json ==="
node - <<'EOF'
const pkg = require(process.env.PKG_DIR + "/package.json");
const entry = pkg.exports?.["./testing"];
if (!entry) {
console.error("FAIL: ./testing export missing from package.json");
process.exit(1);
}
if (!entry.development) {
console.error("FAIL: ./testing export is missing the 'development' condition");
process.exit(1);
}
console.log("PASS: ./testing export present with 'development' condition");
EOF
echo "=== Verify compiled /testing artifact exists ==="
if [ ! -f "$PKG_DIR/dist/testing/contract-suite.js" ]; then
echo "FAIL: dist/testing/contract-suite.js not found"
exit 1
fi
if [ ! -f "$PKG_DIR/dist/testing/contract-suite.d.ts" ]; then
echo "FAIL: dist/testing/contract-suite.d.ts not found"
exit 1
fi
echo "PASS: compiled /testing artifacts present"
echo "=== Run OSS contract smoke test (localhost) ==="
# Starts a minimal local session server, runs runContractSuite against it,
# then tears it down. Requires the OSS SDK local server fixture to be in place
# (implemented in codespar/codespar#95). If the fixture is not yet available, this step
# is expected to be wired by the codespar/codespar#95 implementer.
pnpm --filter @codespar/session-contract test -- --testPathPattern=contract-oss
echo "=== Verify managed leg is gated (no unconditional execution) ==="
grep -q 'describeIf' "$PKG_DIR/src/__tests__/contract-managed.test.ts" || {
echo "FAIL: contract-managed.test.ts does not use describeIf gate"
exit 1
}
echo "PASS: managed leg is gated on CONTRACT_API_KEY"
echo "=== All checks passed ==="
Dependencies
Downstream Dependencies
Goal
Implement
runContractSuite(baseUrl, apiKey)in the/testingsubpath of@codespar/session-contract. Add acontract-managed.test.tsfile gated onCONTRACT_API_KEY. Wire the/testingconditional export inpackage.json. Add the managed-leg CI step to the codespar-core workflow — behind a prerequisite checklist that must be satisfied before the step is enabled.Context
The session contract package needs a reusable test helper that any downstream consumer can call to verify their implementation against the published types.
runContractSuiteencodes the full behavioral contract — streaming event variants, tool execution, send/receive, connection listing, and session close — so that both the OSS SDK and the managed endpoint can be validated with the same logic.The
/testingsubpath uses the"development"export condition so production bundlers never pull vitest into user bundles.The managed CI leg (
contract-managed.test.ts) fires only onmainand only after a dedicated contract-test org is provisioned with storage-level isolation. The OSS leg (codespar/codespar#95) ships first; the managed leg follows once backend prerequisites are confirmed.runContractSuitevalidates thebaseUrlargument before issuing any request to prevent API key exfiltration via misconfigured environment variables in downstream CI consumers.Acceptance Criteria
packages/session-contract/src/testing/contract-suite.tsexportsrunContractSuite(baseUrl: string, apiKey: string): voidrunContractSuitethrowsInvalidBaseUrlErrorfor non-https://URLs unless the host islocalhostStreamEventvariants (user_message,assistant_text,tool_use,tool_result,done,error)execute()calls a registered tool and returns aToolResultsend()returns aSendResultwith acontentfieldconnections()returns at least one entry withid: stringandconnected: booleanclose()transitionssession.statusto"closed"afterEachcloses the session in atry/finallyblock so cleanup runs even when an assertion failspackages/session-contract/package.jsoncontains a"./testing"export entry with a"development"condition pointing to the compiled output and typespackages/session-contract/src/__tests__/contract-managed.test.tsexists and is gated withdescribeIfonCONTRACT_API_KEY.github/workflows/ci.ymlis present but NOT enabled until all four prerequisites are met (see Prerequisites below)Prerequisites before the managed CI leg is enabled
The CI step must remain commented out or disabled until all four are confirmed by the backend team:
CONTRACT_API_KEYis scoped tosessions:create,sessions:execute,sessions:closeonly.--provenance) is confirmed active for the@codespar/session-contractpublish step.Validation
Dependencies
runContractSuitecan importSessionBase,CreateSessionRequest,StreamEvent,SendResult,ToolResult, andConnectionInfofrom@codespar/session-contractrather than duplicating them.Downstream Dependencies
runContractSuitefrom@codespar/session-contract/testing. That import is only resolvable after this issue ships the/testingsubpath export.