-
Notifications
You must be signed in to change notification settings - Fork 0
Prepare Prompt SDK v1 API and release readiness (#72) #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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/<name>/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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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" | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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)) || | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an adoption lock contains an ambiguous or non-RFC-3339 value such as Useful? React with 👍 / 👎. |
||
| !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) + '/')) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a structurally malformed lock supplies a numeric, object, or boolean Useful? React with 👍 / 👎. |
||
| 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; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the follow-up release change sets the package and contract statuses to stable, a
contract-lock.jsoncontaining valid but structurally invalid JSON such asnullorfalseproduces no read error and skips this entire block, allowingreleaseReadiness()to returnready: truewithout any of the five required contracts. Validate the parsed value as an object and add a blocker unless it contains the required contracts array.Useful? React with 👍 / 👎.