diff --git a/CHANGELOG.md b/CHANGELOG.md index bedf5b2..a6bcf04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,30 +1,16 @@ # Changelog -All notable changes to the platform will be documented in this file. +## Unreleased — Prompt SDK v1 release preparation -Releases follow the Studio's content-addressed dependency, versioning, and -provenance strategy. See `docs/architecture.md`. +- Final API inventory, quick start, adapter guide, compatibility/deprecation + policy, known limitations and owner-reviewed release checklist. +- Context Package candidate schema id normalized to the canonical v1 URN; + refreshed exact pin and compiled validator, with no payload semantics change. -## Unreleased +## 0.1.0 — implementation baseline -- Added Structured Output v1 exact schema/raw validation, parse-once JSON - normalization, explicit failures, retention policy, provider-constraint - provenance, adversarial tests, example, documentation, and ADR. -- Added Context Package v1 parsing, integrity and authorization validation, - prompt-slot binding, classification and provenance propagation, deterministic - mocks, adversarial tests, an example, documentation, and an ADR. -- Added a vendor-neutral filesystem prompt registry with deterministic - discovery, exact and guarded non-exact resolution, lifecycle warnings, - conflict detection, atomic refresh, source digests, tests, and examples. -- Added Provider Execution v1 validation, synchronous adapter execution, - capability negotiation, normalized provenance/errors, cancellation and - timeout handling, and a deterministic mock adapter. -- Added Prompt Definition v1 schema validation, semantic/security linting, - machine-readable diagnostics, duplicate-key-safe parsing, collection checks, - and a CI-ready CLI. -- Added a dependency-free Prompt Definition v1 renderer with strict explicit - value resolution, deterministic canonical output, structured errors, tests, - and synthetic examples. -- Adopted Constitution v1.0.0 with a revision-scoped conformance assessment and - pre-implementation agent, workflow, and release control requirements. -- Created the initial repository scaffold and ownership boundaries. +Prompt definition validation/lint; deterministic rendering; provider-neutral +execution; filesystem registry; context-package integration; structured outputs; +metadata-only provenance; CLI/authoring workflow; offline conformance suite and +reference goldens. Provisional contract dependencies remain release-blocking +until immutable Codex artifacts are verified. No stable v1 tag is claimed here. diff --git a/CONSTITUTION_CONFORMANCE.md b/CONSTITUTION_CONFORMANCE.md index 0096341..368435f 100644 --- a/CONSTITUTION_CONFORMANCE.md +++ b/CONSTITUTION_CONFORMANCE.md @@ -1,5 +1,19 @@ # Constitution conformance record +## Issue #72 release preparation — 2026-09-11 + +Owner: @andrewperis. Constitution v1.0.0 at +`a9cc8a503aa30e17820edc62ac95f7cbe10e0564` remains authoritative. +Scope: consolidated public API inventory/reference, quick start, compatibility +and deprecation policy, limitations, release checklist, conservative readiness +report and corrected Context Package candidate schema pin. +Evidence: full offline test suite and exact export-inventory check; npm audit +reported zero vulnerabilities on 2026-09-11. No new dependencies or exceptions. +Owner approval, five immutable Codex releases, reviewed stable dependency lock, +runtime/version transition and Platform artifact publication remain required. +Current package and runtime status deliberately remain provisional; this is +not completed constitutional approval for a published v1 release. + ## Issue #71 assessment — 2026-09-11 Scope: reusable offline adapter conformance suite; text, structured and context diff --git a/README.md b/README.md index 1d36af5..1c15876 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Production software for the Definitely Secure Studio creative toolchain. +See the [Prompt SDK v1 API/release guide](docs/prompt-sdk-v1.md) for quick start, +compatibility, limitations and release readiness. + The [reference prompt library](examples/reference-prompts/README.md) demonstrates offline end-to-end v1 flows with reviewed golden fixtures. diff --git a/docs/README.md b/docs/README.md index 17627b1..71955d2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,7 @@ # Platform documentation +- [Prompt SDK v1 API and release guide](prompt-sdk-v1.md) consolidates the supported surface and publication gates. + - [Prompt CLI and authoring workflow](prompt-cli.md) covers local commands, CI and promotion. - [Execution provenance](execution-provenance.md) covers metadata policy and pluggable observers. diff --git a/docs/prompt-sdk-v1.md b/docs/prompt-sdk-v1.md new file mode 100644 index 0000000..05727d8 --- /dev/null +++ b/docs/prompt-sdk-v1.md @@ -0,0 +1,123 @@ +# Prompt SDK v1 release guide + +This is the v1 release candidate documentation, not a claim of publication. +Package/runtime version stays 0.1.0 and contract pins remain visibly provisional +until Codex immutable artifacts and owner release approval are verified. +Studio #72 and Epic #4 must remain open until the actual releases exist. + +## Quick start + +Use Node.js 22 or 24 and the committed npm lock: + +```sh +npm ci +npm test +node src/prompt-sdk/cli.js validate examples/cli/prompt.json --format json +node src/prompt-sdk/cli.js render examples/cli/prompt.json --inputs examples/cli/inputs.json --format json +node examples/reference-prompts/run.mjs structured +``` + +All examples are synthetic and mock-based. No API keys or model network calls +are required. For execution and protected output handling, follow the +[CLI/authoring guide](prompt-cli.md); for integrated flows use the +[reference library](../examples/reference-prompts/README.md). + +## Public API surface + +Import the supported entry point `@definitely-secure-studio/platform/prompt-sdk`. +The exact exported-name inventory is [api-v1.json](../release/api-v1.json), +checked by automated tests. Internal paths and generated validators are not +public APIs. Most validators return `{ valid, diagnostics, ... }`; provenance +validation returns a boolean. Throwing and nonthrowing variants are distinct. + +| API | Inputs and result | Reference | +| --- | --- | --- | +| `canonicalJson(value)` | Explicit JSON data to deterministic string; rejects non-JSON data/accessors | [Rendering](prompt-renderer.md) | +| `parsePromptJson(source)` | Raw JSON to value plus diagnostics, retaining duplicate-key evidence | [Validation](prompt-validation.md) | +| `validatePromptDefinition(definition, options)`, `validatePromptDefinitions(definitions, options)` | Schema/semantic/lint reports; no rendering or execution | [Validation](prompt-validation.md) | +| `renderPrompt(definition, options)`, `tryRenderPrompt(definition, options)` | Explicit inputValues/contextValues to rendered messages, canonical bytes and identity; throwing or result variant | [Rendering](prompt-renderer.md) | +| `FilesystemPromptRegistry.open(options)`, `createFilesystemPromptRegistry(options)` | Async approved filesystem roots to registry; discover/list, resolve and refresh methods | [Registry](prompt-registry.md) | +| `createExecutionRequest(renderResult, options)` | Validated portable execution request with explicit identity, target, authority and output contract | [Execution](provider-execution.md) | +| `validateExecutionDocument(document)`, `validateExecutionCompatibility(request, descriptor)`, `validateExecutionResult(result, options)` | Contract validation and capability/default negotiation; result relation checks need request and descriptor | [Execution](provider-execution.md) | +| `executePrompt(request, options)` | Async single adapter execution; options include adapter, signal, clock and optional observer configuration | [Execution](provider-execution.md) | +| `MockTextAdapter`, `mockTextAdapterDescriptor()` | Configurable offline adapter and independent descriptor copy | [Conformance](../tests/README.md) | +| `parseContextPackageJson(source)`, `validateContextDocument(document)`, `validateContextBinding(...)` | Explicit package/authorization validation; no retrieval | [Context](context-packages.md) | +| `bindContextPackage(...)`, `renderPromptWithContextPackage(...)` | Authorized declared-slot bindings and rendering at an explicit time | [Context](context-packages.md) | +| `createMockContextPackage()`, `createMockContextAuthorization(options)` | Synthetic deterministic fixtures, not production authority | [Context](context-packages.md) | +| `processStructuredOutput(request, result, options)`, `tryProcessStructuredOutput(...)`, `validateStructuredOutputDocument(document)` | Parse once, verify raw/schema bytes, return normalized result or failure; no repair or remote schema fetch | [Structured output](structured-output.md) | +| `createExecutionProvenance(request, result, options)`, `validateExecutionProvenance(document)` | Frozen metadata-only evidence and schema/digest validation | [Provenance](execution-provenance.md) | +| `LocalExecutionObserver`, `deliverExecutionProvenance(observer, document, timeoutMs)` | Bounded local buffer/snapshot/clear and deadline-bounded delivery boolean | [Provenance](execution-provenance.md) | + +Error classes are public for catch/type checks: PromptRenderError, +PromptRegistryError, ExecutionValidationError, AdapterExecutionError, +ContextPackageError and StructuredOutputError. Do not treat arbitrary caught +provider exception text as safe logging output. Each guide documents its error +reports and failure behavior. + +Public metadata constants CONTRACT/PROMPT_DEFINITION_CONTRACT, +EXECUTION_CONTRACT, CONTEXT_PACKAGE_CONTRACT and STRUCTURED_OUTPUT_CONTRACT +identify the implementation's exact contract pins. They do not authorize release. + +## Adapter implementers + +Implement `async describe()` and `async execute(request, { signal })` behind the +Studio-owned adapter boundary. Return the portable descriptor/outcome; keep +provider SDK types, credentials and raw errors inside the adapter. Capability +implementation (native/emulated), parameters, defaults and optional extensions +must be explicit. Honor cancellation where possible; core deadlines do not +cancel a non-cooperating provider's already-started work or billing. + +Follow [provider execution](provider-execution.md) and run the +[reusable offline conformance suite](../tests/README.md). Add stubbed transport +tests for provider mapping, security/retention/region policy and declared optional +capabilities. Provider neutrality is demonstrated by the mock and independent +fake; no real provider is approved by v1 release. + +## Compatibility and deprecation + +SDK and individual Codex contracts version independently using SemVer. The +initial SDK release is `prompt-sdk/v1.0.0`; each Codex family uses +`contract//v1.0.0`. Consumers pin exact releases and digests. +Unknown fields/capabilities are handled according to each closed contract, not +silently ignored. Do not assume generic major-version compatibility replaces +explicit capability negotiation or exact schema support. + +Patch: compatible fixes; minor: backward-compatible API additions and announced +deprecations; major: removals or incompatible behavior/identity/security changes. +Deprecations require owner approval, migration guidance, affected-consumer +inventory and a dated support window; nothing is silently removed within v1. +Security fixes may require a reviewed migration and new major when semantics +change. Keep old tags/artifacts intact. A rollback selects a previously verified +release; it never mutates old versions or downgrades classification rules. + +## Known v1 limitations + +Synchronous text generation and JSON output only. No streaming, asynchronous +jobs, image/audio/multimodal execution, tool protocols, model routing/retries, +retrieval, orchestration or distributed registry. No vendor SDK ships here. +Structured validation is not truth/quality validation or output approval. +Observers are best-effort and sink deadlines do not stop external I/O. +No automatic canon, prompt lifecycle, authority or publication approval. + +## Release checklist + +1. Owner approves Codex release preparation; publish and verify all five immutable + contract releases per its release checklist. Capture complete manifests. +2. Review Platform's dependency lock containing exact repository, contract, + version/tag, source commit, asset URI/type/size/digest. Replace provisional + runtime pins and regenerate validators from downloaded verified assets. +3. Only then change runtime status to released and enable stable prompt lifecycle. + Bump package, lock, renderer and structured processor versions to 1.0.0 + together; review every intentional golden identity change. +4. Confirm exported API inventory, all tests and both CI versions. Run dependency + audit and resolve findings or obtain a documented owner exception. +5. Record Constitution v1.0.0 alignment, owner approval, licenses/notices, + dependency tuples, test evidence, exact Platform source commit and build + workflow identity. No private inputs are used in these release artifacts. +6. Build the source/package artifact, inspect its file list and secret safety, + record byte size/digest, upload to an owner-reviewed draft GitHub release + at `prompt-sdk/v1.0.0`, then publish once and verify immutability/downloads. +7. Close #72 and Epic #4 only after actual release verification. + +The package remains private. GitHub artifacts are sufficient; this work does +not publish to npm or change package/repository visibility. diff --git a/release/README.md b/release/README.md new file mode 100644 index 0000000..abe2f17 --- /dev/null +++ b/release/README.md @@ -0,0 +1,22 @@ +# Reviewed release inputs + +`api-v1.json` inventories the public entry point. Changes require API and +compatibility review; the test suite detects accidental export additions/removals. + +Run `node scripts/check-sdk-release.mjs` for a machine-readable readiness +report (exit 1 while blocked). Its current expected result is not ready. +It never creates tags, uploads files, changes version/status or grants approval. + +The later owner-reviewed adoption change adds `contract-lock.json`: +`{ "contracts": [ ...five downloaded Codex manifests... ] }`. +Each manifest retains the builder's repository, contract, version, tag, commit, +schema_id and assets with URI, media type, byte size and SHA-256. Add +`publication: { "immutable": true, "verified_at": "RFC3339 timestamp" }` +only after independently verifying GitHub immutable status, exact tag target, +and downloaded asset bytes. Retain links to that evidence in the release review. + +This is an offline consistency check of reviewed evidence, not online proof. +The owner must verify evidence before adopting it. The script checks the four +public runtime metadata pins; the fifth provenance generator pin and every +compiled validator must additionally be checked against downloaded schema bytes +as specified in the [release guide](../docs/prompt-sdk-v1.md). diff --git a/release/api-v1.json b/release/api-v1.json new file mode 100644 index 0000000..27b53fc --- /dev/null +++ b/release/api-v1.json @@ -0,0 +1,42 @@ +[ + "AdapterExecutionError", + "CONTEXT_PACKAGE_CONTRACT", + "CONTRACT", + "ContextPackageError", + "EXECUTION_CONTRACT", + "ExecutionValidationError", + "FilesystemPromptRegistry", + "LocalExecutionObserver", + "MockTextAdapter", + "PROMPT_DEFINITION_CONTRACT", + "PromptRegistryError", + "PromptRenderError", + "STRUCTURED_OUTPUT_CONTRACT", + "StructuredOutputError", + "bindContextPackage", + "canonicalJson", + "createExecutionProvenance", + "createExecutionRequest", + "createFilesystemPromptRegistry", + "createMockContextAuthorization", + "createMockContextPackage", + "deliverExecutionProvenance", + "executePrompt", + "mockTextAdapterDescriptor", + "parseContextPackageJson", + "parsePromptJson", + "processStructuredOutput", + "renderPrompt", + "renderPromptWithContextPackage", + "tryProcessStructuredOutput", + "tryRenderPrompt", + "validateContextBinding", + "validateContextDocument", + "validateExecutionCompatibility", + "validateExecutionDocument", + "validateExecutionProvenance", + "validateExecutionResult", + "validatePromptDefinition", + "validatePromptDefinitions", + "validateStructuredOutputDocument" +] diff --git a/scripts/check-sdk-release.mjs b/scripts/check-sdk-release.mjs new file mode 100644 index 0000000..1553cc6 --- /dev/null +++ b/scripts/check-sdk-release.mjs @@ -0,0 +1,41 @@ +import { readFile } from 'node:fs/promises'; +import { pathToFileURL } from 'node:url'; +import { CONTRACT, EXECUTION_CONTRACT, CONTEXT_PACKAGE_CONTRACT, STRUCTURED_OUTPUT_CONTRACT } from '../src/prompt-sdk/index.js'; +export async function releaseReadiness() { + const pkg = JSON.parse(await readFile(new URL('../package.json', import.meta.url))); + const blockers = []; + if (pkg.version !== '1.0.0') blockers.push('SDK package is not version 1.0.0.'); + for (const [name, pin] of Object.entries({ 'prompt-definition': CONTRACT, 'provider-execution': EXECUTION_CONTRACT, 'context-package': CONTEXT_PACKAGE_CONTRACT, 'structured-output': STRUCTURED_OUTPUT_CONTRACT })) { + if (pin.status !== 'released') blockers.push(name + ' remains provisional.'); + } + let lock; + try { lock = JSON.parse(await readFile(new URL('../release/contract-lock.json', import.meta.url))); } + catch { blockers.push('A reviewed immutable contract lock is missing or unreadable.'); } + const names = ['prompt-definition', 'provider-execution', 'context-package', 'structured-output', 'execution-provenance']; + if (lock) { + if (!Array.isArray(lock.contracts) || lock.contracts.length !== names.length) blockers.push('Contract lock must contain exactly five contracts.'); + for (const name of names) { + const entries = Array.isArray(lock.contracts) ? lock.contracts.filter(entry => entry?.contract === name) : []; + const entry = entries[0]; + const schema = Array.isArray(entry?.assets) ? entry.assets.find(asset => asset?.media_type === 'application/schema+json') : undefined; + if (entries.length !== 1 || entry.repository !== 'DefinitelySecureStudio/codex' || entry.version !== '1.0.0' || + entry.tag !== 'contract/' + name + '/v1.0.0' || !/^[0-9a-f]{40}$/.test(entry.commit ?? '') || + entry.publication?.immutable !== true || !Number.isFinite(Date.parse(entry.publication?.verified_at)) || + !schema || !Number.isSafeInteger(schema.byte_size) || schema.byte_size < 1 || + !/^sha256:[0-9a-f]{64}$/.test(schema.sha256 ?? '') || + !schema.artifact_uri?.startsWith('https://github.com/DefinitelySecureStudio/codex/releases/download/' + encodeURIComponent(entry.tag) + '/')) { + blockers.push(name + ' lacks a complete verified immutable reference.'); + } + const pin = { 'prompt-definition': CONTRACT, 'provider-execution': EXECUTION_CONTRACT, 'context-package': CONTEXT_PACKAGE_CONTRACT, 'structured-output': STRUCTURED_OUTPUT_CONTRACT }[name]; + if (pin && (pin.commit !== entry?.commit || pin.schema_sha256 !== schema?.sha256 || pin.schema_byte_size !== schema?.byte_size)) blockers.push(name + ' runtime pin differs from the dependency lock.'); + } + } + // Offline readiness checks the reviewed evidence; it is not a substitute for + // independently verifying GitHub publication and downloaded asset bytes. + return { ready: blockers.length === 0, blockers }; +} +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + const report = await releaseReadiness(); + console.log(JSON.stringify(report, null, 2)); + process.exitCode = report.ready ? 0 : 1; +} diff --git a/scripts/generate-context-schema-validator.mjs b/scripts/generate-context-schema-validator.mjs index a1b156a..0a4951e 100644 --- a/scripts/generate-context-schema-validator.mjs +++ b/scripts/generate-context-schema-validator.mjs @@ -4,8 +4,8 @@ import Ajv2020 from "ajv/dist/2020.js"; import addFormats from "ajv-formats"; import standaloneCode from "ajv/dist/standalone/index.js"; -const CONTRACT_COMMIT = "dfd31a693674dc03dec4784dcdd1345f647cff1e"; -const SCHEMA_SHA256 = "a0915675a2036c8f929c53a212fcd14740e12fda0ef643fe13d727f0d62e9509"; +const CONTRACT_COMMIT = "cb76a9343312d0245b388381e318aa58463303cb"; +const SCHEMA_SHA256 = "d81e88780511c31099b2dd925f31aff26d6ba75e1173e953b98a37298764b617"; const sourcePath = process.argv[2]; const outputPath = process.argv[3] ?? new URL("../src/prompt-sdk/generated/context-package-v1-schema.js", import.meta.url); diff --git a/src/prompt-sdk/diagnostics.js b/src/prompt-sdk/diagnostics.js index 3a4cd9e..2ead0a3 100644 --- a/src/prompt-sdk/diagnostics.js +++ b/src/prompt-sdk/diagnostics.js @@ -20,10 +20,10 @@ export const EXECUTION_CONTRACT = Object.freeze({ export const CONTEXT_PACKAGE_CONTRACT = Object.freeze({ repository: "DefinitelySecureStudio/codex", - commit: "dfd31a693674dc03dec4784dcdd1345f647cff1e", + commit: "cb76a9343312d0245b388381e318aa58463303cb", spec_version: "1.0.0", - schema_sha256: "sha256:a0915675a2036c8f929c53a212fcd14740e12fda0ef643fe13d727f0d62e9509", - schema_byte_size: 8409, + schema_sha256: "sha256:d81e88780511c31099b2dd925f31aff26d6ba75e1173e953b98a37298764b617", + schema_byte_size: 8390, status: "provisional-unreleased" }); diff --git a/src/prompt-sdk/generated/context-package-v1-schema.js b/src/prompt-sdk/generated/context-package-v1-schema.js index 87c5763..ce9f403 100644 --- a/src/prompt-sdk/generated/context-package-v1-schema.js +++ b/src/prompt-sdk/generated/context-package-v1-schema.js @@ -1,12 +1,12 @@ -// Generated from DefinitelySecureStudio/codex@dfd31a693674dc03dec4784dcdd1345f647cff1e -// Source SHA-256: a0915675a2036c8f929c53a212fcd14740e12fda0ef643fe13d727f0d62e9509 +// Generated from DefinitelySecureStudio/codex@cb76a9343312d0245b388381e318aa58463303cb +// Source SHA-256: d81e88780511c31099b2dd925f31aff26d6ba75e1173e953b98a37298764b617 // Rebuild with scripts/generate-context-schema-validator.mjs; do not edit manually. import { createRequire } from "node:module"; const require = createRequire(import.meta.url); "use strict"; export const validate = validate20; export default validate20; -const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schemas.definitelysecure.studio/context-packages/v1/context-package.schema.json","title":"Definitely Secure Studio Context Package v1","oneOf":[{"$ref":"#/$defs/contextPackage"},{"$ref":"#/$defs/contextPackageReference"},{"$ref":"#/$defs/contextAuthorization"}],"$defs":{"safeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$"},"namespace":{"type":"string","pattern":"^[a-z0-9]+(?:[._-][a-z0-9]+)+$"},"symbol":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"promptId":{"type":"string","pattern":"^prompt\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?)+$"},"packageId":{"type":"string","pattern":"^context-package\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?)+$"},"semver":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$"},"timestamp":{"type":"string","format":"date-time"},"absoluteUri":{"type":"string","format":"uri","pattern":"^[A-Za-z][A-Za-z0-9+.-]*:"},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"classification":{"enum":["public","internal","confidential","restricted"]},"owner":{"type":"string","pattern":"^@?[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"},"packageIdentity":{"type":"object","additionalProperties":false,"required":["id","version","instance_id"],"properties":{"id":{"$ref":"#/$defs/packageId"},"version":{"$ref":"#/$defs/semver"},"instance_id":{"$ref":"#/$defs/safeId"}}},"contentIdentity":{"type":"object","additionalProperties":false,"required":["canonicalization","byte_size","sha256"],"properties":{"canonicalization":{"const":"studio-json-v1"},"byte_size":{"type":"integer","minimum":2},"sha256":{"$ref":"#/$defs/sha256"}}},"artifactIdentity":{"type":"object","additionalProperties":false,"required":["artifact_uri","media_type","byte_size","sha256"],"properties":{"artifact_uri":{"$ref":"#/$defs/absoluteUri"},"media_type":{"type":"string","pattern":"^[A-Za-z0-9!#$&^_.+-]+/[A-Za-z0-9!#$&^_.+-]+$"},"byte_size":{"type":"integer","minimum":1},"sha256":{"$ref":"#/$defs/sha256"}}},"sourceRecord":{"type":"object","additionalProperties":false,"required":["source_id","kind","version","classification","evidence_reference"],"properties":{"source_id":{"$ref":"#/$defs/safeId"},"kind":{"enum":["public-canon","approved-private","caller-supplied","synthetic"]},"version":{"type":"string","minLength":1,"maxLength":200},"classification":{"$ref":"#/$defs/classification"},"evidence_reference":{"$ref":"#/$defs/absoluteUri"},"artifact":{"$ref":"#/$defs/artifactIdentity"}}},"section":{"type":"object","additionalProperties":false,"required":["slot","classification","media_type","content","byte_size","sha256","source_ids"],"properties":{"slot":{"$ref":"#/$defs/symbol"},"classification":{"$ref":"#/$defs/classification"},"media_type":{"enum":["text/plain","application/json"]},"content":{},"byte_size":{"type":"integer","minimum":0},"sha256":{"$ref":"#/$defs/sha256"},"source_ids":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/$defs/safeId"}}},"allOf":[{"if":{"properties":{"media_type":{"const":"text/plain"}},"required":["media_type"]},"then":{"properties":{"content":{"type":"string"}}}}]},"manifest":{"type":"object","additionalProperties":false,"required":["package","builder","created_at","review_after","expires_at","purpose","authority_reference","classification","total_content_bytes","sources","sections"],"properties":{"package":{"$ref":"#/$defs/packageIdentity"},"builder":{"type":"object","additionalProperties":false,"required":["id","version"],"properties":{"id":{"$ref":"#/$defs/namespace"},"version":{"$ref":"#/$defs/semver"}}},"created_at":{"$ref":"#/$defs/timestamp"},"review_after":{"$ref":"#/$defs/timestamp"},"expires_at":{"$ref":"#/$defs/timestamp"},"purpose":{"type":"string","minLength":1,"maxLength":1000},"authority_reference":{"$ref":"#/$defs/absoluteUri"},"classification":{"$ref":"#/$defs/classification"},"total_content_bytes":{"type":"integer","minimum":0},"sources":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/sourceRecord"}},"sections":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/section"}}}},"contextPackage":{"type":"object","additionalProperties":false,"required":["spec_version","kind","manifest","manifest_identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"context-package"},"manifest":{"$ref":"#/$defs/manifest"},"manifest_identity":{"$ref":"#/$defs/contentIdentity"}}},"contextPackageReference":{"type":"object","additionalProperties":false,"required":["spec_version","kind","package","artifact","manifest_identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"context-package-reference"},"package":{"$ref":"#/$defs/packageIdentity"},"artifact":{"allOf":[{"$ref":"#/$defs/artifactIdentity"},{"properties":{"media_type":{"const":"application/vnd.definitely-secure-studio.context-package+json"}}}]},"manifest_identity":{"$ref":"#/$defs/contentIdentity"}}},"contextAuthorization":{"type":"object","additionalProperties":false,"required":["spec_version","kind","decision_id","decision","package","prompt","sections","max_classification","purpose","decided_by","decided_at","expires_at","authority_reference"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"context-authorization"},"decision_id":{"$ref":"#/$defs/safeId"},"decision":{"enum":["allow","deny"]},"package":{"$ref":"#/$defs/packageIdentity"},"prompt":{"type":"object","additionalProperties":false,"required":["id","version"],"properties":{"id":{"$ref":"#/$defs/promptId"},"version":{"$ref":"#/$defs/semver"}}},"sections":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/symbol"}},"max_classification":{"$ref":"#/$defs/classification"},"purpose":{"type":"string","minLength":1,"maxLength":1000},"decided_by":{"$ref":"#/$defs/owner"},"decided_at":{"$ref":"#/$defs/timestamp"},"expires_at":{"$ref":"#/$defs/timestamp"},"authority_reference":{"$ref":"#/$defs/absoluteUri"}},"allOf":[{"if":{"properties":{"decision":{"const":"allow"}},"required":["decision"]},"then":{"properties":{"sections":{"minItems":1}}}}]}}}; +const schema31 = {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"urn:definitely-secure:contract:context-package:1.0.0:context-package","title":"Definitely Secure Studio Context Package v1","oneOf":[{"$ref":"#/$defs/contextPackage"},{"$ref":"#/$defs/contextPackageReference"},{"$ref":"#/$defs/contextAuthorization"}],"$defs":{"safeId":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$"},"namespace":{"type":"string","pattern":"^[a-z0-9]+(?:[._-][a-z0-9]+)+$"},"symbol":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"promptId":{"type":"string","pattern":"^prompt\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?)+$"},"packageId":{"type":"string","pattern":"^context-package\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9]+(?:[a-z0-9-]*[a-z0-9])?)+$"},"semver":{"type":"string","pattern":"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$"},"timestamp":{"type":"string","format":"date-time"},"absoluteUri":{"type":"string","format":"uri","pattern":"^[A-Za-z][A-Za-z0-9+.-]*:"},"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"classification":{"enum":["public","internal","confidential","restricted"]},"owner":{"type":"string","pattern":"^@?[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$"},"packageIdentity":{"type":"object","additionalProperties":false,"required":["id","version","instance_id"],"properties":{"id":{"$ref":"#/$defs/packageId"},"version":{"$ref":"#/$defs/semver"},"instance_id":{"$ref":"#/$defs/safeId"}}},"contentIdentity":{"type":"object","additionalProperties":false,"required":["canonicalization","byte_size","sha256"],"properties":{"canonicalization":{"const":"studio-json-v1"},"byte_size":{"type":"integer","minimum":2},"sha256":{"$ref":"#/$defs/sha256"}}},"artifactIdentity":{"type":"object","additionalProperties":false,"required":["artifact_uri","media_type","byte_size","sha256"],"properties":{"artifact_uri":{"$ref":"#/$defs/absoluteUri"},"media_type":{"type":"string","pattern":"^[A-Za-z0-9!#$&^_.+-]+/[A-Za-z0-9!#$&^_.+-]+$"},"byte_size":{"type":"integer","minimum":1},"sha256":{"$ref":"#/$defs/sha256"}}},"sourceRecord":{"type":"object","additionalProperties":false,"required":["source_id","kind","version","classification","evidence_reference"],"properties":{"source_id":{"$ref":"#/$defs/safeId"},"kind":{"enum":["public-canon","approved-private","caller-supplied","synthetic"]},"version":{"type":"string","minLength":1,"maxLength":200},"classification":{"$ref":"#/$defs/classification"},"evidence_reference":{"$ref":"#/$defs/absoluteUri"},"artifact":{"$ref":"#/$defs/artifactIdentity"}}},"section":{"type":"object","additionalProperties":false,"required":["slot","classification","media_type","content","byte_size","sha256","source_ids"],"properties":{"slot":{"$ref":"#/$defs/symbol"},"classification":{"$ref":"#/$defs/classification"},"media_type":{"enum":["text/plain","application/json"]},"content":{},"byte_size":{"type":"integer","minimum":0},"sha256":{"$ref":"#/$defs/sha256"},"source_ids":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/$defs/safeId"}}},"allOf":[{"if":{"properties":{"media_type":{"const":"text/plain"}},"required":["media_type"]},"then":{"properties":{"content":{"type":"string"}}}}]},"manifest":{"type":"object","additionalProperties":false,"required":["package","builder","created_at","review_after","expires_at","purpose","authority_reference","classification","total_content_bytes","sources","sections"],"properties":{"package":{"$ref":"#/$defs/packageIdentity"},"builder":{"type":"object","additionalProperties":false,"required":["id","version"],"properties":{"id":{"$ref":"#/$defs/namespace"},"version":{"$ref":"#/$defs/semver"}}},"created_at":{"$ref":"#/$defs/timestamp"},"review_after":{"$ref":"#/$defs/timestamp"},"expires_at":{"$ref":"#/$defs/timestamp"},"purpose":{"type":"string","minLength":1,"maxLength":1000},"authority_reference":{"$ref":"#/$defs/absoluteUri"},"classification":{"$ref":"#/$defs/classification"},"total_content_bytes":{"type":"integer","minimum":0},"sources":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/sourceRecord"}},"sections":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/section"}}}},"contextPackage":{"type":"object","additionalProperties":false,"required":["spec_version","kind","manifest","manifest_identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"context-package"},"manifest":{"$ref":"#/$defs/manifest"},"manifest_identity":{"$ref":"#/$defs/contentIdentity"}}},"contextPackageReference":{"type":"object","additionalProperties":false,"required":["spec_version","kind","package","artifact","manifest_identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"context-package-reference"},"package":{"$ref":"#/$defs/packageIdentity"},"artifact":{"allOf":[{"$ref":"#/$defs/artifactIdentity"},{"properties":{"media_type":{"const":"application/vnd.definitely-secure-studio.context-package+json"}}}]},"manifest_identity":{"$ref":"#/$defs/contentIdentity"}}},"contextAuthorization":{"type":"object","additionalProperties":false,"required":["spec_version","kind","decision_id","decision","package","prompt","sections","max_classification","purpose","decided_by","decided_at","expires_at","authority_reference"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"context-authorization"},"decision_id":{"$ref":"#/$defs/safeId"},"decision":{"enum":["allow","deny"]},"package":{"$ref":"#/$defs/packageIdentity"},"prompt":{"type":"object","additionalProperties":false,"required":["id","version"],"properties":{"id":{"$ref":"#/$defs/promptId"},"version":{"$ref":"#/$defs/semver"}}},"sections":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/symbol"}},"max_classification":{"$ref":"#/$defs/classification"},"purpose":{"type":"string","minLength":1,"maxLength":1000},"decided_by":{"$ref":"#/$defs/owner"},"decided_at":{"$ref":"#/$defs/timestamp"},"expires_at":{"$ref":"#/$defs/timestamp"},"authority_reference":{"$ref":"#/$defs/absoluteUri"}},"allOf":[{"if":{"properties":{"decision":{"const":"allow"}},"required":["decision"]},"then":{"properties":{"sections":{"minItems":1}}}}]}}}; const schema32 = {"type":"object","additionalProperties":false,"required":["spec_version","kind","manifest","manifest_identity"],"properties":{"spec_version":{"const":"1.0.0"},"kind":{"const":"context-package"},"manifest":{"$ref":"#/$defs/manifest"},"manifest_identity":{"$ref":"#/$defs/contentIdentity"}}}; const schema33 = {"type":"object","additionalProperties":false,"required":["package","builder","created_at","review_after","expires_at","purpose","authority_reference","classification","total_content_bytes","sources","sections"],"properties":{"package":{"$ref":"#/$defs/packageIdentity"},"builder":{"type":"object","additionalProperties":false,"required":["id","version"],"properties":{"id":{"$ref":"#/$defs/namespace"},"version":{"$ref":"#/$defs/semver"}}},"created_at":{"$ref":"#/$defs/timestamp"},"review_after":{"$ref":"#/$defs/timestamp"},"expires_at":{"$ref":"#/$defs/timestamp"},"purpose":{"type":"string","minLength":1,"maxLength":1000},"authority_reference":{"$ref":"#/$defs/absoluteUri"},"classification":{"$ref":"#/$defs/classification"},"total_content_bytes":{"type":"integer","minimum":0},"sources":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/sourceRecord"}},"sections":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/section"}}}}; const schema38 = {"type":"string","pattern":"^[a-z0-9]+(?:[._-][a-z0-9]+)+$"}; @@ -2478,7 +2478,7 @@ validate40.evaluated = {"props":true,"dynamicProps":false,"dynamicItems":false}; function validate20(data, {instancePath="", parentData, parentDataProperty, rootData=data, dynamicAnchors={}}={}){ -/*# sourceURL="https://schemas.definitelysecure.studio/context-packages/v1/context-package.schema.json" */; +/*# sourceURL="urn:definitely-secure:contract:context-package:1.0.0:context-package" */; let vErrors = null; let errors = 0; const evaluated0 = validate20.evaluated; diff --git a/tests/prompt-sdk/release-readiness.test.js b/tests/prompt-sdk/release-readiness.test.js new file mode 100644 index 0000000..cfa2934 --- /dev/null +++ b/tests/prompt-sdk/release-readiness.test.js @@ -0,0 +1,15 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; +import * as sdk from '../../src/prompt-sdk/index.js'; +import { releaseReadiness } from '../../scripts/check-sdk-release.mjs'; +test('documented v1 API inventory exactly matches public exports', async () => { + const inventory = JSON.parse(await readFile(new URL('../../release/api-v1.json', import.meta.url))); + assert.deepEqual(Object.keys(sdk).sort(), inventory); +}); +test('unpublished SDK is explicitly blocked from stable release', async () => { + const report = await releaseReadiness(); + assert.equal(report.ready, false); + assert.ok(report.blockers.some(message => message.includes('immutable'))); + assert.ok(report.blockers.some(message => message.includes('provisional'))); +});