157 lines
8.6 KiB
Markdown
157 lines
8.6 KiB
Markdown
# Internal Sources And Validation
|
|
|
|
## Purpose
|
|
|
|
This document describes Promptkit's implemented internal source, artifact,
|
|
rendering, and output-validation behavior. The
|
|
[architecture policy](../policy/architecture.md) owns the library boundary and
|
|
dependency rules. None of these internal packages is a supported consumer API,
|
|
and the root engine assembles them behind its public source options and values.
|
|
The [framework format reference](../formats.md) owns the exact file fields,
|
|
validation modes, built-in catalog, and source precedence.
|
|
|
|
## Prompt Definitions
|
|
|
|
`internal/promptdef` uses one source-neutral flow for prompt selection and
|
|
normalization. That flow scans normalized YAML ID and version metadata,
|
|
requires one strictly decoded document per file, classifies errors for the
|
|
selected definition, detects duplicates, and normalizes the exact match.
|
|
Small operating-system and `fs.FS` adapters own discovery, byte reads, display
|
|
paths, content opening, and root containment. Each lookup remains a
|
|
point-in-time scan: definitions and catalogs are not cached, and file-backed
|
|
message content is opened only for the exact selected candidate.
|
|
|
|
Operating-system sources enforce containment against canonical roots and
|
|
targets so symlinks cannot escape. Injected `fs.FS` sources enforce containment
|
|
in their clean relative path namespace. A single-file source uses the selected
|
|
prompt file's containing directory as its root. Every content path must be
|
|
relative and is opened from its exact parsed text after a separate blank check;
|
|
contained parent components and whitespace-bearing names remain valid.
|
|
|
|
Exact prompt inspection performs one point-in-time lookup through that same
|
|
repository and validates referenced message content before returning declared
|
|
metadata. It does not parse templates or read profile, input, or schema
|
|
sources, and it does not retain the definition for a later execution.
|
|
|
|
Its package tests own prompt selection, strict decoding, definition validation,
|
|
duplicate detection, and source containment:
|
|
[prompt-definition repository tests](../../internal/promptdef/repository_test.go).
|
|
|
|
## Profiles And Built-Ins
|
|
|
|
`internal/profile` loads and validates execution profiles from an
|
|
operating-system filesystem or an `fs.FS`. A file contains exactly one YAML
|
|
document and its trimmed YAML `id` is its only selection identity; filenames do
|
|
not confer authority. Each point lookup reads discovered files once for their
|
|
metadata and reuses the selected file's bytes for strict decoding; unrelated
|
|
profiles are not fully decoded. Strict selected decoding recognizes the
|
|
optional `backend` field, trims its value, and requires a model plus at least
|
|
one non-blank backend or endpoint. File-backed `extra_params` values are
|
|
validated and defensively copied through the shared bounded JSON-value owner
|
|
before a profile is published. OpenAI-compatible reserved-field policy remains
|
|
with the model-client and backend-registry owners.
|
|
|
|
The overlay repository consults the next repository only when the
|
|
higher-precedence repository reports that a profile is absent. A reliably
|
|
selected malformed profile stops fallback, while an unrelated malformed file
|
|
does not become authoritative through its filename. Loading does not check
|
|
backend registry membership because the available registry belongs to the
|
|
assembled engine; the runner checks membership during preparation and exact
|
|
profile inspection.
|
|
|
|
The root engine assembles profile repositories in precedence order: in-memory
|
|
profiles, one ordinary configured source, an application fallback source, then
|
|
the embedded built-in catalog. An explicit file or `fs.FS` profile source
|
|
replaces `Config.ProfileDir` within the ordinary configured-source category.
|
|
|
|
Exact profile inspection performs one point-in-time lookup through those
|
|
profile sources and checks the resolved target without reading prompt, input,
|
|
or schema sources. It does not retain that lookup for a later execution.
|
|
|
|
`internal/profile/builtin` embeds the maintained built-in profile catalog.
|
|
Every embedded profile selects a maintained built-in backend and inherits that
|
|
backend's endpoint and credential environment-variable name from the built-in
|
|
backend registry rather than repeating those values. Profile loading and
|
|
overlay behavior are owned by the
|
|
[profile repository tests](../../internal/profile/repository_test.go), while
|
|
catalog completeness, the backend-selection invariant, and duplicate IDs are
|
|
owned by the
|
|
[built-in repository tests](../../internal/profile/builtin/repository_test.go).
|
|
|
|
## Ordinary Artifacts
|
|
|
|
`internal/artifact` accepts explicitly typed inline references even when their
|
|
body is empty. It also resolves unrestricted, caller-selected paths only when
|
|
they identify regular operating-system files, checking that condition before
|
|
and after opening the file. It copies content into an artifact, records
|
|
metadata and an opaque content-equality value, and applies a content-type
|
|
fallback.
|
|
|
|
Regular files are read synchronously in bounded chunks. Cancellation is
|
|
checked before opening, before and after every read, and before publishing the
|
|
artifact, so a canceled read never publishes partial content. The ordinary
|
|
reader does not detach file reads into background goroutines.
|
|
|
|
This ordinary reader does not implement an inbound HTTP security boundary. In
|
|
particular, it does not constrain files to an application root or impose an
|
|
HTTP request-size policy. Scriptorium's restricted HTTP reader remains an
|
|
application concern outside Promptkit. The
|
|
[artifact reader tests](../../internal/artifact/reader_test.go) own the
|
|
implemented reader behavior and failures.
|
|
|
|
## Rendering
|
|
|
|
`internal/prompt` renders definition messages as Go templates using named
|
|
artifacts and variables. Within one render, each referenced artifact body is
|
|
converted to text lazily and cached by input name for reuse across the session
|
|
and every message; the cache is not shared across renders. Conversion uses
|
|
bounded chunks and preserves the artifact bytes exactly.
|
|
|
|
Session and message parsing and execution remain synchronous. The renderer
|
|
checks cancellation before and after each parse and execution boundary,
|
|
between artifact conversion chunks, around each message, and before publishing
|
|
the complete prompt. It cannot interrupt template work already in progress and
|
|
never publishes a partial prompt after observing cancellation. It carries
|
|
message roles, session IDs, and cache control into the rendered prompt. The
|
|
[renderer tests](../../internal/prompt/renderer_test.go) own rendering behavior.
|
|
|
|
## Schemas And Output Validation
|
|
|
|
`internal/validate` provides validators backed by an operating-system
|
|
filesystem or an `fs.FS`. Invalid generated content is returned as a validation
|
|
result; inability to load, register, or compile a schema is an operational
|
|
error.
|
|
|
|
Every preparation operation creates one operation-local validation plan. None,
|
|
basic, and JSON modes retain the effective output contract without source
|
|
access. JSON Schema mode loads the root document once, resolves and compiles
|
|
each transitive reference, and retains the compiled validator. Schema compiler
|
|
resources use canonical escaped file or private-scheme URLs; loaders decode
|
|
their paths once and enforce the configured source boundary. The
|
|
provider-facing structured-output metadata uses the root document captured by
|
|
the same plan.
|
|
|
|
Schema preparation and execution remain synchronous. Promptkit checks
|
|
cancellation before and after source resolution, JSON decoding, compilation,
|
|
and validation, and between bounded schema-read chunks. Once cancellation is
|
|
observed it returns the context error without publishing a partial plan or
|
|
validation result, even when a compiler or validator has just returned a
|
|
different error or a successful result. An `fs.FS` method or JSON Schema
|
|
dependency call already in progress cannot be preempted; Promptkit waits for
|
|
that call to return and then gives cancellation precedence. Validation does
|
|
not detach dependency work into background goroutines.
|
|
|
|
`Prepare` discards its validation plan after returning metadata. `Run` retains
|
|
its plan for initial and repaired-output validation, then discards it with the
|
|
operation. `PrepareExecution` retains the plan in its private frozen payload;
|
|
`RunPrepared` uses that plan without reopening prompt, profile, input, or
|
|
schema sources or rerendering the request. A later ordinary `Run` always
|
|
performs fresh source resolution and preparation.
|
|
|
|
The [validator tests](../../internal/validate/standard_validator_test.go) own
|
|
basic, JSON, JSON Schema, source resolution, schema loading, compilation,
|
|
frozen-reference behavior, content-failure behavior, and the synchronous
|
|
cancellation boundary. Prepared execution
|
|
orchestration is owned by the
|
|
[use-case tests](../../internal/usecase/prepared_execution_test.go).
|