Document Scriptorium as a Promptkit application
This commit is contained in:
33
README.md
33
README.md
@@ -1,12 +1,15 @@
|
|||||||
# scriptorium
|
# Scriptorium
|
||||||
|
|
||||||
Scriptorium is a narrow prompt-execution application for rendering prompt
|
Scriptorium is a prompt-execution application with a command-line interface and
|
||||||
requests, running them against OpenAI-compatible chat-completions endpoints, and
|
an HTTP service. It prepares prompt requests, runs them against
|
||||||
serving the same run workflow over HTTP.
|
OpenAI-compatible model endpoints, and returns generated output with validation
|
||||||
|
metadata.
|
||||||
|
|
||||||
It keeps prompt definitions, execution profiles, schemas, and input artifacts as
|
The application uses
|
||||||
separate files so prompts can be reviewed and reused without baking model
|
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/)
|
||||||
runtime settings into application code.
|
for prompt, profile, schema, preparation, generation, and validation behavior.
|
||||||
|
Scriptorium owns executable configuration, CLI and HTTP mapping, process
|
||||||
|
behavior, output presentation, and HTTP artifact-containment policy.
|
||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
@@ -21,8 +24,9 @@ go run ./cmd/scriptorium render \
|
|||||||
--format json
|
--format json
|
||||||
```
|
```
|
||||||
|
|
||||||
This command renders the prepared prompt and effective runtime settings without calling an LLM.
|
This renders the prepared prompt and effective runtime settings without calling
|
||||||
For complete invocation and output behavior, see the [CLI reference](docs/cli.md).
|
a model. For complete invocation and output behavior, see the
|
||||||
|
[CLI reference](docs/cli.md).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
@@ -31,15 +35,16 @@ For complete invocation and output behavior, see the [CLI reference](docs/cli.md
|
|||||||
- [HTTP API reference](docs/api.md)
|
- [HTTP API reference](docs/api.md)
|
||||||
- [Operations guide](docs/operations.md)
|
- [Operations guide](docs/operations.md)
|
||||||
- [Consumer integration overview](docs/consumers/api.md)
|
- [Consumer integration overview](docs/consumers/api.md)
|
||||||
- [Go library package](docs/consumers/pkg-scriptorium.md)
|
|
||||||
- [Subprocess integration](docs/integrations/subprocess.md)
|
- [Subprocess integration](docs/integrations/subprocess.md)
|
||||||
- [OpenAI-compatible chat integration](docs/integrations/openai-compatible-chat.md)
|
|
||||||
- [Architecture policy](docs/policy/architecture.md)
|
- [Architecture policy](docs/policy/architecture.md)
|
||||||
|
- [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md)
|
||||||
|
- [Promptkit Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md)
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
- [Minimal configuration](examples/config.yml) and [complete configuration](examples/config.full.yml)
|
- [Minimal configuration](examples/config.yml) and
|
||||||
- [Prompt definitions](examples/prompts/), [execution profiles](examples/profiles/), [schemas](examples/schemas/), and [synthetic input fixtures](examples/fixtures/)
|
[complete configuration](examples/config.full.yml)
|
||||||
|
- [Prompt definitions](examples/prompts/), [execution profiles](examples/profiles/),
|
||||||
|
[schemas](examples/schemas/), and [synthetic input fixtures](examples/fixtures/)
|
||||||
- [Render script](examples/render-markdown-summary.sh)
|
- [Render script](examples/render-markdown-summary.sh)
|
||||||
- [HTTP request](examples/http-run.json)
|
- [HTTP request](examples/http-run.json)
|
||||||
- [Go library example](examples/go-library/prepare/main.go)
|
|
||||||
|
|||||||
@@ -66,11 +66,12 @@ untrusted writers.
|
|||||||
The optional `model` object accepts `endpoint`, `model`, `temperature`,
|
The optional `model` object accepts `endpoint`, `model`, `temperature`,
|
||||||
`max_tokens`, `top_p`, `timeout_seconds`, `service_tier`,
|
`max_tokens`, `top_p`, `timeout_seconds`, `service_tier`,
|
||||||
`reasoning_effort`, `api_key_env`, and `extra_params`. Numeric ranges and
|
`reasoning_effort`, `api_key_env`, and `extra_params`. Numeric ranges and
|
||||||
credential supply are defined by the [configuration reference](config.md).
|
framework credential semantics are defined by the
|
||||||
|
[Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md).
|
||||||
Explicit zero values for the numeric fields are overrides; zero
|
Explicit zero values for the numeric fields are overrides; zero
|
||||||
`timeout_seconds` disables the per-generation deadline only, retaining the
|
`timeout_seconds` disables the per-generation deadline only, retaining the
|
||||||
request context and configured transport cap. The timeout layers are defined in
|
request context and configured transport cap. The timeout layers are defined in
|
||||||
the [outbound integration contract](integrations/openai-compatible-chat.md#authentication-and-timeout).
|
the [Promptkit outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md#timeout-and-cancellation).
|
||||||
|
|
||||||
Raw API-key values are not accepted. `api_key` and any other unknown model
|
Raw API-key values are not accepted. `api_key` and any other unknown model
|
||||||
field cause `400 invalid_json`.
|
field cause `400 invalid_json`.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# CLI Reference
|
# CLI Reference
|
||||||
|
|
||||||
This is the canonical contract for invoking Scriptorium. Configuration discovery,
|
This is the canonical contract for invoking Scriptorium. Configuration discovery,
|
||||||
precedence, directories, profiles, and schemas are defined in the
|
precedence, application source locations, and server settings are defined in the
|
||||||
[configuration reference](config.md). The [HTTP API reference](api.md) owns
|
[configuration reference](config.md). The [HTTP API reference](api.md) owns
|
||||||
service request and response behavior.
|
service request and response behavior.
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ only; the caller context and configured transport cap remain active. CLI
|
|||||||
durations are converted to whole seconds by truncation toward zero, so any
|
durations are converted to whole seconds by truncation toward zero, so any
|
||||||
duration whose absolute value is below one second becomes an explicit
|
duration whose absolute value is below one second becomes an explicit
|
||||||
zero-second override. The timeout layers are defined in the
|
zero-second override. The timeout layers are defined in the
|
||||||
[outbound integration contract](integrations/openai-compatible-chat.md#authentication-and-timeout).
|
[Promptkit outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md#timeout-and-cancellation).
|
||||||
|
|
||||||
There is no raw API-key flag. Use `--api-key-env`.
|
There is no raw API-key flag. Use `--api-key-env`.
|
||||||
|
|
||||||
|
|||||||
177
docs/config.md
177
docs/config.md
@@ -1,15 +1,17 @@
|
|||||||
# Configuration Reference
|
# Configuration Reference
|
||||||
|
|
||||||
This is the canonical reference for Scriptorium application settings and the
|
This is the canonical reference for Scriptorium application settings. Prompt,
|
||||||
prompt, profile, and schema files those settings select. For command syntax,
|
profile, schema, execution-setting, built-in profile, and framework credential
|
||||||
see the [CLI reference](cli.md); for HTTP request shapes, limits, and outcomes,
|
semantics are defined by the
|
||||||
see the [HTTP API reference](api.md).
|
[Promptkit v0.1.0 format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md).
|
||||||
|
For command syntax, see the [CLI reference](cli.md); for HTTP request shapes and
|
||||||
|
outcomes, see the [HTTP API reference](api.md).
|
||||||
|
|
||||||
## Discovery And Precedence
|
## Discovery And Precedence
|
||||||
|
|
||||||
Application settings are resolved in this order:
|
Application settings are resolved in this order:
|
||||||
|
|
||||||
1. built-in defaults;
|
1. built-in Scriptorium defaults;
|
||||||
2. a configuration file; then
|
2. a configuration file; then
|
||||||
3. CLI overrides.
|
3. CLI overrides.
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ If neither exists, it uses built-in defaults. An explicit `--config` path must
|
|||||||
exist and decode successfully.
|
exist and decode successfully.
|
||||||
|
|
||||||
The maintained [minimal configuration](../examples/config.yml) and
|
The maintained [minimal configuration](../examples/config.yml) and
|
||||||
[full configuration](../examples/config.full.yml) are copyable examples.
|
[complete configuration](../examples/config.full.yml) are copyable examples.
|
||||||
|
|
||||||
## Application Configuration File
|
## Application Configuration File
|
||||||
|
|
||||||
@@ -28,146 +30,57 @@ do not override a prior value. Raw API-key fields are not accepted.
|
|||||||
|
|
||||||
| Field | Default | Meaning |
|
| Field | Default | Meaning |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `prompt_dir` | unset | Directory containing prompt-definition YAML. `run`, `render`, and `serve` require an effective value. |
|
| `prompt_dir` | unset | Promptkit prompt-definition source directory. `run`, `render`, and `serve` require an effective value. |
|
||||||
| `profile_dir` | unset | Directory containing custom profile YAML. Built-in profiles remain available. |
|
| `profile_dir` | unset | Optional custom Promptkit profile source directory overlaid on Promptkit built-ins. |
|
||||||
| `schema_dir` | `.` | Base directory for relative JSON Schema paths. |
|
| `schema_dir` | `.` | Promptkit schema source directory for relative schema paths. |
|
||||||
| `server.addr` | `:8080` | Address used by `serve`. |
|
| `server.addr` | `:8080` | Address used by `serve`. |
|
||||||
| `server.artifact_root` | unset | Root that enables HTTP `file` input references. |
|
| `server.artifact_root` | unset | Root that enables HTTP `file` input references. |
|
||||||
| `server.max_request_bytes` | `16777216` | Maximum encoded HTTP request body bytes; `0` disables the limit. |
|
| `server.max_request_bytes` | `16777216` | Maximum encoded HTTP request-body bytes; `0` disables the limit. |
|
||||||
| `server.max_artifact_bytes` | `16777216` | Maximum HTTP file-input artifact bytes; `0` disables the limit. |
|
| `server.max_artifact_bytes` | `16777216` | Maximum HTTP file-input artifact bytes; `0` disables the limit. |
|
||||||
| `server.max_response_bytes` | `16777216` | Maximum encoded HTTP response bytes; `0` disables the limit. |
|
| `server.max_response_bytes` | `16777216` | Maximum encoded HTTP response bytes; `0` disables the limit. |
|
||||||
| `defaults.render_format` | `text` | Default `render` output format: `text` or `json`. |
|
| `defaults.render_format` | `text` | Default prepared-run output format: `text` or `json`. |
|
||||||
|
|
||||||
The three size fields must be zero or greater. The HTTP contract defines how
|
The size fields must be zero or greater. The [HTTP API](api.md) defines how
|
||||||
each limit is enforced and reported. `server.artifact_root` configures the
|
each limit is enforced and reported. `server.artifact_root` configures an HTTP
|
||||||
deployment boundary; see the [HTTP API reference](api.md) for request-path and
|
deployment boundary; see [operations](operations.md) for deployment handling.
|
||||||
containment behavior, and [operations](operations.md) for deployment handling.
|
|
||||||
|
|
||||||
## Prompt Definition Files
|
## Framework Source Mapping
|
||||||
|
|
||||||
Prompt definitions are strict YAML files anywhere below `prompt_dir`. A prompt
|
Scriptorium passes `prompt_dir`, `profile_dir`, and `schema_dir` to Promptkit
|
||||||
is selected by its YAML `id`, not by file path; nested directories are only for
|
when constructing its engine. Scriptorium does not redefine or independently
|
||||||
organization. See [maintained prompt examples](../examples/prompts/).
|
parse those framework file formats.
|
||||||
|
|
||||||
| Field | Required | Meaning |
|
- Prompt selection, versions, message templates, inputs, output contracts, and
|
||||||
| --- | --- | --- |
|
session IDs are Promptkit contracts.
|
||||||
| `id` | yes | Prompt identifier. |
|
- Profile fields, numeric ranges, execution defaults, overlay precedence,
|
||||||
| `version` | yes | Prompt version. |
|
built-in profiles, and credential rules are Promptkit contracts.
|
||||||
| `default_profile` | no | Profile used when a request omits a profile ID. |
|
- Schema path behavior and generated-content validation are Promptkit
|
||||||
| `description` | no | Human-readable description. |
|
contracts.
|
||||||
| `session_id` | no | Go-template string rendered from request variables and sent to a compatible provider when non-empty. |
|
|
||||||
| `inputs` | no | Declared input metadata. |
|
|
||||||
| `messages` | yes | Chat-message templates. |
|
|
||||||
| `output` | yes | Output format and validation contract. |
|
|
||||||
|
|
||||||
### Inputs And Messages
|
See the
|
||||||
|
[tagged Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md)
|
||||||
|
for all of those definitions. The files under
|
||||||
|
[`examples/prompts`](../examples/prompts/),
|
||||||
|
[`examples/profiles`](../examples/profiles/), and
|
||||||
|
[`examples/schemas`](../examples/schemas/) are maintained Scriptorium
|
||||||
|
application inputs using that tagged format.
|
||||||
|
|
||||||
Each `inputs` item has a required `name` and optional `required`,
|
## Credentials And Outbound Behavior
|
||||||
`content_type`, and `description` fields. Input names must be unique.
|
|
||||||
|
|
||||||
Each message has a required `role`, exactly one of `content` or `content_file`,
|
Scriptorium maps `--api-key-env` and HTTP `model.api_key_env` into Promptkit
|
||||||
and optional `cache_control`. A `content_file` path is relative to the prompt
|
request overrides. Keep secret values in environment variables and store only
|
||||||
file. `cache_control.type` must be `ephemeral`; its optional `ttl` is `1h`.
|
their names in configuration or framework source files. Do not place raw keys
|
||||||
|
in configuration, prompts, profiles, CLI arguments, examples, or HTTP
|
||||||
|
payloads.
|
||||||
|
|
||||||
`session_id` uses the same template variables as messages. Empty rendered
|
Promptkit's
|
||||||
values are omitted. A rendered value may contain at most 256 Unicode code
|
[OpenAI-compatible integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md)
|
||||||
points.
|
defines outbound authentication, provider request mapping, transport limits,
|
||||||
|
and timeout layering.
|
||||||
### Output Contract
|
|
||||||
|
|
||||||
| Field | Required | Values or behavior |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `format` | yes | `text`, `markdown`, or `json`. |
|
|
||||||
| `validation_mode` | yes | `none`, `basic`, `json`, or `json_schema`. |
|
|
||||||
| `schema_path` | for `json_schema` | Schema path, relative to `schema_dir` unless absolute. |
|
|
||||||
| `repair_attempts` | no | Integer greater than or equal to `0`; omitted means `0`. |
|
|
||||||
|
|
||||||
## Profile Definition Files
|
|
||||||
|
|
||||||
Profiles are strict YAML files anywhere below `profile_dir`. A profile is
|
|
||||||
selected by YAML `id`; nested directories are organizational. See the
|
|
||||||
[maintained profile examples](../examples/profiles/).
|
|
||||||
|
|
||||||
| Field | Required | Meaning |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `id` | yes | Profile identifier. |
|
|
||||||
| `endpoint` | yes | OpenAI-compatible base URL, including its API version path when needed. |
|
|
||||||
| `model` | yes | Provider model name. |
|
|
||||||
| `temperature` | no | Number from `0` through `2`. |
|
|
||||||
| `max_tokens` | no | Integer zero or greater. |
|
|
||||||
| `top_p` | no | Number from `0` through `1`. |
|
|
||||||
| `timeout_seconds` | no | Per-generation-call deadline in whole seconds; integer zero or greater. |
|
|
||||||
| `service_tier` | no | Non-empty provider-specific request tier. |
|
|
||||||
| `reasoning_effort` | no | Non-empty provider-specific reasoning setting. |
|
|
||||||
| `api_key_env` | no | Environment-variable name containing the API key. |
|
|
||||||
| `extra_params` | no | JSON-compatible provider-specific outbound request fields. |
|
|
||||||
|
|
||||||
Execution defaults before profile and request overrides are `temperature: 0`,
|
|
||||||
`max_tokens: 0`, `top_p: 1`, and `timeout_seconds: 600`. Profile numeric values
|
|
||||||
merge by non-zero value. Request overrides preserve presence, so an explicit
|
|
||||||
zero can override a profile value. For `timeout_seconds`, explicit request zero
|
|
||||||
disables the generation deadline while retaining the caller context and the
|
|
||||||
built-in client's transport cap. See the
|
|
||||||
[OpenAI-compatible integration contract](integrations/openai-compatible-chat.md#authentication-and-timeout)
|
|
||||||
for the complete timeout interaction.
|
|
||||||
|
|
||||||
Custom profiles take precedence over built-ins with the same ID. Invalid custom
|
|
||||||
profiles are errors; they do not fall back to a built-in profile. Raw `api_key`
|
|
||||||
is rejected. Use `api_key_env`, or the public Go package's request-scoped key
|
|
||||||
mechanism described in the [package contract](consumers/pkg-scriptorium.md).
|
|
||||||
|
|
||||||
`extra_params` keys must be non-empty and cannot be `model`, `session_id`,
|
|
||||||
`messages`, `temperature`, `max_tokens`, `top_p`, `service_tier`,
|
|
||||||
`reasoning_effort`, or `response_format`.
|
|
||||||
|
|
||||||
### Built-In Profile Catalog
|
|
||||||
|
|
||||||
Each embedded profile uses `OPENROUTER_API_KEY`.
|
|
||||||
|
|
||||||
| Provider | ID | Model |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| aion-labs | `aion-2` | `aion-labs/aion-2.0` |
|
|
||||||
| anthropic | `claude-fable-latest` | `~anthropic/claude-fable-latest` |
|
|
||||||
| anthropic | `claude-haiku-latest` | `~anthropic/claude-haiku-latest` |
|
|
||||||
| anthropic | `claude-opus-latest` | `~anthropic/claude-opus-latest` |
|
|
||||||
| anthropic | `claude-sonnet-latest` | `~anthropic/claude-sonnet-latest` |
|
|
||||||
| deepseek | `deepseek-3-2` | `deepseek/deepseek-v3.2` |
|
|
||||||
| deepseek | `deepseek-4-flash` | `deepseek/deepseek-v4-flash` |
|
|
||||||
| deepseek | `deepseek-4-pro` | `deepseek/deepseek-v4-pro` |
|
|
||||||
| google | `gemini-2-flash` | `google/gemini-2.5-flash` |
|
|
||||||
| google | `gemini-2-flash-lite` | `google/gemini-2.5-flash-lite` |
|
|
||||||
| google | `gemini-2-pro` | `google/gemini-2.5-pro` |
|
|
||||||
| google | `gemini-3-flash-lite` | `google/gemini-3.1-flash-lite` |
|
|
||||||
| google | `gemini-flash-latest` | `~google/gemini-flash-latest` |
|
|
||||||
| google | `gemini-pro-latest` | `~google/gemini-pro-latest` |
|
|
||||||
| google | `gemma-4-31b` | `google/gemma-4-31b-it:exacto` |
|
|
||||||
| minimax | `minimax-m2` | `minimax/minimax-m2.5` |
|
|
||||||
| minimax | `minimax-m3` | `minimax/minimax-m3` |
|
|
||||||
| mistral | `mistral-large-2512` | `mistralai/mistral-large-2512` |
|
|
||||||
| mistral | `mistral-medium-3-5` | `mistralai/mistral-medium-3-5` |
|
|
||||||
| mistral | `mistral-small-3` | `mistralai/mistral-small-3.2-24b-instruct` |
|
|
||||||
| mistral | `mistral-small-4` | `mistralai/mistral-small-2603` |
|
|
||||||
| nvidia | `nemotron-3-ultra` | `nvidia/nemotron-3-ultra-550b-a55b` |
|
|
||||||
| openai | `gpt-5-mini` | `openai/gpt-5.4-mini` |
|
|
||||||
| openai | `gpt-5-nano` | `openai/gpt-5.4-nano` |
|
|
||||||
|
|
||||||
## Schemas
|
|
||||||
|
|
||||||
Schemas are JSON files, normally below `schema_dir`. `json_schema` output
|
|
||||||
requires a `schema_path`. Relative paths resolve from `schema_dir`; absolute
|
|
||||||
paths are used directly. Referenced nested schemas use relative paths and are
|
|
||||||
not discovered by basename. An unreadable or invalid schema is a runtime
|
|
||||||
validation error; generated content that fails JSON or schema validation is a
|
|
||||||
validation result.
|
|
||||||
|
|
||||||
## Credentials
|
|
||||||
|
|
||||||
Keep secrets in environment variables. Store only an environment-variable name
|
|
||||||
in `api_key_env`; do not place raw keys in configuration, prompt or profile
|
|
||||||
files, CLI arguments, examples, or HTTP payloads.
|
|
||||||
|
|
||||||
## Related References
|
## Related References
|
||||||
|
|
||||||
- [CLI reference](cli.md)
|
- [CLI reference](cli.md)
|
||||||
- [HTTP API reference](api.md)
|
- [HTTP API reference](api.md)
|
||||||
- [OpenAI-compatible outbound contract](integrations/openai-compatible-chat.md)
|
- [Operations guide](operations.md)
|
||||||
|
- [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md)
|
||||||
|
|||||||
@@ -1,45 +1,21 @@
|
|||||||
# Consumer Integration Overview
|
# Consumer Integration Overview
|
||||||
|
|
||||||
This guide helps applications choose a Scriptorium interface and understand
|
Scriptorium exposes executable interfaces. Choose between a local subprocess
|
||||||
their responsibilities. The linked contracts own interface syntax and wire
|
and the HTTP service according to the boundary your application needs.
|
||||||
semantics.
|
|
||||||
|
|
||||||
| Interface | Use when |
|
| Interface | Use when |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Go package | The consumer is Go and needs typed requests, results, or an injected LLM client. |
|
| CLI subprocess | The consumer needs a synchronous local process boundary or prepared output. |
|
||||||
| CLI subprocess | The consumer needs process isolation or is not written in Go. |
|
|
||||||
| HTTP API | The consumer needs a service boundary or remote access. |
|
| HTTP API | The consumer needs a service boundary or remote access. |
|
||||||
|
|
||||||
- Go package: [package contract](pkg-scriptorium.md)
|
|
||||||
- CLI subprocess: [subprocess integration](../integrations/subprocess.md)
|
- CLI subprocess: [subprocess integration](../integrations/subprocess.md)
|
||||||
- HTTP service: [HTTP API reference](../api.md)
|
- HTTP service: [HTTP API reference](../api.md)
|
||||||
- Prompt, profile, schema, and credential configuration: [configuration reference](../config.md)
|
- Application configuration: [configuration reference](../config.md)
|
||||||
|
|
||||||
## Minimal Go Use
|
Go applications that need an in-process prompt framework should import
|
||||||
|
Promptkit directly. The tagged
|
||||||
```go
|
[Promptkit Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md)
|
||||||
engine, err := scriptorium.NewEngine(scriptorium.Config{
|
owns that interface; Scriptorium does not provide a Go library package.
|
||||||
PromptDir: "./examples/prompts",
|
|
||||||
ProfileDir: "./examples/profiles",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
prepared, err := engine.Prepare(ctx, scriptorium.RunRequest{
|
|
||||||
PromptID: "generic.markdown_summary",
|
|
||||||
Inputs: map[string]scriptorium.ArtifactRef{
|
|
||||||
"transcript": scriptorium.File("./examples/fixtures/transcript.md"),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_ = prepared
|
|
||||||
```
|
|
||||||
|
|
||||||
For a maintained program, see
|
|
||||||
[`examples/go-library/prepare`](../../examples/go-library/prepare).
|
|
||||||
|
|
||||||
## Consumer Responsibilities
|
## Consumer Responsibilities
|
||||||
|
|
||||||
@@ -47,13 +23,14 @@ Consumers are responsible for:
|
|||||||
|
|
||||||
- selecting and deploying prompt, profile, and schema assets;
|
- selecting and deploying prompt, profile, and schema assets;
|
||||||
- supplying required inputs and template variables;
|
- supplying required inputs and template variables;
|
||||||
- supplying credentials through the applicable interface;
|
- supplying credentials through the chosen interface;
|
||||||
- protecting rendered prompts and generated artifacts as potentially sensitive;
|
- protecting rendered prompts and generated artifacts as potentially
|
||||||
|
sensitive;
|
||||||
- deciding whether validation-failed output is usable; and
|
- deciding whether validation-failed output is usable; and
|
||||||
- retrying only when another model call is acceptable.
|
- retrying only when another model call is acceptable.
|
||||||
|
|
||||||
Scriptorium does not persist run state. A retry can produce different output and
|
Scriptorium does not persist run state. A retry can produce different output
|
||||||
can incur another provider request. CLI exit behavior belongs to the
|
and can incur another provider request. CLI exits belong to the
|
||||||
[CLI reference](../cli.md); HTTP status behavior belongs to the
|
[CLI reference](../cli.md), HTTP status behavior belongs to the
|
||||||
[HTTP API reference](../api.md); package errors and results belong to the
|
[HTTP API reference](../api.md), and framework semantics belong to
|
||||||
[package contract](pkg-scriptorium.md).
|
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md).
|
||||||
|
|||||||
@@ -1,203 +0,0 @@
|
|||||||
# Package `scriptorium`
|
|
||||||
|
|
||||||
Import path:
|
|
||||||
|
|
||||||
```go
|
|
||||||
import "gitea.maximumdirect.net/eric/scriptorium"
|
|
||||||
```
|
|
||||||
|
|
||||||
This is the canonical public Go contract for in-process prompt preparation and
|
|
||||||
execution. Prompt, profile, and schema file formats are defined in the
|
|
||||||
[configuration reference](../config.md).
|
|
||||||
|
|
||||||
## Engine Construction
|
|
||||||
|
|
||||||
`NewEngine(Config, ...Option)` constructs an engine. `Config` has these
|
|
||||||
fields:
|
|
||||||
|
|
||||||
| Field | Meaning |
|
|
||||||
| --- | --- |
|
|
||||||
| `PromptDir` | Prompt-definition directory, required unless a prompt source option is supplied. |
|
|
||||||
| `ProfileDir` | Optional custom profile directory over built-ins. |
|
|
||||||
| `SchemaDir` | Schema directory; empty uses `.`. |
|
|
||||||
| `Timeout` | Transport-wide safety cap for the built-in OpenAI-compatible client when `HTTPClient` is absent or has a non-positive timeout. A non-positive value uses the internal ten-minute default. |
|
|
||||||
| `HTTPClient` | Optional HTTP client for that built-in client. It is cloned; a positive `Timeout` on it is the transport cap and takes precedence over `Config.Timeout`. A non-positive client timeout is treated as unset. |
|
|
||||||
|
|
||||||
Nil options are ignored. Invalid construction, including
|
|
||||||
`WithLLMClient(nil)` and `WithArtifactReader(nil)`, returns an error matching
|
|
||||||
`ErrInvalidConfig`.
|
|
||||||
|
|
||||||
Profile and request `timeout_seconds` values select a per-generation-call
|
|
||||||
deadline independently of the transport cap. An explicit request override of
|
|
||||||
zero disables that generation deadline only. The complete interaction with the
|
|
||||||
caller context is defined in the
|
|
||||||
[OpenAI-compatible integration contract](../integrations/openai-compatible-chat.md#authentication-and-timeout).
|
|
||||||
|
|
||||||
Source options replace their matching directory source:
|
|
||||||
|
|
||||||
- prompts: `WithPromptFS(fsys, root)`, `WithPromptFile(path)`;
|
|
||||||
- profiles: `WithProfileFS(fsys, root)`, `WithProfileFile(path)`, and
|
|
||||||
`WithProfiles(profiles...)`;
|
|
||||||
- schemas: `WithSchemaFS(fsys, root)`, `WithSchemaFile(path)`; and
|
|
||||||
- LLM client: `WithLLMClient(client)`; and
|
|
||||||
- artifact reader: `WithArtifactReader(reader)`.
|
|
||||||
|
|
||||||
`fs.FS` prompt-content and schema paths stay inside their configured roots.
|
|
||||||
Single-file prompt and profile sources are selected by their YAML `id`, not
|
|
||||||
their file names. `WithPromptFile` resolves relative `content_file` paths from
|
|
||||||
the prompt file's directory. `WithSchemaFile` exposes its schema by the schema
|
|
||||||
file's base name. In-memory profiles take precedence over an explicit or
|
|
||||||
directory-backed profile source, which in turn takes precedence over built-ins.
|
|
||||||
File and filesystem sources use the format and credential rules in the
|
|
||||||
[configuration reference](../config.md).
|
|
||||||
|
|
||||||
## Prepare And Run
|
|
||||||
|
|
||||||
`Prepare(ctx, request)` resolves the prompt, profile, input artifacts,
|
|
||||||
validation contract, and rendered messages without calling an LLM.
|
|
||||||
`Run(ctx, request)` performs that preparation, calls the configured client,
|
|
||||||
and validates generated content.
|
|
||||||
|
|
||||||
```go
|
|
||||||
engine, err := scriptorium.NewEngine(scriptorium.Config{
|
|
||||||
PromptDir: "./examples/prompts",
|
|
||||||
ProfileDir: "./examples/profiles",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
prepared, err := engine.Prepare(ctx, scriptorium.RunRequest{
|
|
||||||
PromptID: "generic.markdown_summary",
|
|
||||||
Inputs: map[string]scriptorium.ArtifactRef{
|
|
||||||
"transcript": scriptorium.File("./examples/fixtures/transcript.md"),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_ = prepared.Messages
|
|
||||||
```
|
|
||||||
|
|
||||||
The maintained package example is
|
|
||||||
[`examples/go-library/prepare`](../../examples/go-library/prepare).
|
|
||||||
|
|
||||||
`PreparedRun` exposes prompt, selected-profile, effective-model, output
|
|
||||||
contract, structured-output, input-hash, rendered-message, and timing
|
|
||||||
information. It does not include a resolved API key, model output, validation
|
|
||||||
result, or target-presence metadata.
|
|
||||||
|
|
||||||
`RunResult` adds run ID, artifact, raw output, validation, model metadata,
|
|
||||||
usage, and duration. Generated-content validation failures return a result with
|
|
||||||
`Validation.Status == ValidationFailed`; schema or validator runtime failures
|
|
||||||
return an error matching `ErrValidation`.
|
|
||||||
|
|
||||||
## Public Values
|
|
||||||
|
|
||||||
`ArtifactRef` has `Type`, `URI`, and `Body`; `Artifact` has `Name`,
|
|
||||||
`ContentType`, `Body`, `URI`, `Size`, and `Hash`. `ExecutionTarget` exposes the
|
|
||||||
effective endpoint, model, numeric settings, credential-environment name,
|
|
||||||
service tier, reasoning effort, and extra parameters. `ValidationResult`
|
|
||||||
contains status, mode, errors, schema path, repair attempts, and validity.
|
|
||||||
|
|
||||||
The exported constants define these serialized values:
|
|
||||||
|
|
||||||
- artifact types: `inline` and `file`;
|
|
||||||
- output formats: `text`, `markdown`, and `json`;
|
|
||||||
- validation modes: `none`, `basic`, `json`, and `json_schema`; and
|
|
||||||
- validation statuses: `passed`, `failed`, and `skipped`.
|
|
||||||
|
|
||||||
`TokenUsage` reports prompt, completion, total, cached, and cache-write token
|
|
||||||
counts. `RenderedPrompt`, `RenderedMessage`, `CacheControl`, and
|
|
||||||
`StructuredOutputSpec` are the public shapes used by injected LLM clients.
|
|
||||||
|
|
||||||
`ArtifactReader` implements
|
|
||||||
`Read(context.Context, ArtifactRef) (*Artifact, error)`. Supplying it through
|
|
||||||
`WithArtifactReader` replaces, rather than extends, the engine's default inline
|
|
||||||
and file reader for every input. Omitting the option retains that default;
|
|
||||||
`WithArtifactReader(nil)` makes engine construction fail with
|
|
||||||
`ErrInvalidConfig`.
|
|
||||||
|
|
||||||
Reader failures are surfaced as errors matching `ErrArtifactLoad` while
|
|
||||||
preserving the reader's original error identity for `errors.Is`. A `(nil, nil)`
|
|
||||||
reader response is also an artifact-load failure. Readers are responsible for
|
|
||||||
artifact metadata, although the engine assigns the input-map name when the
|
|
||||||
returned name is empty; readers should not retain or mutate caller values.
|
|
||||||
|
|
||||||
## Requests, Inputs, And Overrides
|
|
||||||
|
|
||||||
`RunRequest` fields are `PromptID`, `PromptVersion`, `ProfileID`,
|
|
||||||
`APIKey`, `Inputs`, `Vars`, `Execution`, `Validation`, and
|
|
||||||
`Metadata`.
|
|
||||||
|
|
||||||
Input helpers are:
|
|
||||||
|
|
||||||
- `File(path)` for a file-backed artifact;
|
|
||||||
- `Inline(body)` for inline content; and
|
|
||||||
- `InlineWithURI(uri, body)` for inline content with URI metadata.
|
|
||||||
|
|
||||||
Required declared inputs must be supplied. Template rendering must also resolve
|
|
||||||
every input name the prompt actually references. Extra entries in `Inputs`
|
|
||||||
are not rejected solely because they are undeclared.
|
|
||||||
|
|
||||||
`ExecutionTargetOverride` supplies endpoint, model, credential-environment,
|
|
||||||
service-tier, reasoning-effort, and extra-parameter overrides. Its numeric
|
|
||||||
fields (`Temperature`, `MaxTokens`, `TopP`, and `TimeoutSeconds`) are
|
|
||||||
pointers so explicit zero values are preserved. `OutputContract` supplies
|
|
||||||
`Format`, `ValidationMode`, `SchemaPath`, and `RepairAttempts`.
|
|
||||||
|
|
||||||
`ExtraParams` accepts JSON-compatible values: strings, booleans, finite
|
|
||||||
numbers, objects with string keys, arrays or slices, and nil. Unsupported
|
|
||||||
values, non-string map keys, non-finite floats, and cycles return
|
|
||||||
`ErrInvalidConfig` for profiles or `ErrInvalidRequest` for request
|
|
||||||
overrides.
|
|
||||||
|
|
||||||
## Profiles And Credentials
|
|
||||||
|
|
||||||
`OpenAICompatibleProfile(OpenAICompatibleProfileConfig)` creates an
|
|
||||||
in-memory `Profile`. Its public fields are `ID`, `Endpoint`, `Model`,
|
|
||||||
`Temperature`, `MaxTokens`, `TopP`, `TimeoutSeconds`, `ServiceTier`,
|
|
||||||
`ReasoningEffort`, `APIKeyRequired`, and `ExtraParams`.
|
|
||||||
`WithProfiles` rejects duplicate IDs in one call.
|
|
||||||
|
|
||||||
A direct `RunRequest.APIKey` is request-scoped and takes precedence over
|
|
||||||
`api_key_env` for the built-in client. It is excluded from JSON output and
|
|
||||||
from `PreparedRun` and `RunResult`. The package's `String` and
|
|
||||||
`GoString` methods report only whether a direct key is set. Do not use
|
|
||||||
reflection-based dumps of request structs, which can bypass that redaction.
|
|
||||||
|
|
||||||
## Injected LLM Clients
|
|
||||||
|
|
||||||
`LLMClient` implements:
|
|
||||||
|
|
||||||
```go
|
|
||||||
Generate(context.Context, GenerateRequest) (*GenerateResponse, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
Injected clients receive the rendered prompt, effective execution target, numeric
|
|
||||||
target-presence metadata, optional structured-output specification, and direct
|
|
||||||
request API key. `GenerateResponse` returns content and `TokenUsage`.
|
|
||||||
Custom clients should avoid logging raw prompts or credentials.
|
|
||||||
|
|
||||||
## Errors
|
|
||||||
|
|
||||||
Public methods preserve these sentinel checks through `errors.Is`:
|
|
||||||
|
|
||||||
- `ErrInvalidConfig`
|
|
||||||
- `ErrInvalidRequest`
|
|
||||||
- `ErrPromptNotFound`
|
|
||||||
- `ErrProfileNotFound`
|
|
||||||
- `ErrProfileRequired`
|
|
||||||
- `ErrPromptLoad`
|
|
||||||
- `ErrProfileLoad`
|
|
||||||
- `ErrAPIKeyEnvMissing`
|
|
||||||
- `ErrArtifactLoad`
|
|
||||||
- `ErrPromptRender`
|
|
||||||
- `ErrLLMGenerate`
|
|
||||||
- `ErrValidation`
|
|
||||||
|
|
||||||
`ErrProfileRequired` and `ErrAPIKeyEnvMissing` each also match
|
|
||||||
`ErrInvalidRequest`, so callers can select either the broad request category or
|
|
||||||
the specific condition.
|
|
||||||
|
|
||||||
For the HTTP interface, see the [HTTP API reference](../api.md).
|
|
||||||
@@ -1,63 +1,56 @@
|
|||||||
# Development
|
# Development
|
||||||
|
|
||||||
This is the contributor entry point for Scriptorium. Use the task-specific
|
This is the contributor entry point for Scriptorium. Scriptorium is an
|
||||||
reading guide below before making changes. Canonical architecture, contracts,
|
application that consumes the public
|
||||||
component behavior, and policies remain in their owning documents.
|
[Promptkit v0.1.0 package](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md);
|
||||||
|
framework implementation work belongs in Promptkit.
|
||||||
|
|
||||||
## Initial Orientation
|
## Initial Orientation
|
||||||
|
|
||||||
Before starting work:
|
Before starting work:
|
||||||
|
|
||||||
1. inspect the working tree and preserve unrelated changes;
|
1. inspect the working tree and preserve unrelated changes;
|
||||||
2. read the architecture policy for code or design work;
|
2. read the [architecture policy](policy/architecture.md);
|
||||||
3. read the policy, contract, and internal documents listed for the task;
|
3. follow the task-specific contracts and internal documents below; and
|
||||||
4. inspect the relevant implementation and tests before deciding how to change
|
4. inspect the relevant implementation and tests before changing them.
|
||||||
them.
|
|
||||||
|
|
||||||
Start with:
|
Also read the [documentation policy](policy/documentation.md) before changing
|
||||||
|
documentation and the [testing policy](policy/testing.md) before changing
|
||||||
- [Architecture policy](policy/architecture.md) for system boundaries,
|
tests.
|
||||||
invariants, and non-goals;
|
|
||||||
- [Internal component overview](internal/overview.md) for the current package
|
|
||||||
and component map;
|
|
||||||
- [Documentation policy](policy/documentation.md) before changing
|
|
||||||
documentation;
|
|
||||||
- [Testing policy](policy/testing.md) before adding, rewriting, or deleting
|
|
||||||
tests.
|
|
||||||
|
|
||||||
## Task-Specific Reading Guide
|
## Task-Specific Reading Guide
|
||||||
|
|
||||||
| Task | Read before changing |
|
| Task | Read before changing |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Repository orientation or component responsibility | [Internal component overview](internal/overview.md) and [architecture policy](policy/architecture.md) |
|
| Repository orientation or component responsibility | [Internal component overview](internal/overview.md) and [architecture policy](policy/architecture.md) |
|
||||||
| Public Go package or engine behavior | [Go package consumer contract](consumers/pkg-scriptorium.md), [internal component overview](internal/overview.md), [runner internals](internal/runner.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) |
|
| CLI commands, flags, output, or exit behavior | [CLI contract](cli.md) and [adapter internals](internal/adapters.md) |
|
||||||
| CLI commands, flags, output, or exit behavior | [CLI contract](cli.md), [internal component overview](internal/overview.md), and [adapter internals](internal/adapters.md) |
|
| HTTP routes, DTOs, limits, status mapping, or artifact policy | [HTTP API contract](api.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) |
|
||||||
| HTTP routes, DTOs, limits, or status mapping | [HTTP API contract](api.md), [internal component overview](internal/overview.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) |
|
| Application configuration or precedence | [Configuration contract](config.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) |
|
||||||
| Application configuration | [Configuration contract](config.md), [internal component overview](internal/overview.md), [adapter internals](internal/adapters.md), and [source internals](internal/sources.md) |
|
| Prepared-run presentation | [CLI contract](cli.md), [adapter internals](internal/adapters.md), and `internal/format` |
|
||||||
| Prompt, profile, schema, or artifact loading | [Configuration contract](config.md), [internal component overview](internal/overview.md), and [source internals](internal/sources.md) |
|
| Prompt, profile, schema, generation, or validation semantics | [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md) and the [Promptkit consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md) |
|
||||||
| Runner orchestration, rendering, validation, or repair | [Runner internals](internal/runner.md) and [source internals](internal/sources.md) |
|
| OpenAI-compatible outbound behavior or timeout layering | [Promptkit integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md) |
|
||||||
| OpenAI-compatible request or response behavior | [OpenAI-compatible integration](integrations/openai-compatible-chat.md), [LLM internals](internal/llm.md), [runner internals](internal/runner.md), and [adapter internals](internal/adapters.md) |
|
|
||||||
| Subprocess behavior | [Subprocess integration](integrations/subprocess.md) and [CLI contract](cli.md) |
|
| Subprocess behavior | [Subprocess integration](integrations/subprocess.md) and [CLI contract](cli.md) |
|
||||||
| Runtime operation or recovery | [Operations](operations.md) |
|
| Runtime operation or recovery | [Operations](operations.md) |
|
||||||
| Examples or copyable assets | The owning contract for the demonstrated behavior and the related files under `examples/` |
|
| Release packaging | `.woodpecker/release.yml`, [operations](operations.md), and the architecture policy |
|
||||||
| Architecture decisions or future work | The [documentation policy](policy/documentation.md), relevant accepted ADRs such as [ADR 0001](adr/0001-adopt-canonical-documentation-ownership.md), and relevant roadmap documents under `roadmap/` |
|
| Examples or copyable assets | The owning Scriptorium contract, the relevant [Promptkit format contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md), and the related files under `examples/` |
|
||||||
|
| Architecture decisions or future work | The [documentation policy](policy/documentation.md), relevant accepted ADRs, and relevant roadmap documents |
|
||||||
|
|
||||||
For cross-cutting changes, follow every applicable row. Internal component
|
Cross-project changes land and release in Promptkit before Scriptorium adopts
|
||||||
documents own detailed subsystem change recipes.
|
the tagged version. Do not commit a Go workspace, local replacement, vendored
|
||||||
|
Promptkit source, or an import of a Promptkit `internal` package.
|
||||||
|
|
||||||
## Baseline Validation
|
## Baseline Validation
|
||||||
|
|
||||||
Use focused checks while iterating, then run validation proportionate to the
|
For code changes, run:
|
||||||
change and the risks described by the testing policy.
|
|
||||||
|
|
||||||
The repository-level baseline for code changes is:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test ./...
|
go test ./...
|
||||||
|
go test -race ./...
|
||||||
go vet ./...
|
go vet ./...
|
||||||
go build ./cmd/scriptorium
|
go build ./cmd/scriptorium
|
||||||
```
|
```
|
||||||
|
|
||||||
Documentation-only work does not require the full Go suite unless it changes
|
Check formatting with `gofmt`, run `git diff --check`, and validate affected
|
||||||
commands, examples, generated output, or another behavior that the suite
|
examples and documentation links. Documentation-only work does not require
|
||||||
validates. Always check changed links, paths, examples, and canonical ownership.
|
unrelated new tests, but commands and examples changed by documentation must be
|
||||||
|
run.
|
||||||
|
|||||||
@@ -1,121 +0,0 @@
|
|||||||
# OpenAI-Compatible Chat Integration
|
|
||||||
|
|
||||||
This is the outbound wire contract for Scriptorium's OpenAI-compatible
|
|
||||||
chat-completions client.
|
|
||||||
|
|
||||||
## Endpoint And Method
|
|
||||||
|
|
||||||
Scriptorium uses the request endpoint override when present; otherwise it uses
|
|
||||||
the configured client base URL. It removes a trailing slash and sends
|
|
||||||
`POST /chat/completions`.
|
|
||||||
|
|
||||||
For example, `http://localhost:8000/v1` becomes
|
|
||||||
`http://localhost:8000/v1/chat/completions`.
|
|
||||||
|
|
||||||
## Request Payload
|
|
||||||
|
|
||||||
The payload always contains `model` and rendered `messages`. It additionally
|
|
||||||
contains these fields when applicable:
|
|
||||||
|
|
||||||
| Field | Inclusion |
|
|
||||||
| --- | --- |
|
|
||||||
| `session_id` | Non-empty rendered prompt session ID. |
|
|
||||||
| `temperature` | Non-zero effective value or an explicit zero override. |
|
|
||||||
| `max_tokens` | Non-zero effective value or an explicit zero override. |
|
|
||||||
| `top_p` | Non-zero effective value or an explicit zero override. |
|
|
||||||
| `service_tier` | Any non-empty configured value. |
|
|
||||||
| `reasoning_effort` | Any non-empty configured value. |
|
|
||||||
| `response_format` | Structured output is requested. |
|
|
||||||
| provider-specific fields | Flattened from `extra_params`. |
|
|
||||||
|
|
||||||
`service_tier` and `reasoning_effort` are forwarded without a provider value
|
|
||||||
catalog; the selected backend decides which values it supports.
|
|
||||||
|
|
||||||
`extra_params` are top-level JSON fields, not a nested object. Keys cannot be
|
|
||||||
empty or collide with `model`, `session_id`, `messages`, `temperature`,
|
|
||||||
`max_tokens`, `top_p`, `service_tier`, `reasoning_effort`, or
|
|
||||||
`response_format`. Values must be JSON-serializable.
|
|
||||||
|
|
||||||
A rendered `session_id` is sent as a top-level JSON field, not as a header.
|
|
||||||
Empty values are omitted. The maximum length is 256 Unicode code points.
|
|
||||||
|
|
||||||
Messages without cache control use string `content`. A message with cache
|
|
||||||
control uses one text block:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"role": "system",
|
|
||||||
"content": [{
|
|
||||||
"type": "text",
|
|
||||||
"text": "rendered text",
|
|
||||||
"cache_control": {"type": "ephemeral", "ttl": "1h"}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
When the prompt omits cache-control `ttl`, the payload omits `ttl`.
|
|
||||||
Structured JSON Schema output is sent as:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"response_format": {
|
|
||||||
"type": "json_schema",
|
|
||||||
"json_schema": {
|
|
||||||
"name": "schema name",
|
|
||||||
"strict": true,
|
|
||||||
"schema": {"type": "object"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Authentication And Timeout
|
|
||||||
|
|
||||||
When a direct request API key is present, Scriptorium sends
|
|
||||||
`Authorization: Bearer <key>` and does not read `api_key_env`. Otherwise, it
|
|
||||||
resolves the configured non-empty `api_key_env` at request time and sends the
|
|
||||||
same header. If neither mechanism supplies a key, it sends no
|
|
||||||
`Authorization` header.
|
|
||||||
|
|
||||||
The transport-wide safety cap is chosen at client construction. A positive
|
|
||||||
timeout on a supplied `http.Client` takes precedence over a positive
|
|
||||||
`Config.Timeout`; if neither is positive, the internal ten-minute default is
|
|
||||||
used. The supplied client is cloned, and zero or negative timeout values are
|
|
||||||
treated as unset.
|
|
||||||
|
|
||||||
Separately, a positive effective `timeout_seconds` creates a deadline for each
|
|
||||||
outbound generation call. Its value follows the execution-setting hierarchy:
|
|
||||||
an explicit request override, then a non-zero profile value, then the
|
|
||||||
600-second framework default. An explicit request override of zero disables
|
|
||||||
only this generation deadline. Negative values are rejected before a request
|
|
||||||
is sent.
|
|
||||||
|
|
||||||
The complete observable rule is that the earliest caller-context deadline,
|
|
||||||
transport cap, or positive generation deadline terminates the call. Transport
|
|
||||||
and cancellation failures retain the generation-error classification.
|
|
||||||
|
|
||||||
## Response Subset And Failures
|
|
||||||
|
|
||||||
A successful provider response must supply non-empty
|
|
||||||
`choices[0].message.content`. Scriptorium reads these optional or required
|
|
||||||
usage fields when present:
|
|
||||||
|
|
||||||
- `usage.prompt_tokens`
|
|
||||||
- `usage.completion_tokens`
|
|
||||||
- `usage.total_tokens`
|
|
||||||
- `usage.prompt_tokens_details.cached_tokens`
|
|
||||||
- `usage.cache_write_tokens`
|
|
||||||
|
|
||||||
Missing cache usage is reported as zero. Invalid JSON, an empty choices array,
|
|
||||||
or empty first-choice content is a malformed provider response. Network and
|
|
||||||
request-construction failures, non-2xx responses, and malformed responses fail
|
|
||||||
the outbound call. Provider response bodies are not exposed by this client.
|
|
||||||
|
|
||||||
The client does not implement built-in retries, tool calls, top-level
|
|
||||||
`cache_control`, or multi-request payload modes.
|
|
||||||
|
|
||||||
## Related References
|
|
||||||
|
|
||||||
Prompt schema preparation and runner orchestration are described in
|
|
||||||
[runner internals](../internal/runner.md). Prompt and profile configuration is
|
|
||||||
defined by the [configuration reference](../config.md).
|
|
||||||
@@ -2,115 +2,86 @@
|
|||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Adapters translate external inputs into public engine requests and translate
|
Scriptorium adapters translate executable inputs into Promptkit public requests
|
||||||
public results or errors back to their interface. They own IO and presentation
|
and translate Promptkit results or errors back to CLI or HTTP behavior. They
|
||||||
mechanics; use-case decisions remain behind the root `scriptorium` facade.
|
own IO and presentation mechanics, not framework decisions.
|
||||||
|
|
||||||
External contracts are canonical in the [CLI reference](../cli.md), [HTTP API
|
External contracts are canonical in the [CLI reference](../cli.md) and
|
||||||
reference](../api.md), and [Go package contract](../consumers/pkg-scriptorium.md).
|
[HTTP API reference](../api.md). Promptkit's public engine contract is
|
||||||
|
described by its tagged
|
||||||
|
[Go consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md).
|
||||||
|
|
||||||
## Components And Collaborators
|
## Components And Collaborators
|
||||||
|
|
||||||
- `cmd/scriptorium` passes process arguments and streams to
|
- `cmd/scriptorium` passes process arguments and streams to
|
||||||
`internal/adapter/cli`.
|
`internal/adapter/cli`.
|
||||||
- `internal/adapter/cli` parses commands, resolves application settings through
|
- `internal/adapter/cli` resolves settings through `internal/config`,
|
||||||
`internal/config`, constructs the public engine, and owns process output
|
constructs `promptkit.Engine`, maps CLI values to `promptkit.RunRequest`,
|
||||||
handling.
|
and owns output files, summaries, and exit codes.
|
||||||
- `internal/adapter/http` decodes DTOs, maps them to public run requests,
|
- `internal/adapter/http` strictly decodes request DTOs, maps them to Promptkit
|
||||||
calls its local public `Runner` interface, and maps public errors and results
|
public values, calls its adapter-owned `Runner` interface, and maps results
|
||||||
to HTTP DTOs.
|
and errors to HTTP DTOs.
|
||||||
- The root `scriptorium` package maps its public types and options to internal
|
- `internal/format` renders `promptkit.PreparedRun` values as deterministic text
|
||||||
collaborators and maps selected internal errors to public sentinels.
|
or JSON.
|
||||||
- `internal/format` formats public prepared runs for the CLI.
|
|
||||||
|
|
||||||
## Wiring Flows
|
## Wiring Flows
|
||||||
|
|
||||||
### CLI
|
### CLI
|
||||||
|
|
||||||
The CLI resolves configuration before constructing the public engine. `run`
|
`run` calls `promptkit.Engine.Run`; `render` calls
|
||||||
calls `Engine.Run` with a public request and `render` calls `Engine.Prepare`
|
`promptkit.Engine.Prepare`. Both share request mapping for prompt/profile
|
||||||
with the same request mapping. `serve` constructs the HTTP-owned restricted
|
selection, file inputs, variables, and presence-aware execution overrides.
|
||||||
artifact reader, injects it with `WithArtifactReader`, passes the resulting
|
Omitted framework settings remain zero values so Promptkit resolves its own
|
||||||
engine directly to the HTTP handler, and starts the server.
|
defaults.
|
||||||
|
|
||||||
Parser state records whether numeric runtime values were explicitly supplied.
|
`serve` constructs Scriptorium's restricted HTTP artifact reader, injects it
|
||||||
That presence is carried into `scriptorium.ExecutionTargetOverride`, allowing
|
with `promptkit.WithArtifactReader`, passes the engine through the HTTP
|
||||||
the engine to distinguish omitted values from explicit zero overrides.
|
adapter's consumer-owned `Runner` interface, and starts the server.
|
||||||
|
|
||||||
### HTTP
|
### HTTP
|
||||||
|
|
||||||
The handler first enforces transport limits, strict JSON decoding, and the
|
The handler enforces transport limits and strict JSON decoding before mapping
|
||||||
minimal request shape. It maps DTO values to public types without deciding
|
DTOs into `promptkit.RunRequest`, `promptkit.ArtifactRef`, and
|
||||||
prompt selection, source behavior, or validation semantics. On success it maps
|
`promptkit.ExecutionTargetOverride`. On success it reads Promptkit artifact,
|
||||||
the public result to the response DTO; on failure it uses `errors.Is` over
|
validation, model, usage, and metadata values directly.
|
||||||
public framework errors and HTTP-local artifact-policy errors to choose the
|
|
||||||
public error mapping.
|
|
||||||
|
|
||||||
The [HTTP API reference](../api.md) owns the route, DTO schema, status codes,
|
Failure mapping uses `errors.Is` against Promptkit's public sentinels and the
|
||||||
and externally observable limit behavior.
|
HTTP reader's Scriptorium-owned containment and size errors. Wrapped reader
|
||||||
|
errors preserve their identity through Promptkit's artifact-load boundary.
|
||||||
### Public Go Facade
|
|
||||||
|
|
||||||
`NewEngine` applies public options, selects filesystem, `fs.FS`, single-file,
|
|
||||||
or in-memory dependencies, and constructs a runner. The conversion functions
|
|
||||||
copy maps and slices across the boundary so callers do not receive internal
|
|
||||||
domain values. The facade maps selected internal errors to the public sentinel
|
|
||||||
set and keeps direct request API keys out of public results.
|
|
||||||
|
|
||||||
## Package-Local Guarantees
|
## Package-Local Guarantees
|
||||||
|
|
||||||
- Adapters do not embed framework orchestration or source-loading decisions.
|
- Adapters contain no copied framework types or orchestration.
|
||||||
- Configuration is resolved before adapter dependency composition.
|
- Configuration is resolved before Promptkit engine construction.
|
||||||
- CLI and HTTP consume the public engine without a repairer; a repairer remains
|
- Explicit numeric overrides preserve presence, including zero.
|
||||||
available only through explicit internal runner construction.
|
- HTTP DTO and error mapping remains stable and transport-owned.
|
||||||
- DTO conversion preserves explicit numeric-override presence.
|
- Resolved secrets are not serialized or printed.
|
||||||
- Error mapping matches error identities, not error text.
|
- No adapter creates durable run state.
|
||||||
- No adapter creates durable run state; caller-selected output files are not
|
|
||||||
application state.
|
|
||||||
|
|
||||||
## Failure And Verification Boundaries
|
## Verification
|
||||||
|
|
||||||
Keep external error payloads concise, preserve strict external decoding, and do
|
Inspect:
|
||||||
not serialize resolved secret values. Validation content failures remain result
|
|
||||||
state; runtime failures remain errors for the relevant adapter to map.
|
|
||||||
|
|
||||||
Inspect focused tests when changing this area:
|
|
||||||
|
|
||||||
- `internal/adapter/cli/run_test.go`
|
- `internal/adapter/cli/run_test.go`
|
||||||
- `internal/adapter/http/handler_test.go`
|
- `internal/adapter/http/handler_test.go`
|
||||||
- `engine_test.go`
|
- `internal/adapter/http/artifact_reader_test.go`
|
||||||
- `internal/format/prepared_run_test.go`
|
- `internal/format/prepared_run_test.go`
|
||||||
|
- `internal/adapter/dependency_test.go`
|
||||||
|
|
||||||
Run the affected adapter package tests and recheck the relevant canonical
|
The adapter tests protect parsing, configuration mapping, output, status
|
||||||
contract. The [testing policy](../policy/testing.md) owns global test
|
mapping, restricted artifacts, and representative real Promptkit-engine
|
||||||
sufficiency guidance.
|
workflows. The dependency test protects the repository boundary.
|
||||||
|
|
||||||
## Change Recipes
|
## Change Recipes
|
||||||
|
|
||||||
### Application Configuration Fields
|
For a CLI or HTTP change:
|
||||||
|
|
||||||
1. Add the field to the relevant `internal/config` shape and default handling.
|
1. identify the Scriptorium-owned external contract;
|
||||||
2. Parse and validate it, then preserve configuration and CLI-override
|
2. map through Promptkit public values without copying framework semantics;
|
||||||
precedence while wiring it through its consuming adapter.
|
3. add or update the narrow application-owned test;
|
||||||
3. Add focused configuration and adapter tests for parsing, mapping, and
|
4. update the canonical Scriptorium contract; and
|
||||||
effective behavior.
|
5. coordinate and tag Promptkit first if a required public capability is
|
||||||
4. Update the [configuration contract](../config.md) and any affected external
|
genuinely absent.
|
||||||
contract.
|
|
||||||
|
|
||||||
### CLI Flags
|
Update [source internals](sources.md) when application source locations or HTTP
|
||||||
|
artifact containment changes.
|
||||||
1. Add the flag to the relevant parser in `internal/adapter/cli/run.go`.
|
|
||||||
2. Keep command scope and application-configuration precedence intentional.
|
|
||||||
3. Add or update parser and command tests in
|
|
||||||
`internal/adapter/cli/run_test.go`.
|
|
||||||
4. Update the [CLI contract](../cli.md) and affected maintained examples.
|
|
||||||
|
|
||||||
### Adapter Capabilities
|
|
||||||
|
|
||||||
1. Define or reuse an adapter-local consumer interface with public facade
|
|
||||||
types when a test seam is needed.
|
|
||||||
2. Implement translation and IO behavior without moving framework decisions out
|
|
||||||
of the public engine.
|
|
||||||
3. Add focused mapping, parsing, and error-behavior tests.
|
|
||||||
4. Update this document and the affected public or integration contract. Update
|
|
||||||
[source internals](sources.md) when source-loading behavior changes.
|
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
# LLM Internals
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
`internal/llm` defines the provider-neutral `Client` interface and the
|
|
||||||
OpenAI-compatible client implementation. The [OpenAI-compatible integration
|
|
||||||
contract](../integrations/openai-compatible-chat.md) owns the outbound HTTP wire
|
|
||||||
format and protocol behavior.
|
|
||||||
|
|
||||||
## Construction
|
|
||||||
|
|
||||||
`NewOpenAICompatibleClient` validates a non-empty configured base URL, records
|
|
||||||
an optional default model, and resolves one transport cap. A supplied client
|
|
||||||
with a positive timeout supplies that cap; otherwise a positive configured
|
|
||||||
timeout is used, then the internal default.
|
|
||||||
|
|
||||||
When callers supply an `http.Client`, construction clones it rather than
|
|
||||||
mutating the caller's instance. A supplied client with a zero or negative
|
|
||||||
timeout receives the resolved transport cap in the clone. The client stores the
|
|
||||||
trimmed base URL, default model, and cloned client.
|
|
||||||
|
|
||||||
## Generate Flow
|
|
||||||
|
|
||||||
`Generate` receives a `domain.GenerateRequest` from the runner:
|
|
||||||
|
|
||||||
1. validate the effective timeout and choose the request endpoint;
|
|
||||||
2. map the domain request to the internal wire-request representation;
|
|
||||||
3. validate and flatten extra parameters and encode JSON;
|
|
||||||
4. derive a child context when the effective generation timeout is positive,
|
|
||||||
then create the HTTP request with that context;
|
|
||||||
5. prefer a direct API key, otherwise resolve the configured key environment
|
|
||||||
variable;
|
|
||||||
6. execute with the construction-time HTTP client, reject non-success status
|
|
||||||
responses without returning
|
|
||||||
provider response bodies; and
|
|
||||||
7. decode the response subset into `domain.GenerateResponse`.
|
|
||||||
|
|
||||||
`openAIChatRequestFromGenerateRequest` is the conversion boundary for effective
|
|
||||||
model defaults, explicit numeric-presence state, rendered messages, structured
|
|
||||||
output, and session-ID validation. `openAIChatRequestPayload` protects reserved
|
|
||||||
fields and JSON encoding before an HTTP call. The external payload shape is
|
|
||||||
defined only in the [integration contract](../integrations/openai-compatible-chat.md).
|
|
||||||
|
|
||||||
## Error Categories
|
|
||||||
|
|
||||||
The package uses these internal sentinels:
|
|
||||||
|
|
||||||
- `ErrInvalidConfig` for invalid client construction;
|
|
||||||
- `ErrInvalidRequest` for invalid effective generation input;
|
|
||||||
- `ErrRequestFailed` for request construction or transport failures;
|
|
||||||
- `ErrUnexpectedStatus` for non-success HTTP responses; and
|
|
||||||
- `ErrMalformedResponse` for invalid or incomplete successful-response data.
|
|
||||||
|
|
||||||
The runner maps an invalid LLM request to its invalid-request category and
|
|
||||||
other LLM failures to its generation category. Adapters then apply their public
|
|
||||||
error contracts.
|
|
||||||
|
|
||||||
## Package-Local Guarantees
|
|
||||||
|
|
||||||
- The default-model fallback happens before wire encoding.
|
|
||||||
- Per-generation timeout handling derives a request context; it never replaces
|
|
||||||
or mutates the configured HTTP client's transport cap.
|
|
||||||
- Direct API keys take precedence over environment lookup within this client.
|
|
||||||
- Provider response bodies are discarded for non-success status responses.
|
|
||||||
- The client does not implement retries, tool calls, or a stateful session
|
|
||||||
store.
|
|
||||||
|
|
||||||
## Verification And Change Recipe
|
|
||||||
|
|
||||||
Inspect:
|
|
||||||
|
|
||||||
- `internal/llm/openai_compatible_client_test.go`
|
|
||||||
- `internal/usecase/runner_test.go`
|
|
||||||
- `internal/adapter/http/handler_test.go`
|
|
||||||
|
|
||||||
When changing the client:
|
|
||||||
|
|
||||||
1. keep domain-to-wire mapping inside `internal/llm` and preserve the `Client`
|
|
||||||
interface;
|
|
||||||
2. test construction, timeout selection, mapping, and error categorization;
|
|
||||||
3. update the [OpenAI-compatible integration contract](../integrations/openai-compatible-chat.md)
|
|
||||||
for any observable wire or protocol change; and
|
|
||||||
4. update [runner internals](runner.md) if the client boundary or structured
|
|
||||||
output handoff changes.
|
|
||||||
|
|
||||||
The [testing policy](../policy/testing.md) owns global test sufficiency.
|
|
||||||
@@ -1,48 +1,18 @@
|
|||||||
# Internal Component Overview
|
# Internal Component Overview
|
||||||
|
|
||||||
## Purpose
|
This is the complete inventory of Scriptorium's implemented Go components.
|
||||||
|
The [architecture policy](../policy/architecture.md) owns normative boundaries;
|
||||||
This is the inventory of Scriptorium's implemented components for contributors.
|
public behavior belongs in the linked contracts.
|
||||||
The [architecture policy](../policy/architecture.md) owns normative boundaries
|
|
||||||
and invariants; public behavior belongs in the linked contracts.
|
|
||||||
|
|
||||||
## Public And Command Entrypoints
|
|
||||||
|
|
||||||
| Component | Implemented responsibility | References |
|
| Component | Implemented responsibility | References |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Root package `scriptorium` | Public Go facade that constructs the engine, exposes request/result types and options, and maps internal errors. | [Go package contract](../consumers/pkg-scriptorium.md), [adapter internals](adapters.md) |
|
| `cmd/scriptorium` | Process entrypoint that delegates arguments and streams to the CLI adapter. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
||||||
| `cmd/scriptorium` | Process entrypoint that delegates command execution to the CLI adapter. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
| `internal/adapter/cli` | Parses commands, resolves application settings, constructs Promptkit engines, maps requests, and owns process output and exit behavior. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
||||||
|
| `internal/adapter/http` | Owns routes, DTOs, strict decoding, limits, Promptkit request/result mapping, public error mapping, and restricted HTTP artifact reading. | [HTTP API](../api.md), [adapter internals](adapters.md), [source internals](sources.md) |
|
||||||
|
| `internal/config` | Discovers and strictly decodes application configuration and applies built-in and CLI precedence. | [configuration contract](../config.md), [adapter internals](adapters.md) |
|
||||||
|
| `internal/defaults` | Holds Scriptorium-owned application and HTTP defaults. | [configuration contract](../config.md) |
|
||||||
|
| `internal/format` | Formats Promptkit prepared-run values for CLI text or JSON output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
||||||
|
|
||||||
## Adapters, Domain, And Use Case
|
Framework implementation packages are provided by
|
||||||
|
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md)
|
||||||
| Component | Implemented responsibility | References |
|
and are not part of this repository.
|
||||||
| --- | --- | --- |
|
|
||||||
| `internal/adapter/cli` | Parses CLI commands, constructs the public engine from application settings, and handles process input and output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
|
||||||
| `internal/adapter/http` | Maps HTTP requests and responses through public engine values, maps public errors, and owns restricted HTTP artifact policy. | [HTTP API contract](../api.md), [adapter internals](adapters.md) |
|
|
||||||
| `internal/domain` | Defines core request, result, output-contract, and LLM-boundary types. | [runner internals](runner.md) |
|
|
||||||
| `internal/usecase` | Implements `Runner` preparation, execution, validation coordination, and the repairer boundary. | [runner internals](runner.md) |
|
|
||||||
|
|
||||||
## Configuration And Sources
|
|
||||||
|
|
||||||
| Component | Implemented responsibility | References |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `internal/config` | Loads application settings, applies defaults, and applies CLI overrides. | [configuration contract](../config.md), [adapter internals](adapters.md) |
|
|
||||||
| `internal/defaults` | Holds compile-time default values used when application settings are resolved. | [configuration contract](../config.md) |
|
|
||||||
| `internal/promptdef` | Loads prompt definitions from filesystem and `fs.FS` sources. | [configuration contract](../config.md), [source internals](sources.md) |
|
|
||||||
| `internal/profile` | Loads filesystem and `fs.FS` execution profiles and combines profile repositories. | [configuration contract](../config.md), [source internals](sources.md) |
|
|
||||||
| `internal/profile/builtin` | Provides embedded built-in execution profiles as a repository. | [configuration contract](../config.md), [source internals](sources.md) |
|
|
||||||
| `internal/filecatalog` | Provides shared YAML discovery and source-root helpers. | [source internals](sources.md) |
|
|
||||||
| `internal/artifact` | Provides the framework's ordinary inline and unrestricted file artifact reader. | [configuration contract](../config.md), [source internals](sources.md) |
|
|
||||||
| `internal/prompt` | Renders prompt templates into messages. | [runner internals](runner.md) |
|
|
||||||
|
|
||||||
## Formatting, Validation, And Model Access
|
|
||||||
|
|
||||||
| Component | Implemented responsibility | References |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `internal/format` | Formats public prepared-run information for CLI output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
|
||||||
| `internal/validate` | Defines validation interfaces and provides standard filesystem and `fs.FS` schema validation. | [configuration contract](../config.md), [source internals](sources.md), [runner internals](runner.md) |
|
|
||||||
| `internal/llm` | Defines the provider-neutral LLM client boundary and its OpenAI-compatible implementation. | [OpenAI-compatible integration](../integrations/openai-compatible-chat.md), [LLM internals](llm.md), [runner internals](runner.md) |
|
|
||||||
|
|
||||||
Focused internal documents describe the components that have detailed
|
|
||||||
orchestration, adapter, or source behavior. Package tests live alongside the
|
|
||||||
implementation and are identified in those focused documents where relevant.
|
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
# Runner Internals
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
`internal/usecase.Runner` is the prompt-execution orchestrator. It prepares
|
|
||||||
domain requests, invokes an injected LLM client, validates output, and returns
|
|
||||||
domain results. Transport parsing, response mapping, and public type conversion
|
|
||||||
remain outside this package.
|
|
||||||
|
|
||||||
The [configuration reference](../config.md) owns prompt, profile, schema, and
|
|
||||||
runtime-setting definitions. Public error behavior is defined by the
|
|
||||||
[HTTP API](../api.md) and [Go package](../consumers/pkg-scriptorium.md)
|
|
||||||
contracts.
|
|
||||||
|
|
||||||
## Dependencies And Construction
|
|
||||||
|
|
||||||
`Runner` receives these collaborators:
|
|
||||||
|
|
||||||
- `promptdef.Repository`;
|
|
||||||
- `profile.Repository`;
|
|
||||||
- `artifact.Reader`;
|
|
||||||
- `prompt.Renderer`;
|
|
||||||
- `llm.Client`;
|
|
||||||
- `validate.Validator`; and
|
|
||||||
- an optional `OutputRepairer`.
|
|
||||||
|
|
||||||
`NewRunner` constructs a runner without a repairer. `NewRunnerWithRepairer`
|
|
||||||
accepts one explicitly. The public engine chooses concrete repositories and
|
|
||||||
readers; executable adapters reach the runner only through that engine. The
|
|
||||||
runner does not load application configuration.
|
|
||||||
|
|
||||||
## Prepare Flow
|
|
||||||
|
|
||||||
`Prepare` performs one deterministic preparation pass for a request:
|
|
||||||
|
|
||||||
1. validate the prompt ID and load the prompt definition;
|
|
||||||
2. hash the definition and select the explicit or default profile;
|
|
||||||
3. load the profile and resolve effective execution settings;
|
|
||||||
4. validate endpoint, model, and credential availability;
|
|
||||||
5. resolve the output contract and, for JSON Schema output, load a structured
|
|
||||||
schema document before model execution;
|
|
||||||
6. read and hash input artifacts;
|
|
||||||
7. render messages and the session ID; and
|
|
||||||
8. return a `PreparedRun` containing the effective state and rendered-prompt
|
|
||||||
hash.
|
|
||||||
|
|
||||||
Execution settings merge defaults, profile values, and a request override.
|
|
||||||
Numeric override presence is retained so explicit zero values are not confused
|
|
||||||
with omissions.
|
|
||||||
|
|
||||||
## Run And Validation Flow
|
|
||||||
|
|
||||||
`Run` creates a run ID and timestamps, then calls `Prepare` rather than
|
|
||||||
duplicating preparation. It sends the prepared prompt, effective target,
|
|
||||||
target-presence state, and optional structured-output specification to the LLM
|
|
||||||
client. It converts the returned content to an output artifact, validates it,
|
|
||||||
and returns the artifact, validation, hashes, usage, and timing metadata.
|
|
||||||
|
|
||||||
A validator can return a content result or an operational error. Content
|
|
||||||
failures stay in the result; schema loading, compilation, and validator
|
|
||||||
operational failures are returned as `ErrValidation`. The canonical distinction
|
|
||||||
for callers is documented by the public contracts.
|
|
||||||
|
|
||||||
## Repair Boundary
|
|
||||||
|
|
||||||
Repair is an internal optional loop. It starts only when a repairer is present,
|
|
||||||
the output contract permits one or more attempts, validation failed, and the
|
|
||||||
validation mode is JSON or JSON Schema. Each repair receives the previous
|
|
||||||
output, validation errors, effective target, structured-output specification,
|
|
||||||
and attempt metadata; every repaired result is validated again.
|
|
||||||
|
|
||||||
`NewDefaultOutputRepairer` delegates to the injected LLM client. The public
|
|
||||||
engine, and therefore CLI and HTTP, uses `NewRunner` and does not inject this
|
|
||||||
repairer.
|
|
||||||
|
|
||||||
## Error Translation
|
|
||||||
|
|
||||||
Runner sentinels identify failure categories for adapters:
|
|
||||||
|
|
||||||
- `ErrInvalidRequest`
|
|
||||||
- `ErrProfileRequired`
|
|
||||||
- `ErrAPIKeyEnvMissing` and `ErrAPIKeyRequired`
|
|
||||||
- `ErrPromptLoad`, `ErrProfileLoad`, and `ErrArtifactLoad`
|
|
||||||
- `ErrPromptRender`
|
|
||||||
- `ErrLLMGenerate`
|
|
||||||
- `ErrValidation`
|
|
||||||
|
|
||||||
Wrap errors with those sentinels and preserve their identities through
|
|
||||||
`errors.Is`; adapters must not classify errors by message text. The runner
|
|
||||||
passes direct keys only to the LLM boundary and never includes resolved key
|
|
||||||
values in prepared or run results.
|
|
||||||
|
|
||||||
## Package-Local Guarantees
|
|
||||||
|
|
||||||
- `Run` always reuses `Prepare`.
|
|
||||||
- Schema documents are loaded before the initial LLM call when structured output
|
|
||||||
is required.
|
|
||||||
- Output validation records attempts used, including repair attempts.
|
|
||||||
- Runner state is per request; the package does not create a durable run store
|
|
||||||
or manifest.
|
|
||||||
- Source, renderer, validator, and LLM implementations remain injected
|
|
||||||
boundaries.
|
|
||||||
|
|
||||||
## Verification And Change Recipe
|
|
||||||
|
|
||||||
Inspect:
|
|
||||||
|
|
||||||
- `internal/usecase/runner_test.go`
|
|
||||||
- `engine_test.go`
|
|
||||||
|
|
||||||
When changing orchestration:
|
|
||||||
|
|
||||||
1. identify the collaborator boundary and the affected `Prepare` or `Run` state;
|
|
||||||
2. preserve the `Run`-through-`Prepare` path and error identity;
|
|
||||||
3. add focused runner or integration tests for changed state transitions,
|
|
||||||
validation, or repair behavior; and
|
|
||||||
4. update the owning external contract and any affected source or LLM internal
|
|
||||||
document.
|
|
||||||
|
|
||||||
The [testing policy](../policy/testing.md) owns global test sufficiency.
|
|
||||||
@@ -2,98 +2,67 @@
|
|||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
This document describes how source packages load prompt definitions, profiles,
|
This document covers Scriptorium-owned source locations and the restricted HTTP
|
||||||
schemas, and artifacts. The [configuration reference](../config.md) owns their
|
artifact reader. Prompt, profile, schema, and ordinary artifact semantics are
|
||||||
user-facing formats and settings. The [HTTP API reference](../api.md) owns
|
owned by the tagged
|
||||||
HTTP-visible artifact outcomes; [operations](../operations.md) owns deployment
|
[Promptkit format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md).
|
||||||
handling.
|
|
||||||
|
|
||||||
## Prompt Definitions
|
## Application Source Locations
|
||||||
|
|
||||||
`internal/promptdef` provides filesystem and `fs.FS` repositories. Both use
|
`internal/config` resolves `prompt_dir`, `profile_dir`, and `schema_dir` from
|
||||||
`internal/filecatalog` for recursive YAML discovery, deterministic ordering,
|
Scriptorium defaults, configuration files, and CLI overrides.
|
||||||
display paths, and root cleaning.
|
`internal/adapter/cli` passes those paths into `promptkit.Config` when
|
||||||
|
constructing the engine.
|
||||||
|
|
||||||
Repositories select a prompt by YAML ID and optional version rather than by
|
Scriptorium does not search, parse, validate, or overlay framework source files
|
||||||
path. They decode through strict YAML handling, reject duplicate matching
|
itself. Promptkit owns prompt selection, profile built-ins and overlays, schema
|
||||||
definitions, and resolve `content_file` relative to the definition. The `fs.FS`
|
resolution, ordinary file artifacts, and the related error identities.
|
||||||
implementation resolves content paths inside its source root; absolute paths and
|
|
||||||
traversal outside that root are rejected before file access.
|
|
||||||
|
|
||||||
## Profiles And Built-Ins
|
The [configuration reference](../config.md) owns Scriptorium's source-location
|
||||||
|
fields and precedence. Maintained files under `examples/` are application
|
||||||
|
inputs that use Promptkit's tagged formats.
|
||||||
|
|
||||||
`internal/profile` provides filesystem, `fs.FS`, and overlay repositories.
|
## Restricted HTTP Artifact Reader
|
||||||
`internal/profile/builtin` exposes embedded assets through the same repository
|
|
||||||
interface.
|
|
||||||
|
|
||||||
An overlay asks its primary source first. It falls back only when the primary
|
`internal/adapter/http` implements `promptkit.ArtifactReader` for HTTP
|
||||||
reports `ErrProfileNotFound`; invalid YAML, duplicate IDs, validation failures,
|
requests. The `serve` path injects it with
|
||||||
and raw-key failures are returned rather than hidden by fallback. This makes a
|
`promptkit.WithArtifactReader`, replacing Promptkit's ordinary reader for
|
||||||
custom ID override a built-in ID while retaining errors in the custom source.
|
inbound HTTP inputs.
|
||||||
|
|
||||||
The public engine can overlay in-memory profiles ahead of both file-backed and
|
The reader:
|
||||||
built-in repositories. Profile field definitions, validation ranges, and the
|
|
||||||
built-in catalog remain in the [configuration reference](../config.md).
|
|
||||||
|
|
||||||
## Schemas
|
- accepts inline references without an artifact root;
|
||||||
|
- denies file references when no root is configured;
|
||||||
|
- resolves relative paths below the configured root;
|
||||||
|
- accepts absolute paths only when they are lexically within that root;
|
||||||
|
- rejects lexical traversal outside the root;
|
||||||
|
- applies the configured file byte limit, with zero meaning unlimited;
|
||||||
|
- preserves content type, body, size, hash, name, and URI metadata; and
|
||||||
|
- honors context cancellation.
|
||||||
|
|
||||||
`internal/validate` supplies `StandardValidator` for filesystem sources and
|
Containment is lexical and does not resolve symlinks. The operating system
|
||||||
`FSValidator` for `fs.FS` sources. Directory-backed validation loads the named
|
follows symlinks after the check. The [HTTP API](../api.md) owns observable
|
||||||
schema path; it does not search directories by basename. `fs.FS` schema paths
|
request outcomes, and [operations](../operations.md) owns safe deployment
|
||||||
are cleaned and checked against their configured root, while a single-file
|
permissions and root selection.
|
||||||
source matches its file base name.
|
|
||||||
|
|
||||||
The runner requests a schema document before generation when it needs
|
Reader errors remain identifiable after Promptkit wraps them as artifact-load
|
||||||
structured output. JSON and schema mismatches in generated content are
|
failures, allowing the HTTP adapter to preserve Scriptorium status and error
|
||||||
validation results; source access, decoding, registration, and compilation
|
codes.
|
||||||
failures are operational errors.
|
|
||||||
|
|
||||||
## Artifacts
|
|
||||||
|
|
||||||
`internal/artifact` owns the framework's ordinary inline and unrestricted file
|
|
||||||
reader. The public engine uses it by default and permits consumers to replace it
|
|
||||||
for every input through the public `ArtifactReader` extension. The
|
|
||||||
HTTP adapter owns its restricted reader for HTTP containment: `serve` injects
|
|
||||||
that reader into the public engine with `WithArtifactReader`.
|
|
||||||
|
|
||||||
The rooted reader cleans paths and applies lexical containment without resolving
|
|
||||||
symlinks. It checks relative references against the configured root and accepts
|
|
||||||
absolute references only when they remain inside that lexical root. The OS still
|
|
||||||
follows symlinks after that check. The public containment outcome is documented
|
|
||||||
by the [HTTP API reference](../api.md); deployment permissions belong in
|
|
||||||
[operations](../operations.md).
|
|
||||||
|
|
||||||
## Failure Boundaries
|
|
||||||
|
|
||||||
Source packages report repository, decoding, duplicate, validation, and read
|
|
||||||
failures to their callers. They do not select public status codes or response
|
|
||||||
schemas. The runner categorizes source failures and the public engine preserves
|
|
||||||
the corresponding public error identities; adapters map those identities to
|
|
||||||
their own external contract.
|
|
||||||
|
|
||||||
Source reads use current filesystem or `fs.FS` content for each request. These
|
|
||||||
packages create no manifests, checkpoints, or durable run state.
|
|
||||||
|
|
||||||
## Verification And Change Recipe
|
## Verification And Change Recipe
|
||||||
|
|
||||||
Inspect:
|
Inspect:
|
||||||
|
|
||||||
- `internal/promptdef/repository_test.go`
|
- `internal/config/config_test.go`
|
||||||
- `internal/profile/repository_test.go`
|
- `internal/adapter/cli/run_test.go`
|
||||||
- `internal/profile/builtin/repository_test.go`
|
|
||||||
- `internal/artifact/reader_test.go`
|
|
||||||
- `internal/adapter/http/artifact_reader_test.go`
|
- `internal/adapter/http/artifact_reader_test.go`
|
||||||
- `internal/validate/standard_validator_test.go`
|
- `internal/adapter/http/handler_test.go`
|
||||||
- `engine_test.go`
|
|
||||||
|
|
||||||
When updating prompt, profile, schema, or built-in assets:
|
When changing an application source location or HTTP artifact policy:
|
||||||
|
|
||||||
1. keep assets valid for the strict loader and the relevant source boundary;
|
1. preserve strict configuration precedence and the Promptkit public boundary;
|
||||||
2. update the [configuration reference](../config.md) when a file-format,
|
2. keep containment and size policy in Scriptorium;
|
||||||
catalog, or default changes;
|
3. update focused configuration, reader, and handler tests;
|
||||||
3. run focused source and integration tests, including the built-in repository
|
4. update the [configuration](../config.md), [HTTP](../api.md), and
|
||||||
test when embedded assets change; and
|
[operations](../operations.md) contracts as applicable; and
|
||||||
4. update this document when discovery, precedence, containment, or failure
|
5. do not duplicate Promptkit loaders, formats, or ordinary artifact behavior.
|
||||||
mechanics change.
|
|
||||||
|
|
||||||
The [testing policy](../policy/testing.md) owns global test sufficiency.
|
|
||||||
|
|||||||
@@ -7,8 +7,11 @@ recovery for Scriptorium. It does not redefine invocation syntax, configuration
|
|||||||
fields, or HTTP wire behavior.
|
fields, or HTTP wire behavior.
|
||||||
|
|
||||||
- [CLI reference](cli.md): commands, output destinations, and exit codes.
|
- [CLI reference](cli.md): commands, output destinations, and exit codes.
|
||||||
- [Configuration reference](config.md): configuration, prompt/profile/schema
|
- [Configuration reference](config.md): application settings, source
|
||||||
formats, defaults, and credentials.
|
locations, defaults, and credential mapping.
|
||||||
|
- [Promptkit framework formats](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md):
|
||||||
|
prompt, profile, schema, execution-setting, and framework credential
|
||||||
|
contracts.
|
||||||
- [HTTP API reference](api.md): route, request/response schema, status codes,
|
- [HTTP API reference](api.md): route, request/response schema, status codes,
|
||||||
limits, and HTTP artifact access.
|
limits, and HTTP artifact access.
|
||||||
- [Consumer integration overview](consumers/api.md): caller responsibilities.
|
- [Consumer integration overview](consumers/api.md): caller responsibilities.
|
||||||
@@ -26,10 +29,10 @@ responsibilities.
|
|||||||
|
|
||||||
## Deploy The Filesystem And Process
|
## Deploy The Filesystem And Process
|
||||||
|
|
||||||
Provide the process with readable prompt, profile, and schema sources. Keep
|
Provide the process with readable configured Promptkit prompt, profile, and
|
||||||
prompt templates adjacent to the prompt definitions that reference them. For an
|
schema sources that follow the tagged framework formats. For an HTTP deployment
|
||||||
HTTP deployment that accepts file artifacts, use a dedicated, narrow artifact
|
that accepts file artifacts, use a dedicated, narrow artifact directory rather
|
||||||
directory rather than a general-purpose or sensitive filesystem tree.
|
than a general-purpose or sensitive filesystem tree.
|
||||||
|
|
||||||
Run Scriptorium under an identity that can:
|
Run Scriptorium under an identity that can:
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +1,102 @@
|
|||||||
# Architecture
|
# Architecture
|
||||||
|
|
||||||
This document is the development architecture policy for Scriptorium.
|
This document defines Scriptorium's current application architecture and
|
||||||
|
durable development boundaries.
|
||||||
It is for developers and LLM coding agents. User-facing behavior belongs in `README.md` and the docs under `docs/` that target operators/users.
|
|
||||||
|
|
||||||
## System Shape
|
## System Shape
|
||||||
|
|
||||||
Scriptorium is a narrow prompt-execution application with three executable
|
Scriptorium is an executable application with three entry paths: CLI `run`, CLI
|
||||||
entry paths: CLI `run`, CLI `render`, and the HTTP service started by `serve`.
|
`render`, and the HTTP service started by `serve`. It does not expose a reusable
|
||||||
It also provides a public Go package for in-process use. Executable adapters
|
root Go package.
|
||||||
consume framework behavior through that public facade; the facade continues to
|
|
||||||
compose the framework implementation inside this single repository. Its current
|
|
||||||
component inventory is maintained in the [internal overview](../internal/overview.md).
|
|
||||||
|
|
||||||
Domain behavior is centralized in `internal/usecase` and `internal/domain`.
|
The application consumes
|
||||||
|
[Promptkit v0.1.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/consumers/pkg-promptkit.md)
|
||||||
|
through its supported root package. Promptkit owns prompt execution,
|
||||||
|
preparation, source formats, built-in profiles, model-client behavior, and
|
||||||
|
validation. Scriptorium owns application configuration, executable adapters,
|
||||||
|
prepared-run presentation, process behavior, and HTTP deployment policy.
|
||||||
|
|
||||||
## Core Principles
|
The concrete package inventory is maintained in the
|
||||||
|
[internal overview](../internal/overview.md).
|
||||||
- Keep orchestration narrow: Scriptorium executes one prompt request; it is not a multi-step workflow engine.
|
|
||||||
- Keep adapter logic thin: adapters map external shapes to public engine
|
|
||||||
requests/results and should not hold framework decisions.
|
|
||||||
- Keep boundaries explicit: repositories/loaders/renderers/validators/LLM client stay behind package interfaces.
|
|
||||||
- Keep external decoding strict: configuration, prompt, and profile YAML and
|
|
||||||
HTTP JSON should reject unknown fields.
|
|
||||||
- Keep secrets out of payloads: raw API key values must not be accepted or emitted.
|
|
||||||
|
|
||||||
## Dependency Direction
|
## Dependency Direction
|
||||||
|
|
||||||
- Adapters translate external shapes and IO concerns; they do not make
|
```text
|
||||||
use-case decisions.
|
cmd/scriptorium
|
||||||
- Executable adapters and prepared-run formatting use the public facade for
|
|
|
||||||
framework behavior rather than importing framework implementation packages
|
v
|
||||||
directly.
|
CLI and HTTP adapters, configuration, defaults, and formatting
|
||||||
- Use-case and domain code depend on explicit repository, renderer, validator,
|
|
|
||||||
and LLM interfaces rather than adapter implementations.
|
v
|
||||||
- Source, rendering, validation, and LLM implementations remain behind their
|
gitea.maximumdirect.net/eric/promptkit
|
||||||
package boundaries.
|
```
|
||||||
- Dependency-specific types must not leak across unrelated package boundaries.
|
|
||||||
- Prefer the standard library; add an external dependency only when it
|
|
||||||
materially reduces risk or complexity.
|
|
||||||
|
|
||||||
## State And Persistence Policy
|
- Retained application packages may import Promptkit's root package.
|
||||||
|
- They must not import Promptkit `internal` packages.
|
||||||
|
- They must not import the removed Scriptorium root facade or recreate former
|
||||||
|
framework package families.
|
||||||
|
- Adapter-owned interfaces use Promptkit public values when a consumer-side
|
||||||
|
substitution boundary is needed.
|
||||||
|
- Scriptorium passes omitted framework settings as zero values so Promptkit
|
||||||
|
applies its own defaults.
|
||||||
|
|
||||||
Scriptorium has no durable run-state store.
|
The repository architecture guard enforces these import and removal
|
||||||
|
invariants.
|
||||||
|
|
||||||
- No built-in resume/checkpoint/archive behavior.
|
## Retained Boundaries
|
||||||
- Recovery model is rerun after correcting inputs/config/environment.
|
|
||||||
|
|
||||||
## Contract Ownership
|
- `internal/adapter/cli` owns commands, flags, configuration precedence,
|
||||||
|
process streams, output files, summaries, and exit codes.
|
||||||
|
- `internal/adapter/http` owns routes, strict JSON DTOs, size limits, response
|
||||||
|
mapping, status mapping, and the restricted artifact reader.
|
||||||
|
- `internal/config` owns discovery and strict decoding of Scriptorium
|
||||||
|
application configuration.
|
||||||
|
- `internal/defaults` owns Scriptorium application and HTTP defaults only.
|
||||||
|
- `internal/format` owns deterministic prepared-run text and JSON presentation.
|
||||||
|
- Promptkit owns framework orchestration and contracts. Its
|
||||||
|
[format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/formats.md)
|
||||||
|
and
|
||||||
|
[outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/docs/integrations/openai-compatible-chat.md)
|
||||||
|
are canonical.
|
||||||
|
|
||||||
The [CLI](../cli.md), [configuration](../config.md), [HTTP API](../api.md),
|
## HTTP Artifact Security Boundary
|
||||||
[public Go package](../consumers/pkg-scriptorium.md), and
|
|
||||||
[integration](../integrations/) documents own their respective external
|
|
||||||
contracts. This policy keeps only the architectural boundaries that govern
|
|
||||||
their implementation.
|
|
||||||
|
|
||||||
## Error Handling And Logging
|
Ordinary CLI file loading is provided by Promptkit. Scriptorium's HTTP adapter
|
||||||
|
injects a restricted `promptkit.ArtifactReader` for inbound HTTP requests.
|
||||||
|
That reader denies file references without an artifact root, enforces the
|
||||||
|
configured byte limit, and applies Scriptorium's lexical root-containment rule.
|
||||||
|
The operating system still follows symlinks after the lexical check.
|
||||||
|
|
||||||
- Wrap errors with domain/operation context.
|
The [HTTP API](../api.md) owns observable request outcomes, and
|
||||||
- Map public error identities to adapter-appropriate statuses/codes without
|
[operations](../operations.md) owns deployment permissions and root selection.
|
||||||
leaking sensitive internals.
|
|
||||||
- Never emit raw secret values.
|
|
||||||
|
|
||||||
## Testing And Documentation
|
## State, Errors, And Secrets
|
||||||
|
|
||||||
Testing philosophy and change-validation expectations are defined by the
|
Scriptorium has no durable run-state store, checkpoint, cache, or resume
|
||||||
[testing policy](testing.md). Documentation ownership and maintenance rules are
|
mechanism. Recovery is a new request after correcting inputs, configuration, or
|
||||||
defined by the [documentation policy](documentation.md).
|
environment.
|
||||||
|
|
||||||
|
Adapters map Promptkit public error identities into CLI exits or HTTP statuses
|
||||||
|
without classifying by message text. Raw API keys are not accepted in
|
||||||
|
Scriptorium configuration, CLI arguments, or HTTP payloads, and resolved
|
||||||
|
secrets must not be emitted.
|
||||||
|
|
||||||
## Architectural Invariants
|
## Architectural Invariants
|
||||||
|
|
||||||
- `Runner.Run` reuses `Runner.Prepare` flow.
|
- External YAML and JSON decoding remains strict.
|
||||||
- Raw API key values must not be accepted through external configuration or
|
- CLI and HTTP behavior remains presentation and transport logic rather than
|
||||||
request payloads, and resolved secret values must not be emitted.
|
framework orchestration.
|
||||||
|
- Explicit numeric request overrides preserve presence, including zero.
|
||||||
|
- HTTP artifact containment and byte limits remain Scriptorium policy.
|
||||||
|
- No application package depends on Promptkit implementation packages.
|
||||||
|
|
||||||
## Non-Goals
|
## Non-Goals
|
||||||
|
|
||||||
- Do not move orchestration responsibilities from external callers into Scriptorium.
|
- Do not recreate an in-process Scriptorium framework API or compatibility
|
||||||
- Do not add adapter-specific business logic in `internal/adapter/*` packages.
|
facade.
|
||||||
- Do not bypass repository/renderer/validator/LLM boundaries by introducing cross-package coupling.
|
- Do not copy Promptkit types, defaults, built-in profiles, or implementation
|
||||||
|
into Scriptorium.
|
||||||
|
- Do not move CLI, inbound HTTP, process, or deployment policy into Promptkit.
|
||||||
|
- Do not add durable workflow, archive, or resume behavior.
|
||||||
|
|
||||||
Work that is not implemented belongs in `docs/roadmap/`.
|
Work that is not implemented belongs in `docs/roadmap/`.
|
||||||
|
|||||||
@@ -69,11 +69,11 @@ secret values.
|
|||||||
| Documentation organization | `docs/policy/documentation.md` | Documentation ownership, audience boundaries, maintenance rules, and ADR/document lifecycle. | Application architecture or product behavior. |
|
| Documentation organization | `docs/policy/documentation.md` | Documentation ownership, audience boundaries, maintenance rules, and ADR/document lifecycle. | Application architecture or product behavior. |
|
||||||
| Testing policy | `docs/policy/testing.md` | Test philosophy, risk-based sufficiency, test boundaries, doubles, coverage guidance, regression-test policy, and criteria for adding, rewriting, or deleting tests. | Subsystem behavior, application contracts, subsystem-specific test inventories, and implementation plans. |
|
| Testing policy | `docs/policy/testing.md` | Test philosophy, risk-based sufficiency, test boundaries, doubles, coverage guidance, regression-test policy, and criteria for adding, rewriting, or deleting tests. | Subsystem behavior, application contracts, subsystem-specific test inventories, and implementation plans. |
|
||||||
| CLI contract | `docs/cli.md` | Commands, arguments, flags, invocation semantics, and exit codes. | End-to-end operating procedures, configuration field definitions, runtime filesystem layout, module implementation details. |
|
| CLI contract | `docs/cli.md` | Commands, arguments, flags, invocation semantics, and exit codes. | End-to-end operating procedures, configuration field definitions, runtime filesystem layout, module implementation details. |
|
||||||
| Configuration contract | `docs/config.md` | Discovery and precedence, file schema, fields, defaults, environment overrides, validation rules, and user-selectable module or validator keys. | Complete example files, CLI syntax, runtime state lifecycle, module implementation details. |
|
| Configuration contract | `docs/config.md` | Application discovery and precedence, source locations, server fields, render default, HTTP limits, and credential mapping. | Promptkit framework formats and defaults, complete example files, CLI syntax, runtime lifecycle, and implementation detail. |
|
||||||
| Operations | `docs/operations.md` | Runtime workflows, physical filesystem and state layout, output, cache, and debug handling, resume, cleanup, permissions, recovery, and operational limits. | CLI flag syntax, configuration field definitions, logical output schemas, implementation mechanics. |
|
| Operations | `docs/operations.md` | Runtime workflows, physical filesystem and state layout, output, cache, and debug handling, resume, cleanup, permissions, recovery, and operational limits. | CLI flag syntax, configuration field definitions, logical output schemas, implementation mechanics. |
|
||||||
| Public HTTP contract | `docs/api.md` | Routes, authentication, media types, request and response schemas, status codes, pagination, caching, idempotency, rate limits, and HTTP retry semantics. | Client walkthroughs, upstream or downstream integration internals, implementation detail. |
|
| Public HTTP contract | `docs/api.md` | Routes, authentication, media types, request and response schemas, status codes, pagination, caching, idempotency, rate limits, and HTTP retry semantics. | Client walkthroughs, upstream or downstream integration internals, implementation detail. |
|
||||||
| Consumer guidance | `docs/consumers/` | Task-oriented use of the public interface, minimal client examples, and consumer responsibilities. | HTTP wire semantics, external protocol contracts, internal implementation detail. |
|
| Consumer guidance | `docs/consumers/` | Choosing between Scriptorium's executable interfaces and understanding consumer responsibilities. | HTTP wire semantics, CLI syntax, Promptkit's Go package, and internal implementation detail. |
|
||||||
| External and durable integration contracts | `docs/integrations/` | External file formats and protocols, upstream and downstream contracts, logical output bundle paths and schemas, media types, and compatibility behavior. | Physical runtime placement and lifecycle, internal transformations, CLI syntax, configuration defaults. |
|
| External and durable integration contracts | `docs/integrations/` | Scriptorium-owned process and executable integration contracts. | Promptkit framework formats and outbound provider protocols, physical runtime placement, internal transformations, CLI syntax, and configuration defaults. |
|
||||||
| Implemented component inventory | `docs/internal/overview.md` | Current packages and components, their implemented responsibilities, and links to focused internal docs. | Normative architecture, contributor reading policy, external contracts. |
|
| Implemented component inventory | `docs/internal/overview.md` | Current packages and components, their implemented responsibilities, and links to focused internal docs. | Normative architecture, contributor reading policy, external contracts. |
|
||||||
| Internal component behavior | Other files under `docs/internal/` | Implementation flow, internal collaborators and state transitions, package-local guarantees and failures, and relevant tests. | Global architecture invariants, configuration definitions and defaults, external schemas, operator procedures. |
|
| Internal component behavior | Other files under `docs/internal/` | Implementation flow, internal collaborators and state transitions, package-local guarantees and failures, and relevant tests. | Global architecture invariants, configuration definitions and defaults, external schemas, operator procedures. |
|
||||||
| Architectural decision history | `docs/adr/` | Significant decisions, context, alternatives, rationale, consequences, and supersession history. | Current behavior reference, implementation status, task sequencing. |
|
| Architectural decision history | `docs/adr/` | Significant decisions, context, alternatives, rationale, consequences, and supersession history. | Current behavior reference, implementation status, task sequencing. |
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ Test through the narrowest stable boundary that expresses the behavior clearly.
|
|||||||
|
|
||||||
This is often the package API, but it may instead be:
|
This is often the package API, but it may instead be:
|
||||||
|
|
||||||
- a smaller pure function when dense domain logic is most clearly isolated there;
|
- a smaller pure function when dense application logic is most clearly isolated there;
|
||||||
- a package-level operation when several internal collaborators jointly produce the behavior; or
|
- a package-level operation when several internal collaborators jointly produce the behavior; or
|
||||||
- a larger integration boundary when correctness emerges from interaction with a real dependency.
|
- a larger integration boundary when correctness emerges from interaction with a real dependency.
|
||||||
|
|
||||||
@@ -162,13 +162,16 @@ Use a test-controlled limit and measure the behavior relative to that limit. Do
|
|||||||
|
|
||||||
Each behavior should have a clear test owner.
|
Each behavior should have a clear test owner.
|
||||||
|
|
||||||
- Parser tests own parsing cases.
|
- Configuration tests own application YAML, discovery, precedence, and
|
||||||
- Validator tests own validation rules.
|
application defaults.
|
||||||
- Domain tests own transformations and invariants.
|
- CLI tests own argument mapping, streams, summaries, exit behavior, and
|
||||||
- Adapter tests own external integration behavior.
|
representative command workflows.
|
||||||
- Orchestrator tests own coordination and failure propagation.
|
- HTTP tests own DTOs, strict decoding, limits, status mapping, and restricted
|
||||||
- CLI tests own argument and configuration mapping.
|
artifact policy.
|
||||||
- End-to-end tests prove that representative assembled workflows work.
|
- Formatter tests own prepared-run text and JSON presentation.
|
||||||
|
- Architecture tests own dependency direction and removal invariants.
|
||||||
|
- Promptkit owns framework parsing, orchestration, validation, profiles, and
|
||||||
|
model-client behavior.
|
||||||
|
|
||||||
Higher-level tests should not repeat every lower-level case. A single intentional policy change should not require unrelated edits across many test files.
|
Higher-level tests should not repeat every lower-level case. A single intentional policy change should not require unrelated edits across many test files.
|
||||||
|
|
||||||
@@ -221,7 +224,9 @@ Coverage is a diagnostic, not a target.
|
|||||||
|
|
||||||
Use it to find untested critical branches and unexpectedly weak packages. Do not write low-value tests solely to increase a percentage, and do not infer test quality from coverage alone.
|
Use it to find untested critical branches and unexpectedly weak packages. Do not write low-value tests solely to increase a percentage, and do not infer test quality from coverage alone.
|
||||||
|
|
||||||
Pure domain logic will often warrant higher coverage than CLI wiring or external adapters. Uneven coverage is acceptable when it reflects risk.
|
Security-sensitive HTTP containment and external mappings may warrant denser
|
||||||
|
coverage than straightforward process wiring. Uneven coverage is acceptable
|
||||||
|
when it reflects risk.
|
||||||
|
|
||||||
Increasing coverage is valuable only when the newly covered behavior protects a meaningful risk at an acceptable cost.
|
Increasing coverage is valuable only when the newly covered behavior protects a meaningful risk at an acceptable cost.
|
||||||
|
|
||||||
|
|||||||
@@ -231,9 +231,9 @@ passes its documented validation, and has published its first versioned tag
|
|||||||
before Scriptorium or another consumer adopts it, as required by
|
before Scriptorium or another consumer adopts it, as required by
|
||||||
[ADR 0003](../adr/0003-use-maintainer-run-validation-and-tag-only-releases-for-promptkit.md).
|
[ADR 0003](../adr/0003-use-maintainer-run-validation-and-tag-only-releases-for-promptkit.md).
|
||||||
|
|
||||||
**Gate status:** Complete as of 2026-07-28. The
|
**Gate status:** Complete as of 2026-07-28. Repository history records source
|
||||||
[Step 6 completion record](step6.md) records source Scriptorium commit
|
Scriptorium commit `c7263ab2a8e58f7fb97280082d327a820c7cece7`,
|
||||||
`c7263ab2a8e58f7fb97280082d327a820c7cece7`, accepted Promptkit commit
|
accepted Promptkit commit
|
||||||
`9e68a2bbf779545995270c47842048a3bc6c85dc`, independently passing acceptance,
|
`9e68a2bbf779545995270c47842048a3bc6c85dc`, independently passing acceptance,
|
||||||
published annotated tag `v0.1.0`, and successful remote-consumer validation.
|
published annotated tag `v0.1.0`, and successful remote-consumer validation.
|
||||||
Scriptorium remains unchanged at its pre-cutover boundary. Step 7 adoption of
|
Scriptorium remains unchanged at its pre-cutover boundary. Step 7 adoption of
|
||||||
|
|||||||
Reference in New Issue
Block a user