Compare commits
229 Commits
53490cdb59
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e92bcfa74c | |||
| e6b2ae88d2 | |||
| b2e83bd6e7 | |||
| 7f01c3e79e | |||
| 7b5f4ebd42 | |||
| 4bb4582695 | |||
| 7d3434e5f6 | |||
| 29872b2e28 | |||
| b487d93186 | |||
| 8dd7a4324d | |||
| 04ba87e174 | |||
| a26d6ed042 | |||
| 759d32403f | |||
| 1a7b20c766 | |||
| 85a5b52be7 | |||
| 9d0faabf61 | |||
| 1c3da3e869 | |||
| 9abd93502f | |||
| c8a29a5fa2 | |||
| 916d9210fd | |||
| 3d3f16db4a | |||
| 63c397d86a | |||
| 9a92212632 | |||
| 0ef8931697 | |||
| e00cc45c6b | |||
| ab9b743df6 | |||
| 3bd3c7ebf7 | |||
| 75a3f51cee | |||
| 2be999ebd3 | |||
| 32fe7c5b98 | |||
| 55247c47ab | |||
| 5e5c69bf9d | |||
| b4a81f8b09 | |||
| adfed22e1a | |||
| 75b1e2f68b | |||
| 4473363d9f | |||
| 6eb45e0003 | |||
| 0585ad76dc | |||
| 56145c3b7e | |||
| a478fd86c5 | |||
| 916532100d | |||
| bef8ca263b | |||
| f6d037b613 | |||
| 449b506804 | |||
| 071a78ae22 | |||
| ad1cba41c2 | |||
| 67338798aa | |||
| e95e2f2220 | |||
| 628b8d1800 | |||
| d24d4609b6 | |||
| c7f79fb38e | |||
| 8c071800cf | |||
| 569e12c6f4 | |||
| 5b6eb591b2 | |||
| b630384aa0 | |||
| 297d58f090 | |||
| ee71dc4937 | |||
| 65e5d65d14 | |||
| b40b40aaf3 | |||
| f120be1cb4 | |||
| 17673d74ea | |||
| ef19a03cbf | |||
| 0546f6eb4f | |||
| d28d1062e0 | |||
| b3ebfcef37 | |||
| b70d9f77e3 | |||
| 2a75f40871 | |||
| a705ba74a1 | |||
| 8d9c9e7c87 | |||
| 0b5cc4f251 | |||
| 82ffe85f2d | |||
| b3644abc0e | |||
| d653bf1b90 | |||
| 3e66127b94 | |||
| 5d086c13ca | |||
| d36d4e7689 | |||
| 1456aa51cc | |||
| ffc179c822 | |||
| 8e669a1f14 | |||
| 14bfae216d | |||
| 5a58d87995 | |||
| 557809f364 | |||
| ee600975f0 | |||
| 0d8017e23f | |||
| 37b18edf3d | |||
| cda7a61b47 | |||
| 2ad9283148 | |||
| 41a8a80dda | |||
| 90c7fa6381 | |||
| e3839f8620 | |||
| 0fc2f9ee01 | |||
| 5d6305f21a | |||
| 551e4daea2 | |||
| 3589d33468 | |||
| a22c1a7f59 | |||
| ad85d71b0f | |||
| f3506240c2 | |||
| 70c199aa31 | |||
| e2b82746ab | |||
| 4235507f7b | |||
| b346670cc7 | |||
| 7868c26be7 | |||
| 92e89076a2 | |||
| d9b87347b8 | |||
| 20397ef710 | |||
| fc449863f2 | |||
| 51d62de1f3 | |||
| fc76805075 | |||
| 8e680cf96e | |||
| ece1bca460 | |||
| 516af12916 | |||
| 1015d61b2d | |||
| 4192aa8584 | |||
| 8cf03a2a44 | |||
| 2ee6b495e1 | |||
| f1b120b590 | |||
| 2ec17f5b4f | |||
| 6de470d541 | |||
| a6e176e160 | |||
| 3dfefd0e14 | |||
| f91237e9c0 | |||
| ad9ee076b5 | |||
| ce04387dbc | |||
| e8965ebbbb | |||
| c006b163d5 | |||
| 2f61118e78 | |||
| 5e2ccffc0f | |||
| 3f4a1f2647 | |||
| 9653e06297 | |||
| 916a32195b | |||
| 299c110267 | |||
| 4093ff2e8b | |||
| 39563f3ea0 | |||
| 4b52cace76 | |||
| 16d1b29b14 | |||
| 856b26b718 | |||
| ab70347c5d | |||
| 8ed99ceaee | |||
| 257bca0dc2 | |||
| bad5db3ef3 | |||
| 406ad1d362 | |||
| 5f207b2ab1 | |||
| c613b306ae | |||
| 1c7291e17d | |||
| 2345da106a | |||
| 03761c97dd | |||
| 9cb9ee48a7 | |||
| 08954f17e2 | |||
| a57f83e30d | |||
| f4c05c34ef | |||
| 29fcad6e9b | |||
| f5fd115046 | |||
| 7f28899730 | |||
| 84c0758455 | |||
| 5002864e88 | |||
| 55b188fd84 | |||
| d1f43df88e | |||
| d52387c1f7 | |||
| 9c5e3cff14 | |||
| 811d5b8bd9 | |||
| a168c13b85 | |||
| dd61a4efda | |||
| 228cc6ee83 | |||
| 06170e1f65 | |||
| 7715baa1f6 | |||
| 98506db1a9 | |||
| bb4855f0c6 | |||
| c51934d5c6 | |||
| c3513da880 | |||
| c7d853ea52 | |||
| da7fcdaffd | |||
| b6aad4fa98 | |||
| 9c6af28d02 | |||
| 04eabdfcb9 | |||
| a8a99c1037 | |||
| e15007fffb | |||
| e6b7c61f45 | |||
| 42973215fa | |||
| ba1d112d1f | |||
| b722131d57 | |||
| a92d2c0885 | |||
| 02ec10d66b | |||
| 9dd57dbfa4 | |||
| c164a3fc69 | |||
| 8834df617f | |||
| db2adb52da | |||
| fc3c128171 | |||
| 8a15b083a0 | |||
| d9dae2b639 | |||
| 7a4fd7be7a | |||
| 39388e96d4 | |||
| 12ac25bd63 | |||
| 394278e1f2 | |||
| 5cd7f8e737 | |||
| bf3fadf9ae | |||
| 58815aaf33 | |||
| ce857966f1 | |||
| a3bd0c1867 | |||
| b05634ee86 | |||
| 4829f94157 | |||
| 67b315099d | |||
| b5c86de4d7 | |||
| 2eeca2ed5a | |||
| b5aaeb1c78 | |||
| 9171b66a41 | |||
| b4363b3b73 | |||
| 241e9d2a89 | |||
| 715fff7b72 | |||
| d627b91b4f | |||
| a67b3aa76d | |||
| a16dcdfa52 | |||
| 46e4466d28 | |||
| 71a004bfc8 | |||
| f8333f2c15 | |||
| f603f7ac64 | |||
| 7a00e7049c | |||
| 2a9db9a957 | |||
| de046a8f13 | |||
| f1a6574013 | |||
| 4bca6d3103 | |||
| 7c569a3d8c | |||
| 8e04ef9e2b | |||
| 53a330587b | |||
| 7cfab8ada0 | |||
| 5c82b62856 | |||
| de8ed41b34 | |||
| d1eaec4dad | |||
| c0ec068f53 | |||
| 5cbd9e56e4 |
33
.woodpecker/release.yml
Normal file
33
.woodpecker/release.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
when:
|
||||
- event: tag
|
||||
|
||||
steps:
|
||||
- name: validate-release
|
||||
image: golang:1.25.5
|
||||
commands:
|
||||
- |
|
||||
set -eu
|
||||
|
||||
version="$CI_COMMIT_TAG"
|
||||
release_note="docs/releases/$version.md"
|
||||
|
||||
if ! printf '%s\n' "$version" | grep -E -x 'v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)' >/dev/null; then
|
||||
printf '%s\n' "invalid release tag: $version" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -s "$release_note" ]; then
|
||||
printf '%s\n' "missing release note: $release_note" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -F -x "# Notarius $version" "$release_note" >/dev/null; then
|
||||
printf '%s\n' "release note heading does not match $version" >&2
|
||||
exit 1
|
||||
fi
|
||||
for heading in '## Summary' '## Compatibility' '## Upgrade' '## Changes'; do
|
||||
if ! grep -F -x "$heading" "$release_note" >/dev/null; then
|
||||
printf '%s\n' "release note is missing heading: $heading" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
./scripts/check-release-source.sh "$version"
|
||||
21
README.md
21
README.md
@@ -2,8 +2,9 @@
|
||||
|
||||
Notarius is a Go CLI for turning source material into structured artifacts with
|
||||
configured extraction pipelines. The implemented D&D workflow reads Seriatim
|
||||
transcript JSON and can produce scene descriptions, item and currency events,
|
||||
NPC identities, combat turns, NPC interactions, and spell casts.
|
||||
transcript JSON and can produce NPC, location, and item registries; their
|
||||
source-grounded occurrences; scene descriptions, combat turns, enemy events,
|
||||
and spell casts.
|
||||
|
||||
## Quickstart
|
||||
|
||||
@@ -27,6 +28,20 @@ For the complete ordered D&D workflow, use
|
||||
[its synthetic transcript](examples/dnd-complete-transcript.json). It
|
||||
demonstrates all implemented D&D lanes and the supporting campaign references.
|
||||
|
||||
## Install A Source Release
|
||||
|
||||
Install a pinned source release with Go:
|
||||
|
||||
~~~
|
||||
GOWORK=off go install \
|
||||
gitea.maximumdirect.net/eric/notarius/cmd/notarius@<tag>
|
||||
~~~
|
||||
|
||||
Replace `<tag>` with a stable release tag such as `vMAJOR.MINOR.PATCH`. The
|
||||
installed command's diagnostic version is described in the [CLI
|
||||
reference](docs/cli.md); maintainers preparing a release should follow [Source
|
||||
Releases](docs/release.md).
|
||||
|
||||
## Documentation
|
||||
|
||||
- [CLI reference](docs/cli.md) — commands, flags, output streams, and exits.
|
||||
@@ -38,6 +53,8 @@ demonstrates all implemented D&D lanes and the supporting campaign references.
|
||||
artifact formats.
|
||||
- [Subprocess consumer guide](docs/consumers/subprocess.md) — invoke Notarius
|
||||
from an orchestrator and consume a published result.
|
||||
- [Complete D&D consumer guide](docs/consumers/dnd-pipeline.md) — run the full
|
||||
D&D pipeline as a subprocess and discover its structured artifacts.
|
||||
- [Internal overview](docs/internal/overview.md) — implemented component map
|
||||
for maintainers.
|
||||
- [Developer guide](docs/development.md) — contributor orientation and
|
||||
|
||||
18
assets/dnd/combat-turns/prompts/instructions.md
Normal file
18
assets/dnd/combat-turns/prompts/instructions.md
Normal file
@@ -0,0 +1,18 @@
|
||||
Extract Dungeons & Dragons combat-turn artifacts from the supplied transcript.
|
||||
Include a record only when the transcript establishes that an in-world
|
||||
participant takes a combat turn or performs a discrete interrupting combat
|
||||
event. Keep events in transcript chronology; place an interrupting event where
|
||||
it occurs.
|
||||
|
||||
Exclude initiative setup without a turn or combat event, tactical planning,
|
||||
table talk, rules lookup, hypothetical events, abandoned intentions, recaps
|
||||
outside the current passage, and downstream consequences. Do not infer combat
|
||||
events from Dungeons & Dragons rules knowledge. Preserve the session as played
|
||||
and attribute relevant nonstandard rulings to the GM or table. Unmatched actors
|
||||
remain permitted.
|
||||
|
||||
Treat each record as one turn-level event and keep its supporting transcript
|
||||
evidence together. Use `turn` for a regular combat turn, `reaction` for an
|
||||
off-turn reaction, `legendary_action` for a legendary action,
|
||||
`lair_action` for a lair action, and `other` for another discrete combat
|
||||
event that does not fit those categories.
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.combat_turns
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
@@ -14,36 +14,32 @@ inputs:
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: npcs
|
||||
- name: npc_registry
|
||||
required: false
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-npcs.md
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-npc-registry.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_combat_turns_llm.v1.json
|
||||
repair_attempts: 0
|
||||
repair_attempts: 1
|
||||
12
assets/dnd/enemy-events/prompts/combat-grounding.md
Normal file
12
assets/dnd/enemy-events/prompts/combat-grounding.md
Normal file
@@ -0,0 +1,12 @@
|
||||
Compact combat grounding is supplied below. It can guide attention and
|
||||
disambiguation, but it is not evidence. Do not derive an event, subject,
|
||||
outcome, or source range from either list. The current transcript alone must
|
||||
directly establish every returned event.
|
||||
|
||||
Combat-turn grounding:
|
||||
|
||||
{{ input "combat_turns" }}
|
||||
|
||||
Named combat-opponent grounding:
|
||||
|
||||
{{ input "npc_occurrences" }}
|
||||
25
assets/dnd/enemy-events/prompts/instructions.md
Normal file
25
assets/dnd/enemy-events/prompts/instructions.md
Normal file
@@ -0,0 +1,25 @@
|
||||
Extract Dungeons & Dragons enemy events from the supplied combat transcript.
|
||||
An `engaged` event requires direct establishment that a subject is actively
|
||||
opposing the party in combat. A `killed`, `fled`, `captured`, or
|
||||
`incapacitated` event requires explicit establishment of that outcome. An
|
||||
outcome may share evidence with an engagement, and a later engagement or
|
||||
outcome for the same subject remains a separate observation. Emit at most one
|
||||
`engaged` observation for the same subject in this combat scene.
|
||||
|
||||
For `killed`, direct death or killing is required. For `fled`, the subject
|
||||
must explicitly escape, retreat, or leave combat to avoid continued engagement.
|
||||
For `captured`, the subject must be explicitly taken prisoner or secured
|
||||
under the party's control. For `incapacitated`, the subject must be explicitly
|
||||
unable to continue acting without being established as killed or captured.
|
||||
|
||||
When the transcript identifies a named NPC, use its normalized registry
|
||||
spelling. A hostile creature without a registry entry is allowed. For unnamed
|
||||
individuals or groups, use only the narrowest transcript-grounded label, such
|
||||
as `Orcs`, `One orc`, or `Remaining orcs`; never invent member names, IDs,
|
||||
or quantities.
|
||||
|
||||
Exclude party members, allies, neutral observers, mentioned-but-absent enemies,
|
||||
hazards, traps, environmental effects, uncertain allegiance, table talk,
|
||||
planning, hypotheses, recaps outside this passage, and downstream inference.
|
||||
Do not infer an engagement or outcome from initiative, turn absence, damage,
|
||||
defeat, movement, or a scene ending.
|
||||
53
assets/dnd/enemy-events/prompts/prompt.yaml
Normal file
53
assets/dnd/enemy-events/prompts/prompt.yaml
Normal file
@@ -0,0 +1,53 @@
|
||||
id: dnd.enemy_events
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: players
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: party
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: npc_registry
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: combat_turns
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: npc_occurrences
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-npc-registry.md
|
||||
- role: user
|
||||
content_file: ./combat-grounding.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_enemy_events_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.item_events.llm",
|
||||
"$id": "notarius.dnd.enemy_events.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["events"],
|
||||
@@ -14,18 +14,15 @@
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"kind": {"type": "string"},
|
||||
"quantity": {"type": "integer"},
|
||||
"from": {"type": "string"},
|
||||
"to": {"type": "string"},
|
||||
"source_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_segment", "end_segment"],
|
||||
"required": ["start_unit_id", "end_unit_id"],
|
||||
"properties": {
|
||||
"start_segment": {"type": "integer"},
|
||||
"end_segment": {"type": "integer"}
|
||||
"start_unit_id": {"type": "integer"},
|
||||
"end_unit_id": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
assets/dnd/item-occurrences/prompts/instructions.md
Normal file
30
assets/dnd/item-occurrences/prompts/instructions.md
Normal file
@@ -0,0 +1,30 @@
|
||||
Extract meaningful Dungeons & Dragons item and currency occurrences: discoveries and changes
|
||||
in party possession established by the transcript. This is an occurrence history,
|
||||
not an inventory or ledger: do not calculate balances, resolve item identity
|
||||
across records, or infer ownership that the transcript does not establish.
|
||||
|
||||
For every occurrence, use the supplied canonical item `name`. Record a stated
|
||||
quantity as an integer and leave it null when the transcript does not state
|
||||
one. Preserve the stated currency denomination through the selected canonical
|
||||
registry name.
|
||||
|
||||
Use `discovered` when the party learns of or encounters an item without
|
||||
establishing possession. Use `acquired` when the party or a party member gains
|
||||
possession. Use `lost` when party possession ends through a gift, sale, payment,
|
||||
theft, abandonment, or destruction not caused by intended use. Use `consumed`
|
||||
when intended use depletes an expendable item. Monetary spending, purchases, and
|
||||
payments are always `lost`, not `consumed`. Classify currency as `consumed` only
|
||||
when the transcript explicitly describes it being physically destroyed or
|
||||
expended as a non-payment component. Use `transferred` only when possession
|
||||
moves between two distinct named party members.
|
||||
|
||||
Return both `from` and `to` for every occurrence, using `null` when a holder does not
|
||||
apply. For `discovered`, set both holders to `null`. For `acquired`, set `from`
|
||||
to `null` and provide `to`; for `lost` and `consumed`, provide `from` and set
|
||||
`to` to `null`; and for `transferred`, provide both holders. Use `party` only
|
||||
for collective or unresolved party possession, never for either side of a
|
||||
transfer. Do not emit a transfer for a gift, sale, or payment outside the party.
|
||||
|
||||
Ordinary non-depleting use is not an occurrence. Do not infer acquisition from a
|
||||
discovery, or discovery from an acquisition: emit both only when each is
|
||||
independently established.
|
||||
6
assets/dnd/item-occurrences/prompts/item-registry.md
Normal file
6
assets/dnd/item-occurrences/prompts/item-registry.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Use the supplied item registry only to ground each occurrence. Every record
|
||||
must use one registry item's canonical `name`; do not invent, rename, merge,
|
||||
or infer registry items. The registry is not transcript evidence: cite only the
|
||||
current transcript chunk in `source_refs`.
|
||||
|
||||
{{ input "item_registry" }}
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.npc_interactions
|
||||
id: dnd.item_occurrences
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
@@ -14,36 +14,32 @@ inputs:
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: npcs
|
||||
- name: item_registry
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-npcs.md
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./item-registry.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_npc_interactions_llm.v1.json
|
||||
repair_attempts: 0
|
||||
schema_path: dnd_item_occurrences_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.item_occurrences.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["occurrences"],
|
||||
"properties": {
|
||||
"occurrences": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "kind", "quantity", "from", "to", "source_refs"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"kind": {"type": "string"},
|
||||
"quantity": {"type": ["integer", "null"]},
|
||||
"from": {"type": ["string", "null"]},
|
||||
"to": {"type": ["string", "null"]},
|
||||
"source_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_unit_id", "end_unit_id"],
|
||||
"properties": {
|
||||
"start_unit_id": {"type": "integer"},
|
||||
"end_unit_id": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
assets/dnd/item-registry/extract/prompts/instructions.md
Normal file
12
assets/dnd/item-registry/extract/prompts/instructions.md
Normal file
@@ -0,0 +1,12 @@
|
||||
Extract only items established by the provided Dungeons & Dragons transcript.
|
||||
|
||||
Include named unique items, concrete reusable item types, and stable unique
|
||||
designations. Record each currency denomination separately when it is
|
||||
established, such as copper pieces, silver pieces, gold pieces, or platinum
|
||||
pieces. Do not use capitalization as an eligibility test. Keep distinct names
|
||||
and designations as separate candidates; do not merge aliases or invent
|
||||
qualifiers.
|
||||
|
||||
Do not record vague categories such as "loot", "treasure", or "some gear";
|
||||
generic weapons; inferred properties; quantities; or inferred uniqueness. Omit
|
||||
uncertain or unsupported items.
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.npcs
|
||||
id: dnd.item_registry
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
@@ -17,26 +17,24 @@ inputs:
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_npcs_llm.v1.json
|
||||
repair_attempts: 0
|
||||
schema_path: dnd_item_registry_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.item_registry.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["items"],
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "source_refs"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"source_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_unit_id", "end_unit_id"],
|
||||
"properties": {
|
||||
"start_unit_id": {"type": "integer"},
|
||||
"end_unit_id": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
Determine whether candidates identify the same item type or unique designation
|
||||
using their contextual labels and cited transcript windows. Do not treat nearby
|
||||
evidence, similar objects, or a shared owner as sufficient.
|
||||
|
||||
Keep currency denominations and materially different item types separate. Keep
|
||||
uncertain aliases separate. Do not infer an item property or uniqueness.
|
||||
|
||||
When selecting a canonical display name, choose one supplied candidate name
|
||||
that is the clearest established designation.
|
||||
30
assets/dnd/item-registry/normalize/prompts/prompt.yaml
Normal file
30
assets/dnd/item-registry/normalize/prompts/prompt.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
id: dnd.item_registry.normalize
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: candidates
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/protocol.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/candidates.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/transcript-windows.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: semantic_reconciliation_llm.v1.json
|
||||
repair_attempts: 1
|
||||
34
assets/dnd/location-occurrences/prompts/instructions.md
Normal file
34
assets/dnd/location-occurrences/prompts/instructions.md
Normal file
@@ -0,0 +1,34 @@
|
||||
Extract Dungeons & Dragons location occurrences from the supplied transcript.
|
||||
Include an occurrence only when the transcript establishes one supplied
|
||||
location, one occurrence kind, and a coherent passage supporting both.
|
||||
|
||||
Use exactly one kind per occurrence:
|
||||
|
||||
- visited: party members are physically present, arrive, remain, or depart;
|
||||
- planned: the party explicitly proposes, intends, or agrees to future travel;
|
||||
- recalled: the transcript explicitly recounts an earlier party visit; or
|
||||
- mentioned: the location is explicitly referenced without stronger support,
|
||||
including non-actionable speculation or a mere hypothetical reference.
|
||||
|
||||
A mere hypothetical or speculative reference is not planned unless the
|
||||
transcript also establishes an actual proposal, intention, or agreement to
|
||||
travel. When the hypothetical explicitly names a supplied location, it may be
|
||||
mentioned.
|
||||
|
||||
A generic phrase in the current chunk may refer to a supplied named registry
|
||||
location only when the chunk's context supports that coreference. It must not
|
||||
create a registry location, and registry content or provenance must never
|
||||
replace current-chunk evidence.
|
||||
|
||||
For every occurrence, return the exact selector from the location registry:
|
||||
the canonical `name`, plus an empty `registry_refs` array for a unique name or
|
||||
the complete ordered `registry_refs` array for a repeated name. Registry ranges
|
||||
and context identify the location only; they are not occurrence evidence.
|
||||
|
||||
For overlapping support, visited outranks planned, recalled, and mentioned;
|
||||
planned outranks recalled and mentioned; recalled outranks mentioned. A passage
|
||||
may produce multiple records when it independently establishes separate facts,
|
||||
such as recalling an earlier visit while planning a return. Omit inferred,
|
||||
unstated, uncertain, or unsupported places and occurrences. Do not infer a
|
||||
location or occurrence from surrounding events when the transcript does not
|
||||
state it. Do not summarize location descriptions.
|
||||
11
assets/dnd/location-occurrences/prompts/location-registry.md
Normal file
11
assets/dnd/location-occurrences/prompts/location-registry.md
Normal file
@@ -0,0 +1,11 @@
|
||||
A contextual location registry is provided below for identity grounding. It may
|
||||
be empty. Every record supplies a canonical display name. A name that appears
|
||||
once is selected with that name and an empty `registry_refs` array. A repeated
|
||||
name is selected only by copying both its name and its complete, ordered
|
||||
`registry_refs` array exactly as supplied.
|
||||
|
||||
Registry content is context, not occurrence evidence. Do not derive an
|
||||
occurrence or `source_refs` range from the registry. Do not invent a location
|
||||
or selector that is absent from it.
|
||||
|
||||
{{ input "location_registry" }}
|
||||
45
assets/dnd/location-occurrences/prompts/prompt.yaml
Normal file
45
assets/dnd/location-occurrences/prompts/prompt.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
id: dnd.location_occurrences
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: players
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: party
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: location_registry
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./location-registry.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_location_occurrences_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.location_occurrences.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["occurrences"],
|
||||
"properties": {
|
||||
"occurrences": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "registry_refs", "kind", "source_refs"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"registry_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_unit_id", "end_unit_id"],
|
||||
"properties": {
|
||||
"start_unit_id": {"type": "integer", "minimum": 1},
|
||||
"end_unit_id": {"type": "integer", "minimum": 1}
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind": {"enum": ["visited", "planned", "recalled", "mentioned"]},
|
||||
"source_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_unit_id", "end_unit_id"],
|
||||
"properties": {
|
||||
"start_unit_id": {"type": "integer"},
|
||||
"end_unit_id": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
assets/dnd/location-registry/extract/prompts/instructions.md
Normal file
13
assets/dnd/location-registry/extract/prompts/instructions.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Extract only physical places established by the provided Dungeons & Dragons
|
||||
transcript that have a stable proper name or unique in-world designation. This
|
||||
includes named planes, regions, settlements, districts, buildings, rooms,
|
||||
landmarks, routes, and geographic features.
|
||||
|
||||
Do not create a registry location for generic, temporary, relative, or merely
|
||||
descriptive phrases, including "the room", "the bar", "the hallway",
|
||||
"outside", and "upstairs". Do not use capitalization as an eligibility test.
|
||||
Keep aliases and nested places when the transcript identifies them; do not merge
|
||||
or invent qualifiers for similarly named places.
|
||||
|
||||
Exclude people, creatures, objects, organizations, abstract concepts, and
|
||||
places merely inferred from an event. Omit uncertain or unsupported places.
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.item_events
|
||||
id: dnd.location_registry
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
@@ -17,26 +17,24 @@ inputs:
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_item_events_llm.v1.json
|
||||
repair_attempts: 0
|
||||
schema_path: dnd_location_registry_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.location_registry.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["locations"],
|
||||
"properties": {
|
||||
"locations": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "source_refs"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"source_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_unit_id", "end_unit_id"],
|
||||
"properties": {
|
||||
"start_unit_id": {"type": "integer"},
|
||||
"end_unit_id": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
Determine whether candidates identify the same physical place using their
|
||||
contextual labels and cited transcript windows. Do not treat matching names,
|
||||
nearby evidence, nested places, or generic labels as sufficient.
|
||||
|
||||
Keep parent and child places separate, as well as similarly named places and
|
||||
uncertain aliases.
|
||||
|
||||
When selecting a canonical display name, prefer the clearest established name.
|
||||
30
assets/dnd/location-registry/normalize/prompts/prompt.yaml
Normal file
30
assets/dnd/location-registry/normalize/prompts/prompt.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
id: dnd.location_registry.normalize
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: candidates
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/protocol.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/candidates.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/transcript-windows.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: semantic_reconciliation_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -1,6 +1,14 @@
|
||||
Return the interactions array even when no interaction is established. Every
|
||||
record must contain name, kind, and source_refs. Cite transcript ranges that
|
||||
support both the NPC identity and the interaction kind.
|
||||
Extract Dungeons & Dragons NPC occurrences from the supplied
|
||||
transcript. Include an occurrence only when the transcript establishes one
|
||||
supplied NPC, one occurrence kind, and a coherent passage supporting both.
|
||||
Use the supplied canonical NPC `name`; never invent or substitute a similar
|
||||
name. Cite current-transcript evidence for every occurrence.
|
||||
|
||||
Do not summarize, infer relationships, sentiment, factions, motives, aliases,
|
||||
or persistent state. Do not identify player characters, anonymous groups, or
|
||||
invented NPCs. Split records when an NPC's occurrence kind changes, when
|
||||
combat alignment changes, or when an NPC is first mentioned and later becomes
|
||||
present.
|
||||
|
||||
Use exactly one kind per occurrence:
|
||||
|
||||
45
assets/dnd/npc-occurrences/prompts/prompt.yaml
Normal file
45
assets/dnd/npc-occurrences/prompts/prompt.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
id: dnd.npc_occurrences
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: players
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: party
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: npc_registry
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-npc-registry.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_npc_occurrences_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.npc_interactions.llm",
|
||||
"$id": "notarius.dnd.npc_occurrences.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["interactions"],
|
||||
"required": ["occurrences"],
|
||||
"properties": {
|
||||
"interactions": {
|
||||
"occurrences": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
19
assets/dnd/npc-registry/extract/prompts/instructions.md
Normal file
19
assets/dnd/npc-registry/extract/prompts/instructions.md
Normal file
@@ -0,0 +1,19 @@
|
||||
Extract the individually identifiable Dungeons & Dragons non-player characters
|
||||
established by the provided transcript.
|
||||
|
||||
Include an in-world non-PC only when the transcript factually establishes a
|
||||
proper name or a stable, individually distinguishing title or alias. A factual
|
||||
third-party mention establishes that identity even when the NPC is not
|
||||
physically present, does not speak, and takes no direct action in this chunk.
|
||||
Record only the NPC identity and the transcript evidence that establishes it;
|
||||
do not infer or classify a separate occurrence.
|
||||
|
||||
Exclude human players, transcript speakers, and the GM as out-of-world people;
|
||||
player characters identified by the player or party references; names used only
|
||||
in hypothetical, speculative, or imagined examples; corrected transcription
|
||||
mistakes; anonymous or generic roles; indistinguishable crowds or groups;
|
||||
invented descriptive labels; and temporary summoned creatures or spell effects
|
||||
without a persistent individual identity.
|
||||
|
||||
Preserve observed display spelling. Do not invent a label for an anonymous
|
||||
creature, crowd, or generic role.
|
||||
40
assets/dnd/npc-registry/extract/prompts/prompt.yaml
Normal file
40
assets/dnd/npc-registry/extract/prompts/prompt.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
id: dnd.npc_registry
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: players
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: party
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_npc_registry_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.npcs.llm",
|
||||
"$id": "notarius.dnd.npc_registry.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["npcs"],
|
||||
11
assets/dnd/npc-registry/normalize/prompts/instructions.md
Normal file
11
assets/dnd/npc-registry/normalize/prompts/instructions.md
Normal file
@@ -0,0 +1,11 @@
|
||||
Determine whether candidates refer to the same individual using their
|
||||
contextual labels and cited transcript windows. Preserve distinct individuals
|
||||
even when their names are similar or their contextual descriptions are
|
||||
identical.
|
||||
|
||||
When selecting a canonical display name, prefer a complete, stable proper name
|
||||
over an abbreviation. Prefer an unadorned proper name over that name plus a
|
||||
contextual class, role, title, or relationship descriptor unless the transcript
|
||||
establishes the descriptor as part of the person's name. A longer display name
|
||||
is not inherently more canonical; for example, do not prefer `Captain Aria`
|
||||
over `Aria` solely because it includes the contextual title `Captain`.
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.npcs.normalize
|
||||
id: dnd.npc_registry.normalize
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: candidates
|
||||
required: true
|
||||
@@ -11,20 +11,20 @@ inputs:
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
content_file: ./sharedassets/protocol.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./candidates.md
|
||||
content_file: ./sharedassets/candidates.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
content_file: ./sharedassets/transcript-windows.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_npcs_normalize_llm.v1.json
|
||||
repair_attempts: 0
|
||||
schema_path: semantic_reconciliation_llm.v1.json
|
||||
repair_attempts: 1
|
||||
5
assets/dnd/profiles/dnd-extraction.yaml
Normal file
5
assets/dnd/profiles/dnd-extraction.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
id: dnd-extraction
|
||||
backend: openrouter
|
||||
model: openai/gpt-5.6-luna
|
||||
timeout_seconds: 240
|
||||
service_tier: flex
|
||||
@@ -1,4 +1,9 @@
|
||||
Choose exactly one kind:
|
||||
Describe exactly one accepted Dungeons & Dragons scene from the supplied
|
||||
transcript chunk. The complete chunk is the evidence boundary: do not split it
|
||||
into multiple scenes or use facts that are not supported by it.
|
||||
|
||||
Return one kind, one concise title, and one concise summary. Choose exactly one
|
||||
kind:
|
||||
|
||||
- combat: active combat materially organizes the scene, including
|
||||
initiative-like exchanges or sustained hostile action. Planning a fight or
|
||||
@@ -37,8 +42,4 @@ must not invent a proper noun.
|
||||
The summary must briefly state the main activity and material transition or
|
||||
outcome established within the accepted chunk. Do not add analysis, inferred
|
||||
motives, hidden state, future consequences, relationship claims, or facts from
|
||||
outside the chunk. Campaign references may disambiguate names but never add
|
||||
events or lore.
|
||||
|
||||
Do not return identifiers, source identifiers, source ranges, unit identifiers,
|
||||
participants, confidence, or any fields besides kind, title, and summary.
|
||||
outside the chunk.
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.scene_descriptions
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
@@ -19,22 +19,20 @@ messages:
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_scene_descriptions_llm.v1.json
|
||||
repair_attempts: 0
|
||||
repair_attempts: 1
|
||||
@@ -1,5 +1,5 @@
|
||||
Divide the provided transcript into coherent Dungeons & Dragons scenes for the
|
||||
`dnd/scenes` chunk module.
|
||||
Divide the complete provided transcript into coherent Dungeons & Dragons scenes
|
||||
for the `dnd/scenes` chunk module.
|
||||
|
||||
A scene is a coherent unit of play. Start a new scene when the transcript
|
||||
establishes a meaningful change in location, objective, threat, activity,
|
||||
@@ -13,6 +13,7 @@ Do not split a scene merely because a speaker or combat round changes, a
|
||||
routine turn occurs, or the table briefly digresses. Prefer fewer coherent
|
||||
scenes over speculative or fine-grained boundaries.
|
||||
|
||||
Return only inclusive `start_unit_id` and `end_unit_id` endpoints for each
|
||||
scene. Do not return titles, modes, participants, summaries, boundary notes,
|
||||
confidence, caveats, final chunk IDs, or chunk indexes.
|
||||
Cover the complete transcript from its first source unit to its last. Return
|
||||
scenes in source-unit order with no gaps or overlaps. Use only positive integer
|
||||
source-unit IDs from the transcript, and give every scene one inclusive
|
||||
`start_unit_id` and one inclusive `end_unit_id`.
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.scenes
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
@@ -17,20 +17,18 @@ inputs:
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript-full.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_scenes.v1.json
|
||||
repair_attempts: 0
|
||||
schema_path: dnd_scenes_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.scenes",
|
||||
"$id": "notarius.dnd.scenes.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["scenes"],
|
||||
@@ -0,0 +1,6 @@
|
||||
Transcript units are the only evidence for extracted events and factual claims.
|
||||
Every reported factual claim must be supported by cited transcript units. Use
|
||||
integer `start_unit_id` and `end_unit_id` values from the transcript.
|
||||
|
||||
When supporting evidence is non-contiguous, use multiple narrow ranges rather
|
||||
than a broad range that bridges unrelated conversation.
|
||||
@@ -7,4 +7,4 @@ participants, effects, or source references from the registry. Registry source
|
||||
references describe registry provenance and may belong to another session; they
|
||||
are never evidence for the current transcript.
|
||||
|
||||
{{ input "npcs" }}
|
||||
{{ input "npc_registry" }}
|
||||
5
assets/dnd/shared/prompts/common-dnd-system.md
Normal file
5
assets/dnd/shared/prompts/common-dnd-system.md
Normal file
@@ -0,0 +1,5 @@
|
||||
You process Dungeons & Dragons gameplay transcripts.
|
||||
|
||||
As input, you will receive one or more portions of a transcript. The transcript may contain transcription errors, repeated lines, incomplete sentences, and misheard proper nouns.
|
||||
|
||||
Return exactly one JSON object that conforms to the configured response schema, with no explanatory prose.
|
||||
3
assets/dnd/shared/prompts/common-dnd-transcript-chunk.md
Normal file
3
assets/dnd/shared/prompts/common-dnd-transcript-chunk.md
Normal file
@@ -0,0 +1,3 @@
|
||||
One extraction chunk from a Dungeons & Dragons gameplay transcript is provided below. Report and infer only what is within this chunk. Its unit IDs retain their source-wide meaning.
|
||||
|
||||
{{ input "transcript" }}
|
||||
3
assets/dnd/shared/prompts/common-dnd-transcript-full.md
Normal file
3
assets/dnd/shared/prompts/common-dnd-transcript-full.md
Normal file
@@ -0,0 +1,3 @@
|
||||
The complete ordered transcript of this Dungeons & Dragons gameplay session is provided below.
|
||||
|
||||
{{ input "transcript" }}
|
||||
14
assets/dnd/spells/prompts/instructions.md
Normal file
14
assets/dnd/spells/prompts/instructions.md
Normal file
@@ -0,0 +1,14 @@
|
||||
Extract Dungeons & Dragons spell-cast artifacts from the provided transcript.
|
||||
Include an actual casting event or an unambiguous declared casting attempt.
|
||||
Exclude spell mentions, hypothetical plans, rules discussion, and catalog
|
||||
matches that do not establish a casting event in the transcript.
|
||||
|
||||
For every extracted cast, the transcript evidence must collectively support the
|
||||
in-world caster, the spell, and the fact that the cast or declared attempt
|
||||
occurred.
|
||||
|
||||
Attribute every cast to its in-world caster. Map first-person player speech to
|
||||
the associated player character, and attribute a spell narrated by the GM to
|
||||
the in-world creature that casts it. If the caster cannot be resolved, use only
|
||||
the most specific in-world identity supported by the transcript; do not invent
|
||||
a name.
|
||||
@@ -1,6 +1,6 @@
|
||||
id: dnd.spells
|
||||
version: "v1"
|
||||
default_profile: gemini-2-flash
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
@@ -17,38 +17,34 @@ inputs:
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: npcs
|
||||
- name: npc_registry
|
||||
required: false
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-npcs.md
|
||||
content_file: ./sharedassets/common-dnd-transcript-chunk.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./catalog.md
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
content_file: ./sharedassets/common-dnd-npc-registry.md
|
||||
- role: user
|
||||
content_file: ./spell-catalog.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_spells_llm.v1.json
|
||||
repair_attempts: 0
|
||||
repair_attempts: 1
|
||||
6
assets/dnd/spells/prompts/spell-catalog.md
Normal file
6
assets/dnd/spells/prompts/spell-catalog.md
Normal file
@@ -0,0 +1,6 @@
|
||||
The spell catalog for this extraction is provided below as JSON. Each entry
|
||||
lists a `canonical_name` and its recognized `aliases`. If the transcript uses
|
||||
an alias, select that entry's `canonical_name`. Return spell names using the
|
||||
canonical spelling exactly; never return an alias as a spell name.
|
||||
|
||||
{{ input "spell_catalog" }}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.spells",
|
||||
"$id": "notarius.dnd.spells.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["spell_casts"],
|
||||
@@ -0,0 +1,3 @@
|
||||
Candidate material:
|
||||
|
||||
{{ input "candidates" }}
|
||||
@@ -0,0 +1,5 @@
|
||||
Identify only high-confidence duplicate entities among the supplied candidates.
|
||||
|
||||
Preserve distinct entities even when their names are similar. Treat contextual descriptions and transcript evidence as supporting material, not as permission to merge ambiguous records.
|
||||
|
||||
When several records are duplicates, choose as canonical the candidate with the clearest stable identity. Prefer a complete proper name over an abbreviation, and prefer an unadorned proper name over one with incidental descriptors unless the evidence establishes those descriptors as part of the name. A longer name is not inherently more canonical.
|
||||
27
assets/generic/normalize/deduplication/prompts/prompt.yaml
Normal file
27
assets/generic/normalize/deduplication/prompts/prompt.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
id: generic.semantic_reconciliation
|
||||
version: "v1"
|
||||
inputs:
|
||||
- name: candidates
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./system.md
|
||||
- role: user
|
||||
content_file: ./protocol.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./candidates.md
|
||||
- role: user
|
||||
content_file: ./transcript-windows.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: semantic_reconciliation_llm.v1.json
|
||||
repair_attempts: 1
|
||||
@@ -0,0 +1,7 @@
|
||||
Use only the positive integer `candidate_id` values supplied in the candidate material.
|
||||
|
||||
Return a duplicate group only when the evidence supports that every selected candidate describes the same underlying entity. Each group must contain at least two distinct candidate IDs, and its `canonical_candidate_id` must be one of those IDs. A candidate may appear in at most one group.
|
||||
|
||||
Omit uncertain matches and candidates that should remain distinct. Do not invent candidates or infer an ID from list position. An empty `duplicate_groups` array is valid.
|
||||
|
||||
The response must conform exactly to the selected JSON schema. Return IDs only: do not copy candidate names, evidence, transcript text, source identifiers, or source ranges into the response.
|
||||
2
assets/generic/normalize/deduplication/prompts/system.md
Normal file
2
assets/generic/normalize/deduplication/prompts/system.md
Normal file
@@ -0,0 +1,2 @@
|
||||
You reconcile structured records that may describe the same underlying entity.
|
||||
Follow the supplied protocol and return only the requested structured result.
|
||||
@@ -0,0 +1,3 @@
|
||||
Transcript evidence windows:
|
||||
|
||||
{{ input "transcript" }}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.generic.semantic_reconciliation.llm",
|
||||
"title": "notarius_semantic_reconciliation_llm_v1",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["duplicate_groups"],
|
||||
"properties": {
|
||||
"duplicate_groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["candidate_ids", "canonical_candidate_id"],
|
||||
"properties": {
|
||||
"candidate_ids": {
|
||||
"type": "array",
|
||||
"minItems": 2,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"canonical_candidate_id": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
assets/package.go
Normal file
15
assets/package.go
Normal file
@@ -0,0 +1,15 @@
|
||||
// Package assets exposes embedded LLM-facing content.
|
||||
package assets
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
//go:embed dnd generic
|
||||
var embedded embed.FS
|
||||
|
||||
// FS returns the embedded read-only asset filesystem.
|
||||
func FS() fs.FS {
|
||||
return embedded
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# ADR-0004: Package modules by domain, not by stage
|
||||
|
||||
**Status:** Accepted
|
||||
**Status:** Accepted — its asset-co-location rule is superseded by [ADR-0011](0011-centralize-llm-assets.md); its domain-first module packaging decision remains accepted.
|
||||
**Date:** 2026-07-13
|
||||
|
||||
## Context
|
||||
|
||||
49
docs/adr/0010-workload-oriented-llm-profile-defaults.md
Normal file
49
docs/adr/0010-workload-oriented-llm-profile-defaults.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# ADR-0010: Use workload-oriented LLM profile defaults
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-08-03
|
||||
|
||||
## Context
|
||||
|
||||
LLM-backed D&D operations share an execution-policy choice, but repeating a
|
||||
provider or model-named profile on every module binding ties pipeline structure
|
||||
to a deployment decision. Different environments may require different model,
|
||||
backend, timeout, or reasoning settings while retaining the same workload.
|
||||
|
||||
Notarius also needs a usable default for maintained D&D prompts without making
|
||||
an operator profile mandatory. That default must remain owned by the D&D
|
||||
family, while generic LLM infrastructure stays unaware of domain-specific
|
||||
policy.
|
||||
|
||||
## Decision
|
||||
|
||||
Pipelines may name one workload-oriented default profile, inherited only by
|
||||
selected LLM-backed bindings and validators. Binding-level profile IDs remain
|
||||
intentional exceptions, and the run-wide CLI profile override has highest
|
||||
precedence.
|
||||
|
||||
The D&D family owns an embedded fallback profile named `dnd-extraction`.
|
||||
Operators may provide a complete profile with the same ID through a PromptKit
|
||||
filesystem source. PromptKit selects the higher-precedence matching definition;
|
||||
Notarius does not merge profile documents. Production, development, and local
|
||||
deployments can therefore use different execution policy behind one unchanged
|
||||
pipeline ID.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
- Repeat a model-named profile on every binding. This makes routine deployment
|
||||
policy changes noisy and obscures the shared workload intent.
|
||||
- Require every deployment to install a profile file. This adds configuration
|
||||
friction and leaves maintained D&D prompts without an application-owned
|
||||
fallback.
|
||||
- Put D&D profile policy in generic LLM infrastructure. This breaks domain
|
||||
ownership and makes generic code depend on one workload.
|
||||
|
||||
## Consequences
|
||||
|
||||
Pipeline configuration expresses workload intent rather than a specific
|
||||
provider or model. Operators can replace the complete execution policy without
|
||||
editing bindings, while binding-level and run-wide exceptions remain available.
|
||||
Profile changes affect resolved pipeline and checkpoint identity, so they may
|
||||
intentionally cause work to be recomputed. The D&D fallback becomes a
|
||||
maintained application execution-policy asset.
|
||||
69
docs/adr/0011-centralize-llm-assets.md
Normal file
69
docs/adr/0011-centralize-llm-assets.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# ADR-0011: Centralize LLM-facing assets in a content-only package
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-08-05
|
||||
|
||||
## Context
|
||||
|
||||
LLM prompts, private response schemas, generic schemas, and fallback profiles
|
||||
are authored and reviewed as content, but package-local embedding scattered that
|
||||
content across implementation trees. Finding all of the assets that contribute
|
||||
to a prompt family required navigating code ownership boundaries rather than a
|
||||
single discoverable content boundary.
|
||||
|
||||
The repository must retain module ownership of prompt semantics, schema
|
||||
identities, registration, and prompt-cache behavior. Durable artifact schemas
|
||||
and non-LLM domain data have different compatibility and ownership rules, so
|
||||
they must not move merely because they are embedded files.
|
||||
|
||||
## Decision
|
||||
|
||||
LLM-facing content is embedded by the root `assets` package. It is a data-only
|
||||
dependency leaf: its single `FS() fs.FS` API returns the read-only embedded
|
||||
filesystem, and the package contains no business logic or internal or PromptKit
|
||||
dependencies. The accepted import path is
|
||||
`gitea.maximumdirect.net/eric/notarius/assets`; it makes repository-owned
|
||||
content available to its consumers, not a public extension contract.
|
||||
|
||||
Consumers scope that filesystem to the subtree they own before reading or
|
||||
registering content. Modules continue to own their manifests, prompt ordering,
|
||||
private response-schema identity, and registration. Centralizing physical files
|
||||
does not centralize domain semantics or transfer those responsibilities to the
|
||||
root package.
|
||||
|
||||
The root package contains prompt content, private LLM response schemas, generic
|
||||
LLM schemas, shared fragments, and fallback profiles. Durable artifact schemas
|
||||
and non-LLM domain data remain with their current owners. A module fingerprint
|
||||
is derived from its manifest-selected module and shared files, rather than from
|
||||
an entire asset tree. The relocation is accepted to cause a one-time checkpoint
|
||||
invalidation.
|
||||
|
||||
This decision supersedes only the physical asset-co-location portion of
|
||||
ADR-0004's decision that places domain-specific prompt fragments and schemas
|
||||
within the domain tree. ADR-0004's domain-first packaging and registrar
|
||||
ownership decisions remain accepted.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
- Keep package-local assets. This preserves physical co-location with code but
|
||||
makes prompt-author discovery and cross-family review unnecessarily costly.
|
||||
- Use `internal/llmassets`. This would hide content from legitimate owners
|
||||
outside the `internal` subtree and would make the root asset boundary depend
|
||||
on implementation-layer placement.
|
||||
- Build a behavioral central registry. This would mix content discovery with
|
||||
prompt selection and registration behavior, moving module semantics into a
|
||||
shared registry.
|
||||
- Use runtime filesystem overlays. This would add runtime configuration and
|
||||
failure modes where compile-time embedded content is sufficient.
|
||||
|
||||
## Consequences
|
||||
|
||||
Prompt authors can find in-scope LLM content in one top-level tree while module
|
||||
packages continue to define its meaning and registration. Consumers have an
|
||||
explicit, narrow dependency on only the content they need. The root package is
|
||||
intentionally importable but must remain a stable, content-only leaf rather
|
||||
than becoming a general extension API.
|
||||
|
||||
The initial relocation invalidates existing checkpoints once. Later checkpoint
|
||||
identity changes remain limited to the manifest-selected prompt and shared
|
||||
content, so unrelated files do not trigger recomputation.
|
||||
@@ -0,0 +1,64 @@
|
||||
# ADR-0012: Resolve opaque entity identifiers deterministically
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-08-08
|
||||
|
||||
## Context
|
||||
|
||||
Entity IDs in durable Notarius artifacts are application-owned, deterministic
|
||||
identifiers. They are useful to artifact consumers, but their hash-based form
|
||||
does not help a model distinguish entities and would make the model reproduce
|
||||
an opaque implementation detail. A plain name is likewise insufficient where
|
||||
multiple supplied records share that name.
|
||||
|
||||
The LLM boundary must preserve the typed artifact and durable-schema ownership
|
||||
of [ADR-0003](0003-typed-interfaces-with-two-zone-data-model.md) and the distinction
|
||||
between disambiguating references and source evidence in
|
||||
[ADR-0009](0009-minimal-evidence-grounded-extraction-artifacts.md).
|
||||
|
||||
## Decision
|
||||
|
||||
Callers present a model with semantic selections: a canonical name when it is
|
||||
unique in the request, or a contextual descriptor containing the name and
|
||||
source coordinates when that context is needed to distinguish supplied
|
||||
records. The model returns only those supplied selections. The caller resolves
|
||||
each accepted selection against the request-local supplied records and attaches
|
||||
the opaque application ID deterministically.
|
||||
|
||||
Source coordinates are permitted in a selection solely as identity context.
|
||||
They neither establish an occurrence fact nor replace that occurrence's
|
||||
current-transcript evidence. A selector must resolve exactly; unknown,
|
||||
ambiguous, partial, reordered, or otherwise unsafe selections are not mapped.
|
||||
Where an operation requires a complete grounded artifact, that failure rejects
|
||||
the complete artifact rather than accepting a partially mapped result.
|
||||
|
||||
An explicitly scoped request-local short label is permitted only when a
|
||||
contextual descriptor would be impractical and the caller can deterministically
|
||||
map the label within that one request. Such a label is not a durable ID, must
|
||||
not escape the request boundary, and requires a concrete justification in its
|
||||
own module contract.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
- Ask the model to return durable IDs. This exposes opaque implementation
|
||||
state, does not improve semantic disambiguation, and makes model output
|
||||
depend on hash formatting.
|
||||
- Select by name alone. This cannot safely distinguish same-name records.
|
||||
- Make request-local labels durable identifiers. This would turn prompt
|
||||
presentation into a public identity contract and create avoidable migration
|
||||
pressure.
|
||||
- Let the model invent identifiers or resolve ambiguity. This makes identity
|
||||
assignment non-deterministic and weakens validation.
|
||||
|
||||
## Consequences
|
||||
|
||||
Durable integration contracts retain their exact ID/name pairs while models
|
||||
operate on readable contextual selections. Calling modules must own selector
|
||||
construction, exact resolution, ambiguity handling, and conversion into their
|
||||
durable artifact type; PromptKit and its adapter remain transport-only.
|
||||
|
||||
Some ambiguous or invalid proposals are deliberately omitted, retried, or
|
||||
rejected according to the caller's existing failure policy. Internal candidate
|
||||
keys may support deterministic request-local mapping, but they are not
|
||||
model-visible selectors or durable data. This adds local validation work while
|
||||
keeping identity assignment auditable and stable.
|
||||
@@ -0,0 +1,89 @@
|
||||
# ADR-0013: Use request-local candidate handles for semantic reconciliation
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-08-09
|
||||
|
||||
## Context
|
||||
|
||||
Several typed normalize stage modules need semantic reconciliation after
|
||||
deterministic preprocessing: a model can judge whether source-backed candidates
|
||||
refer to the same underlying entity, while application code remains responsible
|
||||
for constructing the normalized artifact. Requiring the model to reproduce a
|
||||
candidate's full contextual selector makes the response larger and introduces
|
||||
avoidable formatting, ordering, and transcription failure modes.
|
||||
|
||||
Reconciliation must preserve the exact typed artifact boundary established by
|
||||
[ADR-0003](0003-typed-interfaces-with-two-zone-data-model.md), the domain-neutral
|
||||
framework and concrete-domain dependency direction established by
|
||||
[ADR-0004](0004-package-modules-by-domain.md), and the distinction in
|
||||
[ADR-0009](0009-minimal-evidence-grounded-extraction-artifacts.md) between source
|
||||
evidence and auxiliary identity context. It also needs a concrete, narrowly
|
||||
scoped application of the request-local-label exception allowed by
|
||||
[ADR-0012](0012-resolve-opaque-entity-identifiers-deterministically.md).
|
||||
|
||||
## Decision
|
||||
|
||||
Semantic reconciliation will be a domain-neutral framework mechanism used by
|
||||
typed normalize stage modules. A consuming artifact family will retain
|
||||
ownership of its typed records, identity rules, consolidation policy, durable
|
||||
IDs, and domain warnings; the framework mechanism will not infer those rules
|
||||
from arbitrary data.
|
||||
|
||||
For each reconciliation request, deterministic code will assign every eligible
|
||||
model-visible candidate a contiguous, one-based integer handle. The model may
|
||||
receive the candidate's contextual label, source references, and bounded source
|
||||
context needed to judge identity, but its structured response will identify
|
||||
candidates only by those supplied handles. A handle is local to one request,
|
||||
does not represent entity identity, and must never enter a durable artifact or
|
||||
be used to derive a durable ID.
|
||||
|
||||
The model will propose duplicate groups and select one supplied member of each
|
||||
group as canonical. Deterministic code will resolve the handles through the
|
||||
retained request mapping, validate the complete proposal, discard unsafe
|
||||
groups, and apply only validated groups through typed domain-owned policy. The
|
||||
model will not synthesize replacement records or directly mutate an artifact.
|
||||
|
||||
Every reconciliation prompt will combine a mandatory framework-owned protocol
|
||||
and safety policy with an explicitly selected semantic policy. The semantic
|
||||
policy may be the conservative generic policy or a domain-owned policy, but it
|
||||
cannot replace the shared response protocol or deterministic safety boundary.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
- Return durable application IDs. Opaque IDs do not help semantic judgment,
|
||||
expose application identity mechanics, and make model output reproduce data
|
||||
that deterministic code already owns.
|
||||
- Return names alone or copied contextual selectors. Names can be ambiguous,
|
||||
while reproducing labels and source ranges adds response complexity and
|
||||
creates mismatches without adding semantic information. Request-local
|
||||
handles preserve exact selection without either failure mode.
|
||||
- Ask the model to return synthesized canonical replacement records. This
|
||||
would transfer typed artifact construction, provenance consolidation, and
|
||||
durable identity policy to a probabilistic boundary.
|
||||
- Reconcile reflection-discovered fields or arbitrary JSON. This would weaken
|
||||
the typed artifact contract and move domain semantics into generic code.
|
||||
- Hide reconciliation inside extraction or another stage. This would obscure
|
||||
stage ownership and create cross-stage behavior outside the fixed pipeline;
|
||||
reconciliation remains explicit normalize-stage behavior.
|
||||
- Let each domain replace the complete prompt protocol. This would duplicate
|
||||
safety mechanics and allow domain policy to bypass the common response and
|
||||
validation contract.
|
||||
|
||||
## Consequences
|
||||
|
||||
Model responses become smaller and easier to validate, while deterministic
|
||||
application code retains authority over identity, provenance, ordering, and
|
||||
typed artifact construction. The framework requires a request-local mapping,
|
||||
bounded context preparation, a private integer response contract, proposal
|
||||
assessment, and shared prompt assets. Each consuming artifact family still
|
||||
requires a typed adapter for its irreducibly domain-specific rules.
|
||||
|
||||
Request-local handles are deliberately unsuitable for persistence, logging as
|
||||
entity identity, checkpoint contracts, or cross-request correlation. Changes
|
||||
to shared protocol and policy assets must participate in the normal prompt,
|
||||
schema, and checkpoint fingerprint mechanisms.
|
||||
|
||||
The shared mechanism and its initial D&D registry consumers are now
|
||||
implemented. Current behavior is documented in
|
||||
[Module Internals](../internal/modules.md#semantic-reconciliation) and
|
||||
[D&D Module Internals](../internal/dnd.md#semantic-registry-reconciliation).
|
||||
59
docs/adr/0014-feedback-aware-validation-retries.md
Normal file
59
docs/adr/0014-feedback-aware-validation-retries.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# ADR-0014: Use feedback-aware validation retries
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-08-26
|
||||
|
||||
## Context
|
||||
|
||||
Validation can identify a candidate defect after a producer has returned an
|
||||
otherwise well-formed result. Retrying without the validator's deterministic,
|
||||
bounded feedback wastes the useful diagnosis, while treating validator
|
||||
execution failures as defects would ask a producer to repair conditions it
|
||||
cannot control. The mechanism must preserve typed producer ownership,
|
||||
checkpoint safety, and the repository's sensitive-data boundaries.
|
||||
|
||||
## Decision
|
||||
|
||||
The implementation will keep three independent budgets: the producer binding's
|
||||
outer `retries` budget, PromptKit's structured-output repair budget, and each
|
||||
validator's execution-retry budget. Validators will run sequentially in their
|
||||
configured order and aggregate both rejections and execution failures before a
|
||||
candidate disposition is selected.
|
||||
|
||||
A correction-capable producer will provide the exact single LLM response that
|
||||
controlled its candidate using the `single_response_v1` protocol. A correction
|
||||
attempt will reconstruct the ordinary request and append exactly two fresh
|
||||
messages: that latest response as `assistant`, followed by one deterministic
|
||||
aggregate correction request as `user`. Earlier turns will not accumulate.
|
||||
|
||||
Validator failures will not recurse into correction. Pipeline policy owns
|
||||
terminal disposition, with field-by-field producer overrides over pipeline
|
||||
defaults: structural failure and semantic rejection default to `fail_run`, and
|
||||
validator execution failure defaults to `warn_continue`. Validators can report
|
||||
facts and bounded corrective guidance, but never decide disposition.
|
||||
|
||||
Rejected and structurally invalid candidates will not advance. A candidate
|
||||
allowed through after a validator execution failure will retain explicit
|
||||
incomplete-validation provenance and will not be checkpointed. Exact response
|
||||
and correction text remain attempt-local: they are excluded from ordinary
|
||||
errors, warnings, manifests, receipts, caches, checkpoints, and default debug
|
||||
summaries.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
- Retry every producer after any validation outcome. This conflates producer
|
||||
defects with validator operational failures and wastes retry budget.
|
||||
- Let validators decide whether to continue. This would distribute pipeline
|
||||
disposition policy across validators and undermine consistent defaults.
|
||||
- Reuse the full prior conversation. Accumulated turns introduce unbounded
|
||||
prompt growth and make correction behavior depend on incidental history.
|
||||
- Persist raw responses to simplify diagnosis. Raw model output and correction
|
||||
guidance may be sensitive and do not belong in durable pipeline records.
|
||||
|
||||
## Consequences
|
||||
|
||||
The framework gains transport-neutral correction and candidate contracts,
|
||||
producer capability checks, policy resolution, aggregated validation outcomes,
|
||||
and conservative checkpoint handling. Prompt construction remains inside the
|
||||
LLM adapter, while modules remain responsible for accurately exposing the
|
||||
single response that directly controlled a candidate.
|
||||
39
docs/cli.md
39
docs/cli.md
@@ -10,6 +10,7 @@ defined in [Operations](operations.md).
|
||||
|
||||
~~~
|
||||
notarius help
|
||||
notarius --version
|
||||
notarius run <pipeline-id> --input path/to/source.json [--json] [flags]
|
||||
notarius config validate [--config path/to/config.yml] [--pipeline pipeline-id] [--only lane-a,lane-b]
|
||||
notarius pipelines list [--config path/to/config.yml] [--json]
|
||||
@@ -18,6 +19,17 @@ notarius pipelines list [--config path/to/config.yml] [--json]
|
||||
Running Notarius without arguments, or with **help**, **--help**, or **-h**,
|
||||
writes the command summary to standard output and exits with status 0.
|
||||
|
||||
`notarius --version` is valid only as the sole root argument. It writes exactly
|
||||
`notarius <version>` followed by a newline to standard output and exits with
|
||||
status 0. A tagged `go install` build can report its main-module stable tag,
|
||||
and controlled builds can inject a stable tag at link time through
|
||||
`gitea.maximumdirect.net/eric/notarius/internal/buildinfo.Override`; an ordinary
|
||||
unversioned checkout reports `development`. Invalid injected version content is
|
||||
a runtime error with exit status 1, while extra `--version` arguments are a
|
||||
syntax error with exit status 2. This diagnostic does not replace the
|
||||
[run-result](integrations/run-result.md) or artifact contracts for downstream
|
||||
compatibility decisions.
|
||||
|
||||
## run
|
||||
|
||||
~~~
|
||||
@@ -39,16 +51,33 @@ pipeline ID and **--input** are required.
|
||||
| **--debug** | Retain a debug bundle for this run. |
|
||||
| **--debug-dir path** | Override the debug-bundle root. Requires **--debug**. |
|
||||
| **--only lane-a,lane-b** | Run only the selected comma-separated artifact lanes when that selection is valid for the configured pipeline. |
|
||||
| **--llm-profile id** | Override effective LLM-capable module bindings with one configured profile. |
|
||||
| **--session-id id** | Supply a non-empty prompt session identifier to LLM-backed module calls. |
|
||||
| **--llm-profile id** | Highest-precedence configured profile for selected LLM-backed bindings and validators; it replaces binding and [pipeline](config.md#pipelines) defaults. |
|
||||
| **--session-id id** | Override the generated prompt session identifier with a non-empty value for LLM-backed module calls. |
|
||||
| **--reasoning-effort value** | Replace the selected PromptKit profile's reasoning effort for every LLM-backed call in this run. The value must be non-empty and the flag may be specified only once. |
|
||||
| **--clear-reasoning-effort** | Clear reasoning effort inherited from the selected PromptKit profile for every LLM-backed call in this run. |
|
||||
| **--reference selector=path** | Add or replace a file reference binding. Repeatable. |
|
||||
| **--without-reference selector** | Remove a configured optional reference binding. Repeatable. |
|
||||
|
||||
**--chunk_cache** accepts only **auto**, **bypass**, or **refresh**.
|
||||
**--debug-dir**, **--output-dir**, **--session-id**, and
|
||||
**--recompute-step** reject explicit empty values. **--recompute-step**
|
||||
requires **--resume**; checkpoint requirements and reuse behavior are
|
||||
documented in [Operations](operations.md).
|
||||
**--reasoning-effort**, and **--recompute-step** reject explicit empty values.
|
||||
**--reasoning-effort** and **--clear-reasoning-effort** are mutually exclusive.
|
||||
When neither is present, reasoning effort comes from the selected PromptKit
|
||||
profile. These controls apply to the shared run client, including retries and
|
||||
LLM-backed validators, and do not modify configuration or profile files.
|
||||
Persistent reasoning settings remain a PromptKit profile concern.
|
||||
**--recompute-step** requires **--resume**; checkpoint requirements and reuse
|
||||
behavior are documented in [Operations](operations.md).
|
||||
|
||||
Every run uses one effective prompt session. Without **--session-id**, Notarius
|
||||
generates a stable `notarius:v1:` identifier from the trimmed resolved input
|
||||
module key and the input file's exact raw bytes. The same module and bytes
|
||||
therefore produce the same identifier, regardless of pipeline, references,
|
||||
profile, retries, or run settings. An explicit non-empty value replaces that
|
||||
default. Session identifiers are visible to providers; they are non-secret
|
||||
correlation identifiers, not credential storage. See
|
||||
[Operations](operations.md#operational-limits) for privacy and workflow
|
||||
guidance.
|
||||
|
||||
### Reference selectors
|
||||
|
||||
|
||||
260
docs/config.md
260
docs/config.md
@@ -1,7 +1,7 @@
|
||||
# Configuration
|
||||
|
||||
This is the canonical reference for Notarius configuration. Configuration files
|
||||
are YAML and must declare version 3. They select pipelines and their modules;
|
||||
are YAML and must declare version 4. They select pipelines and their modules;
|
||||
the [CLI reference](cli.md) owns invocation syntax, and
|
||||
[Operations](operations.md) owns run-state procedures.
|
||||
|
||||
@@ -32,7 +32,8 @@ override the fields listed below.
|
||||
single-lane Seriatim-to-spell pipeline.
|
||||
- [Complete D&D configuration](../examples/dnd-complete.config.yml) uses
|
||||
ordered steps, all implemented D&D lanes, generated references, state
|
||||
settings, and bounded LLM concurrency.
|
||||
settings, bounded LLM concurrency, and the maintained
|
||||
[operator profile](../examples/profiles/dnd-extraction.yml).
|
||||
|
||||
Use these complete files as starting points rather than combining the
|
||||
illustrative fragments in this reference.
|
||||
@@ -45,8 +46,8 @@ other than **version** is optional.
|
||||
|
||||
| Field | Type | Default | Rules |
|
||||
| --- | --- | --- | --- |
|
||||
| **version** | integer | none | Required; must be 3. |
|
||||
| **scriptorium** | object | none | Profile source configuration. |
|
||||
| **version** | integer | none | Required; must be 4. |
|
||||
| **promptkit** | object | none | Profile source and optional local-backend configuration. |
|
||||
| **pipelines** | map | empty | Maps pipeline IDs to pipeline definitions. |
|
||||
| **concurrency** | object | see below | Global LLM and extraction limits. |
|
||||
| **output** | object | see below | Published output settings. |
|
||||
@@ -57,7 +58,7 @@ Built-in defaults are:
|
||||
|
||||
| Field | Default |
|
||||
| --- | --- |
|
||||
| **concurrency.total_llm** | 1 |
|
||||
| **concurrency.total_llm** | 16 |
|
||||
| **concurrency.stage_workers.extract** | Effective **total_llm** |
|
||||
| **output.directory** | **./notarius-output** |
|
||||
| **cache.chunk_plans.mode** | **auto** |
|
||||
@@ -69,20 +70,89 @@ Built-in defaults are:
|
||||
An empty cache directory in YAML deliberately selects the corresponding
|
||||
per-user root. An explicit empty output or debug directory is invalid.
|
||||
|
||||
## Scriptorium Profiles
|
||||
## PromptKit Profiles
|
||||
|
||||
The optional **scriptorium** object selects one source of profile definitions:
|
||||
The optional **promptkit** object selects one source of profile definitions and
|
||||
may register one conventional local OpenAI-compatible backend:
|
||||
|
||||
~~~yaml
|
||||
version: 4
|
||||
|
||||
promptkit:
|
||||
profile_dir: ./profiles
|
||||
# profile_file: ./profiles.yml
|
||||
local_backend:
|
||||
endpoint: http://localhost:8000/v1
|
||||
concurrency_limit: 2
|
||||
~~~
|
||||
|
||||
| Field | Type | Rules |
|
||||
| --- | --- | --- |
|
||||
| **profile_dir** | string | Non-empty directory containing profile files. |
|
||||
| **profile_file** | string | Non-empty profile file. |
|
||||
| **local_backend** | object | Optional registration for the conventional PromptKit backend ID **local**. |
|
||||
| **local_backend.endpoint** | string | Required when **local_backend** is present; absolute HTTP or HTTPS URL with a host. |
|
||||
| **local_backend.concurrency_limit** | integer | Optional non-negative limit; defaults to 0. |
|
||||
|
||||
Set at most one of these fields. Profile IDs used by a binding must be available
|
||||
from the selected Scriptorium profile source when the pipeline is resolved.
|
||||
Keep credentials out of this file: configure a profile to read its credential
|
||||
from an environment variable, then set that environment variable only in the
|
||||
run environment.
|
||||
Set at most one of **profile_dir** and **profile_file**. Relative values use
|
||||
the process working directory, not the configuration file's directory. The
|
||||
complete example's `./examples/profiles/dnd-extraction.yml` value is therefore
|
||||
valid when Notarius is launched from the repository root; use an absolute path
|
||||
for services and containers.
|
||||
|
||||
An operator source is optional. For a requested ID, PromptKit checks the
|
||||
configured operator source first, then Notarius's embedded fallback profiles,
|
||||
then its own built-in catalog. A matching profile is complete: it replaces a
|
||||
lower-precedence definition rather than merging with it. The maintained
|
||||
[`dnd-extraction` operator profile](../examples/profiles/dnd-extraction.yml)
|
||||
is a secret-free deployment artifact; production, development, and local
|
||||
deployments can each provide a complete definition with that same workload ID.
|
||||
Use workload-oriented IDs for new profiles instead of model names.
|
||||
[Operations](operations.md#promptkit-profile-deployment) owns the deployment
|
||||
workflow and credential-handling guidance.
|
||||
|
||||
When **local_backend** is present, its endpoint is trimmed and must use HTTP or
|
||||
HTTPS case-insensitively, be absolute, and have a non-empty host. URL paths are
|
||||
allowed. User information, queries, and fragments are rejected. A zero
|
||||
**concurrency_limit** leaves the local backend unrestricted inside PromptKit;
|
||||
a positive value limits simultaneous local generations. The application-wide
|
||||
**concurrency.total_llm** limit still applies in both cases. Neither local
|
||||
backend field has an environment override. Omitting **local_backend** registers
|
||||
nothing and preserves existing built-in and endpoint-only profile behavior.
|
||||
|
||||
A file-backed PromptKit profile selects the registration by its case-sensitive
|
||||
backend ID:
|
||||
|
||||
~~~yaml
|
||||
id: local-summary
|
||||
backend: local
|
||||
model: example-model
|
||||
~~~
|
||||
|
||||
Keep credentials out of the local-backend object. A PromptKit profile may name
|
||||
its credential environment variable through `api_key_env`; set that variable
|
||||
only in the run environment. PromptKit owns the
|
||||
[pinned profile-file format](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md),
|
||||
including `base_profile` inheritance. Notarius passes profiles through without
|
||||
merging them. Filesystem profiles cannot express PromptKit's in-memory
|
||||
`APIKeyRequired` setting; an unset `api_key_env` is optional and may reach the
|
||||
provider without authorization.
|
||||
The [PromptKit upstream boundary](integrations/pkg-promptkit.md) identifies the
|
||||
supported package API, and [Operations](operations.md#operational-limits)
|
||||
describes the effective concurrency layers.
|
||||
|
||||
`notarius config validate --pipeline <id>` resolves the selected pipeline and
|
||||
inspects every explicit effective profile without contacting a provider or
|
||||
requiring credential values. It rejects absent, malformed, or incompatible
|
||||
profiles before a run prepares modules. Credential availability is checked only
|
||||
when a generation is prepared.
|
||||
|
||||
## Migrating Version 3 Configuration
|
||||
|
||||
Version 3 files are not decoded or rewritten. Change **version: 3** to
|
||||
**version: 4** and rename the top-level **scriptorium:** section to
|
||||
**promptkit:**. Version 4 decoding is strict, so a remaining **scriptorium**
|
||||
field is rejected as unknown.
|
||||
|
||||
## Operational Environment Variables
|
||||
|
||||
@@ -138,6 +208,7 @@ Each **pipelines** entry has a unique, non-empty ID and the following shape:
|
||||
~~~yaml
|
||||
pipelines:
|
||||
dnd-session:
|
||||
llm_profile: dnd-extraction
|
||||
input: seriatim
|
||||
chunk: generic
|
||||
output: json
|
||||
@@ -150,6 +221,9 @@ pipelines:
|
||||
|
||||
| Field | Type | Default | Rules |
|
||||
| --- | --- | --- | --- |
|
||||
| **llm_profile** | string | none | Optional non-empty default PromptKit profile ID for selected LLM-backed bindings and validators. An explicitly present blank value is invalid. |
|
||||
| **structured_output_repair_attempts** | integer | prompt-owned (1 in maintained production prompts) | Optional structural-repair limit from 0 through 3 for selected LLM-backed bindings and validators. Omission leaves the prompt's declared policy in control; explicit 0 disables structural repair at that scope. |
|
||||
| **validation_policy** | object | see below | Optional terminal policy defaults for producer validation. Its fields inherit independently into chunk, extract, merge, and normalize bindings. |
|
||||
| **input** | module binding | none | Required. |
|
||||
| **chunk** | module binding | **generic** | Optional. |
|
||||
| **output** | module binding | **json** | Optional. |
|
||||
@@ -163,6 +237,48 @@ needs a unique non-empty **id**, an **artifacts** map, and may have
|
||||
**references**. A lane ID must not appear more than once in a pipeline,
|
||||
including across explicit steps.
|
||||
|
||||
For each selected LLM-backed binding or validator, profile selection occurs
|
||||
after module, validator, and `--only` lane selection. It uses the
|
||||
run-level **--llm-profile** value first, then the binding's **llm_profile**,
|
||||
then the pipeline's **llm_profile**, and finally the PromptKit default.
|
||||
Deterministic bindings do not receive these defaults or run overrides.
|
||||
|
||||
Structural output repair is resolved after module, validator, and `--only` lane
|
||||
selection. An object's **structured_output_repair_attempts** value takes
|
||||
precedence over the pipeline value; otherwise, an LLM-backed binding or
|
||||
validator inherits the pipeline value. If both are omitted, PromptKit uses the
|
||||
prompt's declared repair policy. The value must be an integer from 0 through 3;
|
||||
explicit `null` and non-integer values are invalid. An explicit value on a
|
||||
deterministic binding or validator is invalid, while a pipeline value simply
|
||||
does not apply to deterministic selections.
|
||||
|
||||
`validation_policy` controls terminal disposition for one complete producer
|
||||
attempt and validator chain. It may appear on a pipeline or a **chunk**,
|
||||
**extract**, **merge**, or **normalize** module binding; input, output, and
|
||||
validator bindings reject it. Every field is optional and resolves in binding,
|
||||
pipeline, then application-default order:
|
||||
|
||||
| Field | Values | Default |
|
||||
| --- | --- | --- |
|
||||
| **producer_structural_failure** | **fail_run**, **reject_output** | **fail_run** |
|
||||
| **semantic_rejection** | **fail_run**, **reject_output** | **fail_run** |
|
||||
| **validator_failure** | **warn_continue**, **fail_run** | **warn_continue** |
|
||||
|
||||
The policy object and its fields must be non-null, and unknown fields are
|
||||
rejected. A deterministic producer may not explicitly set
|
||||
**producer_structural_failure** on its binding, although a pipeline-level
|
||||
default remains valid for pipelines that include LLM-backed producers.
|
||||
|
||||
After the producer binding's retry budget is exhausted, an invalid structured
|
||||
response uses **producer_structural_failure**. One or more semantic validator
|
||||
rejections use **semantic_rejection**; rejection takes precedence over an
|
||||
exhausted validator failure or skip. With no rejection, an exhausted validator
|
||||
failure or skip uses **validator_failure**. `reject_output` records the
|
||||
terminal rejection without advancing that candidate. `warn_continue` is valid
|
||||
only for validator execution failure: it advances a structurally valid,
|
||||
otherwise unrejected result with incomplete-validation provenance and without
|
||||
making it reusable checkpoint state.
|
||||
|
||||
A lane has these fields:
|
||||
|
||||
| Field | Type | Default | Rules |
|
||||
@@ -190,7 +306,7 @@ Use an object for fields:
|
||||
~~~yaml
|
||||
extract:
|
||||
module: dnd/spells
|
||||
llm_profile: gemini-2-flash
|
||||
llm_profile: dnd-extraction
|
||||
retries: 2
|
||||
references:
|
||||
spell_catalog: ./dnd-spell-catalog.json
|
||||
@@ -199,17 +315,33 @@ extract:
|
||||
| Binding field | Type | Default | Rules |
|
||||
| --- | --- | --- | --- |
|
||||
| **module** | string | none | Required for an object binding. Must be a registered compatible key. |
|
||||
| **llm_profile** | string | none | Optional non-empty Scriptorium profile ID. |
|
||||
| **retries** | integer | 0 | Non-negative additional attempts for chunk, extract, merge, and normalize bindings. |
|
||||
| **llm_profile** | string | none | Optional non-empty PromptKit profile ID for an LLM-backed binding. It overrides the pipeline default unless the run supplies **--llm-profile**. |
|
||||
| **structured_output_repair_attempts** | integer | pipeline or prompt-owned (1 in maintained production prompts) | Optional structural-repair limit from 0 through 3 for an LLM-backed binding. It overrides the pipeline value; explicit 0 disables structural repair. |
|
||||
| **validation_policy** | object | pipeline or application defaults | Optional field-by-field terminal-policy override for a chunk, extract, merge, or normalize binding. |
|
||||
| **retries** | integer | 0 | Non-negative additional complete producer attempts for chunk, extract, merge, and normalize bindings. This single budget covers operational errors, invalid structured output, module-requested normalization retry, and semantic correction. |
|
||||
| **options** | object | none | Must satisfy the selected module. |
|
||||
| **references** | map | none | Valid only on chunk, extract, merge, and normalize bindings. |
|
||||
| **validators** | list | production chain | Valid only on chunk, extract, merge, and normalize bindings. |
|
||||
|
||||
Omitting **validators** uses the registered chain. **validators: []** selects
|
||||
an empty chain; a non-empty list replaces the chain in the listed order.
|
||||
Validator bindings accept only **module**, **llm_profile**, and **options**.
|
||||
They reject **references**, **retries**, and nested **validators**. Deterministic
|
||||
validators reject an explicit **llm_profile**.
|
||||
Validator bindings accept only **module**, **llm_profile**,
|
||||
**structured_output_repair_attempts**, **retries**, and **options**. Their
|
||||
**retries** value is a non-negative additional validator-execution budget and
|
||||
is valid only when the selected validator is LLM-backed. A validator retry
|
||||
rechecks the same immutable candidate; it never regenerates the producer.
|
||||
They reject
|
||||
**validation_policy**, **references**, and nested **validators**. Deterministic
|
||||
validators reject explicit **llm_profile** and
|
||||
**structured_output_repair_attempts**.
|
||||
Deterministic module bindings also reject those explicit fields.
|
||||
|
||||
An LLM-backed chunk, extract, merge, or normalize producer with both a
|
||||
non-empty validator chain and positive **retries** must declare the supported
|
||||
single-response correction capability. Preparation rejects a configuration
|
||||
that could require semantic correction from a producer that cannot provide an
|
||||
exact prior response. A deterministic producer, or an LLM attempt that did
|
||||
not make a model call, cannot consume a semantic retry after rejection.
|
||||
|
||||
The **json** output module accepts optional **include_chunk_map** and
|
||||
**evidence_context** settings:
|
||||
@@ -223,7 +355,7 @@ output:
|
||||
enabled: true
|
||||
window_units: 3
|
||||
lanes:
|
||||
- npcs
|
||||
- npc-registry
|
||||
- spells
|
||||
~~~
|
||||
|
||||
@@ -244,7 +376,8 @@ Unknown outer or nested option fields are rejected, as are incompatible YAML
|
||||
types. The allowlist remains valid when a run uses lane filtering: a configured
|
||||
lane that is not active for that invocation simply contributes no evidence.
|
||||
Evidence publication is opt-in because it can persist source text and metadata.
|
||||
Its payload contract is [Published Evidence Context](integrations/evidence-context.md).
|
||||
When enabled, it publishes the selected source-unit excerpt defined by the
|
||||
[Published Evidence Context contract](integrations/evidence-context.md).
|
||||
|
||||
## References And Ordered Handoffs
|
||||
|
||||
@@ -257,15 +390,15 @@ step:
|
||||
steps:
|
||||
- id: describe-session
|
||||
artifacts:
|
||||
npcs:
|
||||
extract: dnd/npcs
|
||||
normalize: dnd/npcs
|
||||
npc-registry:
|
||||
extract: dnd/npc-registry
|
||||
normalize: dnd/npc-registry
|
||||
- id: extract-events
|
||||
references:
|
||||
npcs:
|
||||
npc_registry:
|
||||
artifact:
|
||||
step: describe-session
|
||||
lane: npcs
|
||||
lane: npc-registry
|
||||
artifacts:
|
||||
spells:
|
||||
extract: dnd/spells
|
||||
@@ -295,14 +428,38 @@ selected target declares them:
|
||||
| **players** | Optional text player context. |
|
||||
| **glossary** | Optional text campaign glossary. |
|
||||
| **spell_catalog** | Optional JSON spell-catalog overlay for spell extraction and normalization. See [spell-catalog overlays](integrations/dnd-spell-catalog-overlays.md). |
|
||||
| **npcs** | Normalized NPC registry. Optional for spells and combat turns; required for NPC interactions. |
|
||||
| **scene_descriptions** | Required normalized scene-description artifact for combat-turn extraction. |
|
||||
| **location_registry** | Required normalized location registry for location-occurrence extraction and normalization. |
|
||||
| **item_registry** | Required normalized item registry for item-occurrence extraction and normalization. |
|
||||
| **npc_registry** | Normalized NPC registry. Optional for spells and combat turns; required for NPC occurrences and enemy-event extraction and normalization. |
|
||||
| **scene_descriptions** | Required normalized scene-description artifact for combat-turn and enemy-event extraction. |
|
||||
| **combat_turns** | Required normalized combat-turn artifact for enemy-event extraction. |
|
||||
| **npc_occurrences** | Required normalized NPC-occurrence artifact for enemy-event extraction. |
|
||||
|
||||
Registry-backed occurrence and enemy-event artifact slots have the following
|
||||
exact binding contracts. Durable semantics and wire shapes remain in their
|
||||
[NPC occurrence](integrations/dnd-npc-occurrence-artifacts.md),
|
||||
[location occurrence](integrations/dnd-location-occurrence-artifacts.md),
|
||||
[item occurrence](integrations/dnd-item-occurrence-artifacts.md), and
|
||||
[enemy-event](integrations/dnd-enemy-event-artifacts.md) contracts.
|
||||
|
||||
| Slot | Accepted artifact kind | Media type | Maximum size | Required stage |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `npc_registry` | `dnd/npc-registry` | `application/json` | 1,048,576 bytes | extract and normalize |
|
||||
| `scene_descriptions` | `dnd/scene-description-list` | `application/json` | 1,048,576 bytes | extract only |
|
||||
| `combat_turns` | `dnd/combat-turn-list` | `application/json` | 1,048,576 bytes | extract only |
|
||||
| `npc_occurrences` | `dnd/npc-occurrence-list` | `application/json` | 1,048,576 bytes | extract only |
|
||||
| `location_registry` | `dnd/location-registry` | `application/json` | 1,048,576 bytes | location-occurrence extract and normalize |
|
||||
| `item_registry` | `dnd/item-registry` | `application/json` | 1,048,576 bytes | item-occurrence extract and normalize |
|
||||
|
||||
Scene descriptions accept **party**, **players**, and **glossary**, but not
|
||||
**roster**. NPC interactions require **npcs** for both extraction and
|
||||
**roster**. NPC occurrences require **npc_registry** for both extraction and
|
||||
normalization. Combat turns require **scene_descriptions** for extraction; the
|
||||
normalized combat-turn module may use optional **npcs**. The complete example
|
||||
shows generated **npcs** and **scene_descriptions** bindings.
|
||||
normalized combat-turn module may use optional **npc_registry**. Location occurrences
|
||||
require **location_registry** for extraction and normalization. Item occurrences require
|
||||
**item_registry** for extraction and normalization. Enemy-event extraction requires all
|
||||
four of its JSON artifact slots; its normalizer requires **npc_registry**.
|
||||
The [complete example](../examples/dnd-complete.config.yml) shows the ordered
|
||||
generated bindings.
|
||||
|
||||
## Production Module Keys
|
||||
|
||||
@@ -310,18 +467,29 @@ shows generated **npcs** and **scene_descriptions** bindings.
|
||||
| --- | --- |
|
||||
| Input | **seriatim** |
|
||||
| Chunk | **generic**, **dnd/scenes** |
|
||||
| Extract | **dnd/spells**, **dnd/npcs**, **dnd/combat-turns**, **dnd/item-events**, **dnd/npc-interactions**, **dnd/scene-descriptions** |
|
||||
| Extract | **dnd/spells**, **dnd/npc-registry**, **dnd/combat-turns**, **dnd/item-occurrences**, **dnd/item-registry**, **dnd/npc-occurrences**, **dnd/scene-descriptions**, **dnd/enemy-events**, **dnd/location-registry**, **dnd/location-occurrences** |
|
||||
| Merge | **appendorder** |
|
||||
| Normalize | **noop**, **dnd/spells**, **dnd/npcs**, **dnd/combat-turns**, **dnd/item-events**, **dnd/npc-interactions**, **dnd/scene-descriptions** |
|
||||
| Normalize | **noop**, **dnd/spells**, **dnd/npc-registry**, **dnd/combat-turns**, **dnd/item-occurrences**, **dnd/item-registry**, **dnd/npc-occurrences**, **dnd/scene-descriptions**, **dnd/enemy-events**, **dnd/location-registry**, **dnd/location-occurrences** |
|
||||
| Output | **json** |
|
||||
|
||||
`dnd/scenes` and every D&D extractor are `llm_backed`. The
|
||||
`dnd/npc-registry`, `dnd/location-registry`, and `dnd/item-registry`
|
||||
normalizers are also `llm_backed` for bounded duplicate proposals; every other
|
||||
D&D normalizer is `deterministic`. LLM-backed bindings use the effective
|
||||
[PromptKit profile](#promptkit-profiles). The complete example binds each
|
||||
registry in an earlier step before its occurrence consumer.
|
||||
|
||||
The D&D artifact contracts define each emitted schema:
|
||||
[spells](integrations/dnd-spell-artifacts.md),
|
||||
[NPCs](integrations/dnd-npc-artifacts.md),
|
||||
[NPC interactions](integrations/dnd-npc-interaction-artifacts.md),
|
||||
[NPC registry](integrations/dnd-npc-registry-artifacts.md),
|
||||
[NPC occurrences](integrations/dnd-npc-occurrence-artifacts.md),
|
||||
[combat turns](integrations/dnd-combat-turn-artifacts.md),
|
||||
[item events](integrations/dnd-item-event-artifacts.md), and
|
||||
[scene descriptions](integrations/dnd-scene-description-artifacts.md).
|
||||
[item registry](integrations/dnd-item-registry-artifacts.md),
|
||||
[item occurrences](integrations/dnd-item-occurrence-artifacts.md),
|
||||
[scene descriptions](integrations/dnd-scene-description-artifacts.md),
|
||||
[enemy events](integrations/dnd-enemy-event-artifacts.md),
|
||||
[location registry](integrations/dnd-location-registry-artifacts.md), and
|
||||
[location occurrences](integrations/dnd-location-occurrence-artifacts.md).
|
||||
|
||||
## Production Validator Keys And Default Chains
|
||||
|
||||
@@ -331,11 +499,15 @@ Available validator keys are:
|
||||
| --- | --- |
|
||||
| Generic | **generic/always_accept**, **generic/always_reject**, **generic/valid_json**, **generic/valid_json_schema** |
|
||||
| Spells | **extract/dnd/spells/shape**, **extract/dnd/spells/catalog**, **extract/dnd/spells/source_refs**, **extract/dnd/spells/source_relatedness** |
|
||||
| NPCs | **extract/dnd/npcs/shape**, **extract/dnd/npcs/source_refs**, **extract/dnd/npcs/source_relatedness**, **normalize/dnd/npcs/identity** |
|
||||
| NPC registry | **extract/dnd/npc-registry/shape**, **extract/dnd/npc-registry/source_refs**, **extract/dnd/npc-registry/source_relatedness**, **normalize/dnd/npc-registry/identity** |
|
||||
| Combat turns | **extract/dnd/combat-turns/shape**, **extract/dnd/combat-turns/source_refs**, **extract/dnd/combat-turns/source_relatedness**, **normalize/dnd/combat-turns/invariants** |
|
||||
| Item events | **extract/dnd/item-events/shape**, **extract/dnd/item-events/source_refs**, **extract/dnd/item-events/source_relatedness**, **normalize/dnd/item-events/invariants** |
|
||||
| NPC interactions | **extract/dnd/npc-interactions/shape**, **extract/dnd/npc-interactions/registry**, **extract/dnd/npc-interactions/source_refs**, **extract/dnd/npc-interactions/source_relatedness**, **normalize/dnd/npc-interactions/invariants** |
|
||||
| Item occurrences | **extract/dnd/item-occurrences/shape**, **extract/dnd/item-occurrences/registry**, **extract/dnd/item-occurrences/source_refs**, **extract/dnd/item-occurrences/source_relatedness**, **normalize/dnd/item-occurrences/invariants** |
|
||||
| Item registry | **extract/dnd/item-registry/shape**, **extract/dnd/item-registry/source_refs**, **extract/dnd/item-registry/source_relatedness**, **normalize/dnd/item-registry/identity** |
|
||||
| NPC occurrences | **extract/dnd/npc-occurrences/shape**, **extract/dnd/npc-occurrences/registry**, **extract/dnd/npc-occurrences/source_refs**, **extract/dnd/npc-occurrences/source_relatedness**, **normalize/dnd/npc-occurrences/invariants** |
|
||||
| Scene descriptions | **extract/dnd/scene-descriptions/shape**, **extract/dnd/scene-descriptions/source_refs**, **extract/dnd/scene-descriptions/source_relatedness**, **normalize/dnd/scene-descriptions/invariants** |
|
||||
| Enemy events | **extract/dnd/enemy-events/shape**, **extract/dnd/enemy-events/engagements**, **extract/dnd/enemy-events/source_refs**, **extract/dnd/enemy-events/source_relatedness**, **normalize/dnd/enemy-events/invariants** |
|
||||
| Location registry | **extract/dnd/location-registry/shape**, **extract/dnd/location-registry/source_refs**, **extract/dnd/location-registry/source_relatedness**, **normalize/dnd/location-registry/identity** |
|
||||
| Location occurrences | **extract/dnd/location-occurrences/shape**, **extract/dnd/location-occurrences/registry**, **extract/dnd/location-occurrences/source_refs**, **extract/dnd/location-occurrences/source_relatedness**, **normalize/dnd/location-occurrences/invariants** |
|
||||
|
||||
When no override is configured, production D&D bindings use the following
|
||||
ordered chains. Each row lists extract then normalize; spell chains are the
|
||||
@@ -344,11 +516,15 @@ same at both stages.
|
||||
| Lane | Extract | Normalize |
|
||||
| --- | --- | --- |
|
||||
| Spells | generic/valid_json, extract/dnd/spells/shape, extract/dnd/spells/catalog, extract/dnd/spells/source_refs, generic/valid_json_schema, extract/dnd/spells/source_relatedness | Same as extract |
|
||||
| NPCs | generic/valid_json, extract/dnd/npcs/shape, extract/dnd/npcs/source_refs, generic/valid_json_schema, extract/dnd/npcs/source_relatedness | generic/valid_json, extract/dnd/npcs/shape, normalize/dnd/npcs/identity, extract/dnd/npcs/source_refs, generic/valid_json_schema, extract/dnd/npcs/source_relatedness |
|
||||
| NPC registry | generic/valid_json, extract/dnd/npc-registry/shape, extract/dnd/npc-registry/source_refs, generic/valid_json_schema, extract/dnd/npc-registry/source_relatedness | generic/valid_json, extract/dnd/npc-registry/shape, normalize/dnd/npc-registry/identity, extract/dnd/npc-registry/source_refs, generic/valid_json_schema, extract/dnd/npc-registry/source_relatedness |
|
||||
| Combat turns | generic/valid_json, extract/dnd/combat-turns/shape, extract/dnd/combat-turns/source_refs, generic/valid_json_schema, extract/dnd/combat-turns/source_relatedness | generic/valid_json, extract/dnd/combat-turns/shape, normalize/dnd/combat-turns/invariants, extract/dnd/combat-turns/source_refs, generic/valid_json_schema, extract/dnd/combat-turns/source_relatedness |
|
||||
| Item events | generic/valid_json, extract/dnd/item-events/shape, extract/dnd/item-events/source_refs, generic/valid_json_schema, extract/dnd/item-events/source_relatedness | generic/valid_json, extract/dnd/item-events/shape, normalize/dnd/item-events/invariants, extract/dnd/item-events/source_refs, generic/valid_json_schema, extract/dnd/item-events/source_relatedness |
|
||||
| NPC interactions | generic/valid_json, extract/dnd/npc-interactions/shape, extract/dnd/npc-interactions/registry, extract/dnd/npc-interactions/source_refs, generic/valid_json_schema, extract/dnd/npc-interactions/source_relatedness | generic/valid_json, extract/dnd/npc-interactions/shape, extract/dnd/npc-interactions/registry, normalize/dnd/npc-interactions/invariants, extract/dnd/npc-interactions/source_refs, generic/valid_json_schema, extract/dnd/npc-interactions/source_relatedness |
|
||||
| Item occurrences | generic/valid_json, extract/dnd/item-occurrences/shape, extract/dnd/item-occurrences/registry, extract/dnd/item-occurrences/source_refs, generic/valid_json_schema, extract/dnd/item-occurrences/source_relatedness | generic/valid_json, extract/dnd/item-occurrences/shape, extract/dnd/item-occurrences/registry, normalize/dnd/item-occurrences/invariants, extract/dnd/item-occurrences/source_refs, generic/valid_json_schema, extract/dnd/item-occurrences/source_relatedness |
|
||||
| Item registry | generic/valid_json, extract/dnd/item-registry/shape, extract/dnd/item-registry/source_refs, generic/valid_json_schema, extract/dnd/item-registry/source_relatedness | generic/valid_json, extract/dnd/item-registry/shape, normalize/dnd/item-registry/identity, extract/dnd/item-registry/source_refs, generic/valid_json_schema, extract/dnd/item-registry/source_relatedness |
|
||||
| NPC occurrences | generic/valid_json, extract/dnd/npc-occurrences/shape, extract/dnd/npc-occurrences/registry, extract/dnd/npc-occurrences/source_refs, generic/valid_json_schema, extract/dnd/npc-occurrences/source_relatedness | generic/valid_json, extract/dnd/npc-occurrences/shape, extract/dnd/npc-occurrences/registry, normalize/dnd/npc-occurrences/invariants, extract/dnd/npc-occurrences/source_refs, generic/valid_json_schema, extract/dnd/npc-occurrences/source_relatedness |
|
||||
| Scene descriptions | generic/valid_json, extract/dnd/scene-descriptions/shape, extract/dnd/scene-descriptions/source_refs, generic/valid_json_schema, extract/dnd/scene-descriptions/source_relatedness | generic/valid_json, extract/dnd/scene-descriptions/shape, normalize/dnd/scene-descriptions/invariants, extract/dnd/scene-descriptions/source_refs, generic/valid_json_schema, extract/dnd/scene-descriptions/source_relatedness |
|
||||
| Enemy events | generic/valid_json, extract/dnd/enemy-events/shape, extract/dnd/enemy-events/engagements, extract/dnd/enemy-events/source_refs, generic/valid_json_schema, extract/dnd/enemy-events/source_relatedness | generic/valid_json, extract/dnd/enemy-events/shape, normalize/dnd/enemy-events/invariants, extract/dnd/enemy-events/source_refs, generic/valid_json_schema, extract/dnd/enemy-events/source_relatedness |
|
||||
| Location registry | generic/valid_json, extract/dnd/location-registry/shape, extract/dnd/location-registry/source_refs, generic/valid_json_schema, extract/dnd/location-registry/source_relatedness | generic/valid_json, extract/dnd/location-registry/shape, normalize/dnd/location-registry/identity, extract/dnd/location-registry/source_refs, generic/valid_json_schema, extract/dnd/location-registry/source_relatedness |
|
||||
| Location occurrences | generic/valid_json, extract/dnd/location-occurrences/shape, extract/dnd/location-occurrences/registry, extract/dnd/location-occurrences/source_refs, generic/valid_json_schema, extract/dnd/location-occurrences/source_relatedness | generic/valid_json, extract/dnd/location-occurrences/shape, extract/dnd/location-occurrences/registry, normalize/dnd/location-occurrences/invariants, extract/dnd/location-occurrences/source_refs, generic/valid_json_schema, extract/dnd/location-occurrences/source_relatedness |
|
||||
|
||||
Chains are only registered for the D&D extract and normalize modules shown
|
||||
above; select an explicit override when a different compatible chain is
|
||||
|
||||
208
docs/consumers/dnd-pipeline.md
Normal file
208
docs/consumers/dnd-pipeline.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# Consuming The Complete D&D Pipeline
|
||||
|
||||
Use this workflow when an orchestrator runs the maintained complete D&D
|
||||
pipeline and consumes its structured JSON artifacts. The generic
|
||||
[subprocess consumer guide](subprocess.md) owns process-level responsibilities;
|
||||
this guide connects that workflow to the complete D&D configuration, its
|
||||
Seriatim input, and its artifact inventory.
|
||||
|
||||
The [CLI reference](../cli.md), [configuration reference](../config.md),
|
||||
[run-result receipt](../integrations/run-result.md), and
|
||||
[published JSON output contract](../integrations/json-output.md) remain the
|
||||
canonical definitions of those public interfaces.
|
||||
|
||||
## Prepare And Validate The Deployment
|
||||
|
||||
Start from the maintained
|
||||
[complete D&D configuration](../../examples/dnd-complete.config.yml). It uses
|
||||
the `dnd-session` pipeline and demonstrates every implemented D&D lane, ordered
|
||||
artifact handoffs, campaign references, chunk-map publication, and evidence
|
||||
context.
|
||||
|
||||
A deployment must provide its own PromptKit profile and campaign reference
|
||||
files. Use absolute paths for service and subprocess deployments. In
|
||||
particular, observe these different resolution rules:
|
||||
|
||||
- reference paths in YAML are resolved relative to the Notarius configuration
|
||||
file; and
|
||||
- `promptkit.profile_file` is resolved relative to the Notarius process working
|
||||
directory.
|
||||
|
||||
Do not copy the repository example's relative profile path into a deployment
|
||||
without also controlling that working directory. The complete path and profile
|
||||
rules are defined in [Configuration](../config.md).
|
||||
|
||||
Preflight the deployed configuration before processing sessions and whenever
|
||||
it changes:
|
||||
|
||||
```sh
|
||||
notarius config validate \
|
||||
--config /absolute/path/to/notarius.yml \
|
||||
--pipeline dnd-session
|
||||
```
|
||||
|
||||
Provide credentials through the environment or the documented configuration
|
||||
mechanism. Do not put credentials in command arguments, generated
|
||||
configuration, or logs.
|
||||
|
||||
## Supply The Transcript
|
||||
|
||||
The complete pipeline consumes a Seriatim JSON document. The
|
||||
[Seriatim input contract](../integrations/seriatim.md) defines its required
|
||||
metadata, segments, and validation rules. Preserve segment IDs: D&D artifact
|
||||
citations use those segment IDs as source-unit ranges.
|
||||
|
||||
When the caller maintains several transcript tiers, use the final trimmed JSON
|
||||
transcript so extraction operates on the same session content presented to
|
||||
later consumers. For example, Narratio identifies this implemented artifact as
|
||||
`narratio.transcript.final_trimmed` and normally stores it at
|
||||
`transcripts/final.trimmed.json`.
|
||||
|
||||
Notarius generates a stable prompt session from the resolved input module and
|
||||
the exact input bytes. An ordinary orchestrator should not pass `--session-id`.
|
||||
Use that override only when intentionally changing the routing relationship
|
||||
between invocations; it is not a credential or output identity.
|
||||
|
||||
## Run Notarius
|
||||
|
||||
Invoke the pipeline with explicit absolute paths and request its
|
||||
machine-readable receipt:
|
||||
|
||||
```sh
|
||||
notarius run dnd-session \
|
||||
--config /absolute/path/to/notarius.yml \
|
||||
--input /absolute/path/to/transcripts/final.trimmed.json \
|
||||
--output-dir /absolute/path/to/notarius-output \
|
||||
--json
|
||||
```
|
||||
|
||||
The caller should:
|
||||
|
||||
- capture stdout and stderr separately;
|
||||
- propagate cancellation and impose an operator-appropriate timeout;
|
||||
- wait for process completion before interpreting stdout; and
|
||||
- retain stderr for diagnosis without copying secrets or transcript content
|
||||
into other logs.
|
||||
|
||||
Only exit status 0 permits decoding stdout as a receipt. Ignore stdout after a
|
||||
nonzero exit because a failed receipt write can leave partial bytes. The
|
||||
[CLI reference](../cli.md#output-streams-and-exit-statuses) defines the complete
|
||||
stream and exit-status contract.
|
||||
|
||||
## Discover The Published Bundle
|
||||
|
||||
Decode the successful stdout document as a supported run-result schema. For
|
||||
the current contract, `schema_version` is `notarius.run-result.v1`. Tolerate
|
||||
unknown fields allowed by that version, but reject an unsupported schema
|
||||
version.
|
||||
|
||||
Use the receipt's absolute `output_directory` as the exact run-specific bundle
|
||||
root. Do not scan the output root for its newest directory, guess a run ID, or
|
||||
construct a bundle path. Resolve `index_file` beneath `output_directory` and
|
||||
reject an absolute logical path or any result that escapes the bundle root.
|
||||
|
||||
The complete configuration uses the application validation defaults. A caller
|
||||
that requires fully validated D&D artifacts must also require receipt
|
||||
`validation_status: approved`; a successful `incomplete` result reflects the
|
||||
configured validator-failure continuation policy and carries its bounded
|
||||
validator provenance in `validation_summaries`.
|
||||
|
||||
Read `index.json` and locate each requested lane in `output_files` by its exact
|
||||
`lane_id`. Do not guess a lane filename. Before decoding a payload:
|
||||
|
||||
1. resolve its descriptor's relative `file` beneath the bundle root with the
|
||||
same confinement check;
|
||||
2. verify the descriptor's media type and schema identity against the linked
|
||||
artifact contract; and
|
||||
3. decode the payload according to that contract.
|
||||
|
||||
The [published JSON output contract](../integrations/json-output.md) defines
|
||||
the index and bundle layout. Treat all paths obtained from a decoded external
|
||||
document as untrusted until confined to their documented root.
|
||||
|
||||
## Complete Artifact Inventory
|
||||
|
||||
When every configured lane is accepted, the complete example publishes these
|
||||
lane artifacts:
|
||||
|
||||
| Lane ID | Purpose | Canonical contract |
|
||||
| --- | --- | --- |
|
||||
| `item-registry` | Canonical registry of encountered items and currency. | [Item registry](../integrations/dnd-item-registry-artifacts.md) |
|
||||
| `npc-registry` | Canonical registry of named NPCs. | [NPC registry](../integrations/dnd-npc-registry-artifacts.md) |
|
||||
| `location-registry` | Canonical registry of named locations. | [Location registry](../integrations/dnd-location-registry-artifacts.md) |
|
||||
| `scene-descriptions` | Classification, title, and summary for each scene. | [Scene descriptions](../integrations/dnd-scene-description-artifacts.md) |
|
||||
| `item-occurrences` | Source-grounded item discovery, acquisition, use, transfer, and loss events. | [Item occurrences](../integrations/dnd-item-occurrence-artifacts.md) |
|
||||
| `spells` | Source-grounded spell casts and casters. | [Spell casts](../integrations/dnd-spell-artifacts.md) |
|
||||
| `combat-turns` | Source-grounded combat turn participation. | [Combat turns](../integrations/dnd-combat-turn-artifacts.md) |
|
||||
| `npc-occurrences` | Source-grounded NPC interaction occurrences. | [NPC occurrences](../integrations/dnd-npc-occurrence-artifacts.md) |
|
||||
| `location-occurrences` | Source-grounded location occurrences. | [Location occurrences](../integrations/dnd-location-occurrence-artifacts.md) |
|
||||
| `enemy-events` | Source-grounded enemy combat events. | [Enemy events](../integrations/dnd-enemy-event-artifacts.md) |
|
||||
|
||||
The JSON encoder always publishes these bundle-management files:
|
||||
|
||||
| File | Purpose |
|
||||
| --- | --- |
|
||||
| `index.json` | Discovery document for lane and pipeline-wide artifacts. |
|
||||
| `manifest.json` | Run provenance and result summaries. |
|
||||
| `rejected.json` | Rejected pipeline outputs. |
|
||||
| `warnings.json` | Accepted-output and run warnings. |
|
||||
|
||||
The complete configuration also requests two pipeline-wide artifacts:
|
||||
|
||||
- [`chunk-map.json`](../integrations/chunk-map.md), the accepted chunk plan and
|
||||
chunk metadata; and
|
||||
- [`evidence-context.json`](../integrations/evidence-context.md), a reading
|
||||
excerpt containing the union of selected cited source units and the
|
||||
configured surrounding window.
|
||||
|
||||
Discover both from their top-level `index.json` descriptors rather than
|
||||
treating them as lanes. Evidence context is convenient reading material, not
|
||||
authoritative provenance; citations in the normalized lane payloads remain the
|
||||
evidence contract.
|
||||
|
||||
Every optional or lane file is published only when its corresponding artifact
|
||||
is available. A successful process does not guarantee that all configured
|
||||
lanes were accepted.
|
||||
|
||||
## Decide What Counts As Consumer Success
|
||||
|
||||
Exit status 0 means Notarius completed the pipeline and published its result
|
||||
bundle. The receipt or bundle may still report warnings, rejected outputs, or
|
||||
missing lane descriptors. A downstream consumer must define its own required
|
||||
artifact set explicitly.
|
||||
|
||||
A caller that claims to consume the complete D&D workflow should normally
|
||||
require all ten lane IDs in the table and verify each descriptor's expected
|
||||
contract. If any required lane is missing, rejected, or incompatible, fail the
|
||||
caller's extraction step while retaining the Notarius bundle for diagnosis. A
|
||||
consumer that needs only a subset may define and document a narrower policy.
|
||||
|
||||
Keep the successful receipt with the complete published bundle. Retain
|
||||
`manifest.json`, `rejected.json`, `warnings.json`, and captured process logs as
|
||||
required by the caller's provenance, diagnosis, and retention policies. Avoid
|
||||
selectively copying payload files without also preserving enough index and
|
||||
manifest information to identify their originating run and contracts.
|
||||
|
||||
The transcript, lane artifacts, evidence context, manifest, debug data, and
|
||||
logs can all contain private campaign information. Apply the same access,
|
||||
publication, and retention controls used for the source transcript.
|
||||
|
||||
## Consumer Checklist
|
||||
|
||||
- Validate the deployed Notarius configuration and `dnd-session` pipeline.
|
||||
- Pass the final trimmed Seriatim JSON transcript with stable segment IDs.
|
||||
- Use absolute configuration, input, output-root, profile, and reference paths
|
||||
in service deployments.
|
||||
- Capture stdout and stderr separately and enforce cancellation and timeout.
|
||||
- Parse stdout only after exit status 0.
|
||||
- Accept only supported receipt, index, and artifact schema versions while
|
||||
tolerating permitted unknown fields.
|
||||
- Use the receipt's `output_directory`; never guess the run directory.
|
||||
- Confine `index_file` and every descriptor path to the published bundle root.
|
||||
- Discover lanes by `lane_id` and verify descriptor compatibility before
|
||||
decoding payloads.
|
||||
- Enforce an explicit required-lane policy and inspect rejections and warnings.
|
||||
- Preserve the receipt and sufficient bundle provenance for every retained
|
||||
artifact.
|
||||
- Protect all transcript-derived files and diagnostic streams as sensitive
|
||||
campaign data.
|
||||
@@ -6,6 +6,10 @@ statuses, while the [run-result receipt](../integrations/run-result.md) and
|
||||
[Published JSON Output contract](../integrations/json-output.md) own the
|
||||
durable result formats.
|
||||
|
||||
For the maintained complete D&D workflow, including its transcript input,
|
||||
configured lane inventory, and downstream acceptance checklist, see
|
||||
[Consuming The Complete D&D Pipeline](dnd-pipeline.md).
|
||||
|
||||
## Run And Check The Process
|
||||
|
||||
Optionally preflight a selected configuration and pipeline before work starts:
|
||||
@@ -27,10 +31,13 @@ notarius run pipeline-id \
|
||||
```
|
||||
|
||||
Use absolute paths for supplied input, configuration, output-root, and
|
||||
reference files. When a stable prompt session identifier or references are
|
||||
needed, pass the supported CLI flags. Supply credentials through Notarius's
|
||||
documented configuration and environment mechanisms, never as command-line
|
||||
arguments or generated secret-bearing configuration.
|
||||
reference files. Notarius generates a stable prompt session for the resolved
|
||||
input module and exact input bytes. Pass **--session-id** only when intentionally
|
||||
grouping different invocations under a different session. Supply credentials
|
||||
through Notarius's documented configuration and environment mechanisms, never
|
||||
as command-line arguments or generated secret-bearing configuration. In
|
||||
particular, a session identifier is provider-visible and is not a credential
|
||||
mechanism.
|
||||
|
||||
Wait for the process before interpreting standard output. Only an exit status
|
||||
of 0 permits decoding the receipt. On a nonzero exit, retain standard error for
|
||||
@@ -52,16 +59,23 @@ contract. The JSON bundle contract links to the available lane contracts.
|
||||
If `index.json` has an `evidence_context` descriptor, treat it as a
|
||||
pipeline-wide artifact rather than a lane entry. Verify its six descriptor
|
||||
fields before decoding the linked file according to the [Published Evidence
|
||||
Context contract](../integrations/evidence-context.md). Use each
|
||||
`evidence_refs` entry as the citation to source material. Its surrounding
|
||||
context range and included units explain the citation, but do not widen or
|
||||
replace the cited source reference.
|
||||
Context contract](../integrations/evidence-context.md). Decode its top-level
|
||||
source-unit array as a reading excerpt. Obtain authoritative citations and lane
|
||||
provenance from the normalized lane artifacts; the excerpt has neither and its
|
||||
nearby units do not widen a lane artifact's cited source reference.
|
||||
|
||||
A zero exit status may still report rejected outputs, warnings, or absent
|
||||
lanes. The caller decides which lane IDs are required for its own work and
|
||||
which are optional; it should make that decision explicitly rather than infer
|
||||
failure from the receipt counts alone.
|
||||
|
||||
When complete validation is required, also require receipt
|
||||
`validation_status: approved` and inspect `validation_summaries`. A successful
|
||||
run with `validation_status: incomplete` contains a structurally valid result
|
||||
that advanced after validator execution could not complete under the configured
|
||||
`warn_continue` policy. It is not reusable checkpoint state and should not be
|
||||
silently treated as fully reviewed by the caller.
|
||||
|
||||
## Preserve Provenance And Handle Data Carefully
|
||||
|
||||
Keep the receipt with the published `manifest.json`, and retain
|
||||
@@ -70,5 +84,5 @@ them. Treat the input, output bundle, cache, debug bundle, and captured process
|
||||
logs as potentially sensitive data. Apply the caller's access controls and
|
||||
retention policy, and avoid copying secrets into arguments, logs, or
|
||||
provenance records. An evidence-context artifact contains source-unit text and
|
||||
metadata, and selected lanes can cover most of an input; preserve and share it
|
||||
only when that source content is authorized for the recipient.
|
||||
metadata and can cover most of an input; preserve and share it only when that
|
||||
source content is authorized for the recipient.
|
||||
|
||||
@@ -18,13 +18,14 @@ implemented component map.
|
||||
| Any documentation addition or revision | [Documentation Policy](policy/documentation.md) | It defines canonical homes, audiences, current-behavior rules, and maintenance requirements. |
|
||||
| Adding, changing, reviewing, or deleting tests | [Testing Policy](policy/testing.md) | It defines risk-based sufficiency, durable test boundaries, test-double guidance, and criteria for retaining tests. |
|
||||
| CLI composition or command behavior | [CLI Internals](internal/cli.md) and [CLI Reference](cli.md) | The internal guide owns composition and command flow; the reference owns public syntax. |
|
||||
| Building a subprocess caller or changing its result protocol | [Subprocess Consumer Guide](consumers/subprocess.md), [Run Result Receipt](integrations/run-result.md), and [CLI Internals](internal/cli.md) | These separate caller workflow, durable receipt contract, and CLI implementation behavior. |
|
||||
| Building a subprocess caller or changing its result protocol | [Subprocess Consumer Guide](consumers/subprocess.md), [Complete D&D Consumer Guide](consumers/dnd-pipeline.md), [Run Result Receipt](integrations/run-result.md), and [CLI Internals](internal/cli.md) | These separate generic caller workflow, the complete D&D workflow, the durable receipt contract, and CLI implementation behavior. |
|
||||
| Configuration loading, resolution, or user-visible configuration behavior | [Configuration Internals](internal/configuration.md) and [Configuration](config.md) | The internal guide owns loading and resolution mechanics; the reference owns the configuration contract. |
|
||||
| Pipeline resolution or execution | [Pipeline Internals](internal/pipeline.md) | It documents profiles, references, validation, retries, checkpoints, and runner behavior. |
|
||||
| Production modules or validators | [Module Internals](internal/modules.md), [D&D Module Internals](internal/dnd.md), and [D&D integration contracts](integrations/) | The generic guide owns extension mechanics, the D&D guide owns shared family conventions, and the contracts own durable output shapes. |
|
||||
| LLM clients, prompts, schemas, profiles, or scheduling | [LLM Runtime](internal/llm.md) | It documents the transport boundary and Scriptorium integration. |
|
||||
| LLM clients, prompts, schemas, profiles, or scheduling | [LLM Runtime](internal/llm.md) | It documents the transport boundary and PromptKit integration. |
|
||||
| Output, cache, resume, or debug artifacts | [Run State Internals](internal/state.md), [Operations](operations.md), and [Configuration](config.md) | These separate implementation details, operator behavior, and configuration contracts. |
|
||||
| External input formats, artifact schemas, or durable output files | [Integration Contracts](integrations/) | Integration documents define external and durable data contracts. |
|
||||
| Release preparation, tagging, publication, or verification | [Source Releases](release.md) and [Documentation Policy](policy/documentation.md) | The release procedure owns maintainer guards and immutable-tag recovery; the policy assigns release-note ownership. |
|
||||
| Proposed or unimplemented behavior | [Roadmap](roadmap/) | Future work belongs only in roadmap documentation until implemented. |
|
||||
|
||||
For an existing subsystem, also inspect its focused tests and the package-local
|
||||
|
||||
@@ -55,7 +55,7 @@ record controls eligibility only: its title, summary, and reference do not
|
||||
become turn evidence. No exact matching scene also produces an empty list and
|
||||
the `scene_classification_unavailable` warning.
|
||||
|
||||
An optional normalized [NPC artifact](dnd-npc-artifacts.md) can ground an
|
||||
An optional normalized [NPC registry artifact](dnd-npc-registry-artifacts.md) can ground an
|
||||
actor name. Its registry references are provenance, never combat evidence.
|
||||
Normalization trims and, where possible, canonicalizes actor names; orders and
|
||||
deduplicates exact source references; orders valid-evidence turns by source
|
||||
@@ -63,7 +63,9 @@ chronology; and collapses only duplicates with the same actor identity, turn
|
||||
kind, and complete valid evidence. It does not infer turns, initiative, or
|
||||
actions from registry or scene data.
|
||||
|
||||
The [NPC-interaction artifact](dnd-npc-interaction-artifacts.md) records
|
||||
broader NPC occurrences. The [JSON output contract](json-output.md) defines
|
||||
publication, and [D&D module internals](../internal/dnd.md) describes routing
|
||||
and validation mechanics.
|
||||
The [NPC-occurrence artifact](dnd-npc-occurrence-artifacts.md) records
|
||||
broader NPC occurrences. The [enemy-event artifact](dnd-enemy-event-artifacts.md)
|
||||
uses combat turns as grounding only; turns do not establish an enemy event or
|
||||
its outcome. The [JSON output contract](json-output.md) defines publication,
|
||||
and [D&D module internals](../internal/dnd.md) describes routing and validation
|
||||
mechanics.
|
||||
|
||||
114
docs/integrations/dnd-enemy-event-artifacts.md
Normal file
114
docs/integrations/dnd-enemy-event-artifacts.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# D&D Enemy-Event Artifact
|
||||
|
||||
This contract defines the durable, source-grounded enemy-event occurrence list.
|
||||
It records enemies directly established as opposing the party and explicitly
|
||||
observed combat outcomes. It is an ordered observation artifact from which a
|
||||
consumer may derive a ledger; it is not a ledger, encounter roster, or terminal
|
||||
state model.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/enemy-event-list` |
|
||||
| Schema ID | `notarius.dnd.enemy_events` |
|
||||
| Schema name | `notarius_dnd_enemy_events_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
|
||||
`v1` is a strict JSON object with required `events`; the array may be empty.
|
||||
Event and source-reference objects reject unknown fields. An incompatible shape
|
||||
change requires a new schema version.
|
||||
|
||||
## Wire shape
|
||||
|
||||
Every event has these required fields:
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `name` | Non-empty display name or directly grounded collective subject label. |
|
||||
| `kind` | `engaged`, `killed`, `fled`, `captured`, or `incapacitated`. |
|
||||
| `source_refs` | One or more current-transcript evidence ranges. |
|
||||
|
||||
Each source reference has exactly `source_id`, `start_unit_id`, and
|
||||
`end_unit_id`. It identifies an inclusive current-transcript range; unit IDs
|
||||
are positive and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"events": [
|
||||
{
|
||||
"name": "Ashfang",
|
||||
"kind": "engaged",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 41, "end_unit_id": 42}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Ashfang",
|
||||
"kind": "fled",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 57, "end_unit_id": 58}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Event semantics and evidence
|
||||
|
||||
| Kind | Required evidence |
|
||||
| --- | --- |
|
||||
| `engaged` | The subject is directly established as actively opposing the party in combat. At most one engagement is emitted for one subject in one combat scene. |
|
||||
| `killed` | The transcript explicitly establishes that the subject died or was killed. Damage, defeat, disappearance, or combat ending is insufficient. |
|
||||
| `fled` | The subject explicitly escapes, retreats, or otherwise leaves combat to avoid continued engagement. Movement or absence from later turns is insufficient. |
|
||||
| `captured` | The subject is explicitly taken prisoner or secured under the party's control. A grapple or temporary restraint alone is insufficient. |
|
||||
| `incapacitated` | The subject is explicitly rendered unable to continue acting without being established as killed or captured. A missed turn is insufficient. |
|
||||
|
||||
The current transcript is the only event evidence. Campaign context and
|
||||
normalized NPC, scene-description, combat-turn, and NPC-occurrence artifacts
|
||||
can ground names or control combat eligibility, but none may supply event
|
||||
evidence. An outcome may share evidence with an engagement, in which case both
|
||||
events are retained.
|
||||
|
||||
Extraction is limited to chunks with an exact combat-scene classification. An
|
||||
exact non-combat classification produces an accepted empty list. Missing or
|
||||
mismatched classification also produces an accepted empty list and a
|
||||
`scene_classification_unavailable` warning.
|
||||
|
||||
## Subjects, normalization, and order
|
||||
|
||||
A subject matching the normalized NPC registry uses that registry's canonical
|
||||
display name. Unmatched hostile creatures, summoned entities, and directly
|
||||
grounded groups remain valid subjects. An unnamed homogeneous group uses the
|
||||
narrowest transcript-grounded label, such as `Orcs`, `One orc`, or `Remaining
|
||||
orcs`; the artifact never invents synthetic member identities or quantities.
|
||||
Party members, allies, neutral observers, mentioned-but-absent enemies, hazards,
|
||||
traps, and environmental effects are excluded.
|
||||
|
||||
Normalization collapses surrounding and repeated internal whitespace in subject
|
||||
display values, canonicalizes recognized registry names, canonicalizes and
|
||||
deduplicates exact source ranges, then orders events by valid evidence
|
||||
chronology, normalized subject identity, display name, kind, and reference
|
||||
sequence. The deterministic kind tie order is `engaged`,
|
||||
`incapacitated`, `captured`, `fled`, then `killed`. Only entries with the same
|
||||
normalized name, kind, and complete canonical evidence sequence are collapsed.
|
||||
Different kinds, evidence, repeated engagement in separate scenes, and later
|
||||
outcomes remain separate. A later engagement for the same named subject is
|
||||
preserved after an earlier outcome because the artifact does not assert an
|
||||
irreversible state transition.
|
||||
|
||||
## Non-goals
|
||||
|
||||
The artifact has no NPC or scene ID, quantity, confidence, description,
|
||||
rationale, summary, current state, or inferred terminal outcome. It does not
|
||||
emit `active` or `unresolved`; consumers may derive an unresolved ledger view
|
||||
only when an engagement has no later explicit outcome. It never infers an
|
||||
outcome from turn absence, scene termination, initiative order, hit-point
|
||||
guesses, or other artifacts.
|
||||
|
||||
The [JSON output contract](json-output.md) defines publication. Configuration
|
||||
keys, required generated-reference slots, and validator-chain selection are
|
||||
defined in the [configuration reference](../config.md). Implementation and
|
||||
prompt-grounding mechanics are described in the
|
||||
[D&D module internals](../internal/dnd.md).
|
||||
@@ -1,78 +0,0 @@
|
||||
# D&D Item-Event Artifact
|
||||
|
||||
This contract defines the durable item and currency occurrence list produced by
|
||||
`dnd/item-events`. It records source-grounded discoveries and possession
|
||||
changes; it does not maintain an inventory, balance, or ledger.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/item-event-list` |
|
||||
| Schema ID | `notarius.dnd.item_events` |
|
||||
| Schema name | `notarius_dnd_item_events_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
|
||||
`v1` is a strict JSON object with required `events`; the array may be empty.
|
||||
Event and source-reference objects reject unknown fields. An incompatible
|
||||
shape change requires a new schema version.
|
||||
|
||||
## Wire shape
|
||||
|
||||
Every event has required `name`, `kind`, and `source_refs`. `quantity`, `from`,
|
||||
and `to` are optional where the event kind permits them.
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `name` | Non-empty item or currency display name. |
|
||||
| `kind` | `discovered`, `acquired`, `lost`, `consumed`, or `transferred`. |
|
||||
| `quantity` | Optional positive integer; omit it when no count is established. |
|
||||
| `from` | Optional non-empty losing holder, when allowed by `kind`. |
|
||||
| `to` | Optional non-empty gaining holder, when allowed by `kind`. |
|
||||
| `source_refs` | One or more transcript evidence ranges. |
|
||||
|
||||
Each source reference has exactly `source_id`, `start_unit_id`, and
|
||||
`end_unit_id`. It identifies an inclusive current-transcript range; unit IDs
|
||||
are positive and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"events": [
|
||||
{
|
||||
"name": "Silver Pieces",
|
||||
"kind": "acquired",
|
||||
"quantity": 20,
|
||||
"to": "party",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 2, "end_unit_id": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Holder rules and minimal extraction
|
||||
|
||||
`discovered` has neither holder; `acquired` requires `to` and forbids `from`;
|
||||
`lost` and `consumed` require `from` and forbid `to`; `transferred` requires
|
||||
both holders. `party` denotes collective possession. A transfer cannot use
|
||||
`party` for either holder and its two normalized holders must differ.
|
||||
|
||||
Only an evidenced discovery or possession change belongs in this artifact.
|
||||
It does not infer quantities or holders, convert currency denominations,
|
||||
calculate balances, or merge nearby events. Campaign references may
|
||||
disambiguate names but are never event evidence. Currency uses the ordinary
|
||||
`name` field and an explicit `quantity` only when the transcript establishes
|
||||
one; each denomination remains a separate event.
|
||||
|
||||
Normalization trims display whitespace, orders and removes exact duplicate
|
||||
source references, then orders events by valid source chronology, name identity
|
||||
and display value, kind, holders, quantity, and reference sequence. It
|
||||
collapses only entries with the same normalized durable fields and complete
|
||||
valid evidence.
|
||||
|
||||
The [JSON output contract](json-output.md) defines publication. See
|
||||
[D&D module internals](../internal/dnd.md) for implementation details and the
|
||||
[NPC-interaction artifact](dnd-npc-interaction-artifacts.md) for a distinct
|
||||
kind of occurrence.
|
||||
72
docs/integrations/dnd-item-occurrence-artifacts.md
Normal file
72
docs/integrations/dnd-item-occurrence-artifacts.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# D&D Item-Occurrence Artifact
|
||||
|
||||
`dnd/item-occurrences` currently produces this source-grounded item and currency
|
||||
occurrence list. It records discoveries and possession changes, not an
|
||||
inventory, balance, or ledger.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/item-occurrence-list` |
|
||||
| Schema ID | `notarius.dnd.item_occurrences` |
|
||||
| Schema name | `notarius_dnd_item_occurrences_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
|
||||
`v1` accepts one strict JSON object with required `occurrences`; the array may
|
||||
be empty. Each occurrence has required `item_id`, `name`, `kind`, and
|
||||
`source_refs`, and occurrence and source-reference objects reject unknown
|
||||
fields. `quantity`, `from`, and `to` appear only when their kind permits them.
|
||||
An incompatible shape change requires a new schema version.
|
||||
|
||||
## Registry grounding
|
||||
|
||||
Both extraction and normalization require an `item_registry` reference bound to
|
||||
an earlier normalized `dnd/item-registry` artifact. The registry is immutable
|
||||
for an operation and contributes names-only grounding after the shared evidence
|
||||
message. Notarius resolves the model's selected name into the unchanged exact
|
||||
durable ID/name pair. It is never occurrence evidence.
|
||||
|
||||
Each occurrence must use one exact registry ID/name pair. An extraction response
|
||||
with an unknown or ambiguous selected name is rejected as invalid model output;
|
||||
the configured pipeline may retry it and never accepts a partial artifact.
|
||||
Normalization and validation remain defense in depth for artifacts entering
|
||||
through other boundaries: normalization canonicalizes a recognized name by ID,
|
||||
preserves unknown values for the registry validator, and the registry validator
|
||||
rejects unknown or mismatched pairs.
|
||||
|
||||
## Wire shape
|
||||
|
||||
Each source reference has exactly `source_id`, `start_unit_id`, and
|
||||
`end_unit_id`. It identifies an inclusive range in the current transcript;
|
||||
unit IDs are positive and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"occurrences": [
|
||||
{
|
||||
"item_id": "item:sha256:…",
|
||||
"name": "Silver Pieces",
|
||||
"kind": "acquired",
|
||||
"quantity": 20,
|
||||
"to": "party",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 2, "end_unit_id": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The five kinds remain `discovered`, `acquired`, `lost`, `consumed`, and
|
||||
`transferred`. Holder, quantity, currency, ordering, and exact-duplicate rules
|
||||
are unchanged: discovered has no holder; acquired requires `to`; lost and
|
||||
consumed require `from`; transferred requires distinct non-`party` holders.
|
||||
The only current downstream compatibility requirement is its registry handoff;
|
||||
the normalized occurrence list is otherwise published for callers. See
|
||||
[Configuration](../config.md#d-d-reference-slots) for the binding and
|
||||
[JSON output](json-output.md) for publication.
|
||||
|
||||
See [item registry](dnd-item-registry-artifacts.md) for the grounding artifact
|
||||
and [D&D module internals](../internal/dnd.md) for implementation details.
|
||||
95
docs/integrations/dnd-item-registry-artifacts.md
Normal file
95
docs/integrations/dnd-item-registry-artifacts.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# D&D Item Registry Artifact
|
||||
|
||||
This contract defines the durable, source-grounded item registry produced by
|
||||
`dnd/item-registry`. It records transcript-established item types and unique
|
||||
designations for one source document; it is not an inventory, holder record,
|
||||
quantity ledger, or item-occurrence artifact.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/item-registry` |
|
||||
| Schema ID | `notarius.dnd.item_registry` |
|
||||
| Schema name | `notarius_dnd_item_registry_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
| Identity policy | `dnd.item_registry.identity.v1` |
|
||||
|
||||
`v1` accepts one strict JSON object with required `items`; the array may be
|
||||
empty. Item and source-reference objects reject unknown fields. An incompatible
|
||||
artifact shape or identity-policy change uses a new version or policy.
|
||||
|
||||
## Wire shape and identity
|
||||
|
||||
Each item has these required fields:
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `id` | `item:sha256:` followed by 64 lowercase hexadecimal characters. |
|
||||
| `name` | Non-empty transcript-established item type or unique designation. |
|
||||
| `source_refs` | One or more transcript evidence ranges that establish the item. |
|
||||
|
||||
A source reference has exactly `source_id`, `start_unit_id`, and `end_unit_id`.
|
||||
The source ID identifies the transcript, unit IDs are positive inclusive unit
|
||||
identifiers, and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": "item:sha256:31e73b6280ef98e4d8070e07fd4de9b2c3e842cc03af1a09ca631cb95b73e3b3",
|
||||
"name": "Star Compass",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 4, "end_unit_id": 5}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The ID is deterministic for an item name or type, rather than for one physical
|
||||
instance. Notarius normalizes the display name for comparison with Unicode
|
||||
NFKC, supported apostrophe normalization, collapsed whitespace, and case
|
||||
folding. It hashes compact JSON for this array:
|
||||
|
||||
```text
|
||||
["dnd.item_registry.identity.v1", comparison_name]
|
||||
```
|
||||
|
||||
The canonical ID is the lowercase SHA-256 digest of those bytes with the
|
||||
`item:sha256:` prefix. Equal comparison names represent one item identity;
|
||||
normalization unions their transcript evidence when it safely consolidates a
|
||||
candidate group.
|
||||
|
||||
## Scope, reconciliation, and evidence
|
||||
|
||||
The registry includes named unique items, concrete reusable item types, stable
|
||||
unique designations, and separately established currency denominations. It
|
||||
excludes vague loot or treasure, generic weapons, quantities, inferred
|
||||
properties, and inferred uniqueness. Capitalization alone does not establish
|
||||
eligibility.
|
||||
|
||||
Normalization first applies deterministic display, evidence, and ID rules. It
|
||||
then may use a bounded LLM-assisted proposal to reconcile semantically duplicate
|
||||
records. The proposal may choose only a supplied candidate display name;
|
||||
invalid, uncertain, overlapping, or unsafe proposals retain the deterministic
|
||||
result with retry or fallback diagnostics. A proposal that mixes a recognized
|
||||
currency denomination with a non-currency item, or combines recognized
|
||||
denominations, is unsafe and retains every deterministic record. Currency
|
||||
denominations, materially different item types, and merely nearby objects
|
||||
remain distinct. Source references establish registry provenance, not evidence
|
||||
for later artifacts.
|
||||
|
||||
## Consumers and publication
|
||||
|
||||
`dnd/item-occurrences` requires one approved item registry through its
|
||||
`item_registry` reference slot for both extraction and normalization. Its
|
||||
consumer receives names-only grounding; Notarius resolves the selected name
|
||||
into the unchanged exact durable ID/name pair. The registry’s source references
|
||||
are never occurrence evidence. Unknown or ambiguous selections are rejected by
|
||||
the occurrence contract. See the
|
||||
[item-occurrence artifact](dnd-item-occurrence-artifacts.md) for that strict
|
||||
wire contract, [Configuration](../config.md#d-d-reference-slots) for binding
|
||||
rules and validator selection, and the [JSON output contract](json-output.md)
|
||||
for publication.
|
||||
86
docs/integrations/dnd-location-occurrence-artifacts.md
Normal file
86
docs/integrations/dnd-location-occurrence-artifacts.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# D&D Location-Occurrence Artifact
|
||||
|
||||
This contract defines the durable occurrence list produced by
|
||||
`dnd/location-occurrences`. It records source-grounded ways the party relates
|
||||
to locations in a required normalized location registry; it does not extend
|
||||
that registry or infer a place absent from it.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/location-occurrence-list` |
|
||||
| Schema ID | `notarius.dnd.location_occurrences` |
|
||||
| Schema name | `notarius_dnd_location_occurrences_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
|
||||
`v1` accepts one strict JSON object with required `occurrences`; the array may
|
||||
be empty. Occurrence and source-reference objects reject unknown fields. An
|
||||
incompatible shape change requires a new schema version.
|
||||
|
||||
## Wire shape
|
||||
|
||||
Each occurrence has these required fields:
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `location_id` | Exact ID from the required normalized [location registry](dnd-location-registry-artifacts.md). |
|
||||
| `name` | Exact canonical display name for `location_id` in that registry. |
|
||||
| `kind` | One of `visited`, `planned`, `recalled`, or `mentioned`. |
|
||||
| `source_refs` | One or more current-transcript evidence ranges for this occurrence. |
|
||||
|
||||
A source reference has exactly `source_id`, `start_unit_id`, and `end_unit_id`.
|
||||
It identifies an inclusive range in the current transcript; unit IDs are
|
||||
positive and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"occurrences": [
|
||||
{
|
||||
"location_id": "location:sha256:fb05475da0fc7debf994b517e1906ffe7209887a6a1ec306356d84de820b1a24",
|
||||
"name": "Moon Gate",
|
||||
"kind": "visited",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 12, "end_unit_id": 13}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Occurrence categories
|
||||
|
||||
| Kind | Meaning |
|
||||
| --- | --- |
|
||||
| `visited` | The transcript establishes physical party presence, including arrival, continuing presence, or departure. |
|
||||
| `planned` | The party explicitly proposes, intends, or agrees to future travel; speculation alone is not enough. |
|
||||
| `recalled` | The transcript explicitly recounts prior party presence before the current live events. |
|
||||
| `mentioned` | The location is explicit but no stronger category applies, including lore, directions, third-party activity, non-actionable speculation, a mere hypothetical reference, or out-of-character discussion. |
|
||||
|
||||
For overlapping evidence, precedence is `visited`, then `planned`, then
|
||||
`recalled`, then `mentioned`. For example, “What if we went to Moon Gate?” is
|
||||
eligible as `mentioned` when its narrow evidence explicitly references that
|
||||
registry location, but it is not `planned` without an actual proposal,
|
||||
intention, or agreement to travel. Inferred, unstated, uncertain, and
|
||||
unsupported places or occurrences are omitted. Normalization
|
||||
canonicalizes the registry name, orders and deduplicates source references, and
|
||||
orders occurrences by source chronology, location ID, name, kind, and reference
|
||||
sequence. It collapses only exact duplicates with the same ID, kind, and
|
||||
complete canonical evidence sequence.
|
||||
|
||||
## Required grounding and evidence
|
||||
|
||||
Both extraction and normalization require exactly one `location_registry` reference of
|
||||
kind `dnd/location-registry`, media type `application/json`, and at most 1 MiB. The
|
||||
registry provides identity grounding only. The model selects a supplied
|
||||
contextual name-and-registry-reference descriptor, and Notarius resolves it
|
||||
into the exact durable ID/name pair. Unknown, partial, or ambiguous selections
|
||||
are rejected rather than guessed or reassigned. The current transcript is the
|
||||
only evidence source for an occurrence; registry evidence and provenance never
|
||||
become occurrence evidence.
|
||||
|
||||
See [Configuration](../config.md#d-d-reference-slots) for the selectable slot
|
||||
and generated-handoff compatibility, [D&D module internals](../internal/dnd.md)
|
||||
for implementation behavior, and the [JSON output contract](json-output.md)
|
||||
for publication.
|
||||
93
docs/integrations/dnd-location-registry-artifacts.md
Normal file
93
docs/integrations/dnd-location-registry-artifacts.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# D&D Location Registry Artifact
|
||||
|
||||
This contract defines the durable, source-grounded location registry produced
|
||||
by `dnd/location-registry`. It records transcript-established physical places for one
|
||||
source document; it is not a map, location hierarchy, campaign-wide world
|
||||
registry, or location description.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/location-registry` |
|
||||
| Schema ID | `notarius.dnd.location_registry` |
|
||||
| Schema name | `notarius_dnd_location_registry_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
| Identity policy | `dnd.location_registry.identity.v1` |
|
||||
|
||||
`v1` accepts one strict JSON object with required `locations`; the array may be
|
||||
empty. Location and source-reference objects reject unknown fields. An
|
||||
incompatible artifact shape or identity-policy change uses a new version or
|
||||
policy.
|
||||
|
||||
## Wire shape and identity
|
||||
|
||||
Each location has these required fields:
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `id` | `location:sha256:` followed by 64 lowercase hexadecimal characters. |
|
||||
| `name` | Non-empty transcript-established display name. |
|
||||
| `source_refs` | One or more transcript evidence ranges that identify the place. |
|
||||
|
||||
A source reference has exactly `source_id`, `start_unit_id`, and `end_unit_id`.
|
||||
The source ID identifies the transcript, unit IDs are positive inclusive unit
|
||||
identifiers, and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"locations": [
|
||||
{
|
||||
"id": "location:sha256:fb05475da0fc7debf994b517e1906ffe7209887a6a1ec306356d84de820b1a24",
|
||||
"name": "Moon Gate",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 4, "end_unit_id": 5}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The ID is deterministic and scoped to the source document. Notarius normalizes
|
||||
the display name for comparison with Unicode NFKC, supported apostrophe
|
||||
normalization, collapsed whitespace, and case folding. It hashes compact JSON
|
||||
for this array, using the earliest canonical source reference as the anchor:
|
||||
|
||||
```text
|
||||
["dnd.location_registry.identity.v1", comparison_name, source_id, start_unit_id, end_unit_id]
|
||||
```
|
||||
|
||||
The canonical ID is the lowercase SHA-256 digest of those bytes with the
|
||||
`location:sha256:` prefix. Equal display names are allowed when their evidence
|
||||
anchors differ, so a generic name does not force distinct places to collapse.
|
||||
|
||||
## Scope, reconciliation, and evidence
|
||||
|
||||
Locations are physical or spatial places established by the transcript with a
|
||||
stable proper name or unique in-world designation, such as named planes,
|
||||
regions, settlements, districts, buildings, rooms, landmarks, routes, and
|
||||
geographic features. Generic, temporary, relative, and descriptive phrases
|
||||
such as “the room,” “the bar,” “the hallway,” “outside,” and “upstairs” are not
|
||||
registry locations. Capitalization alone does not establish eligibility.
|
||||
Notarius does not infer an unstated place or add hierarchy, coordinates,
|
||||
descriptions, participants, or ownership.
|
||||
|
||||
Normalization first applies deterministic display, evidence, and ID rules. It
|
||||
then may use a bounded LLM-assisted proposal to reconcile semantically duplicate
|
||||
records. The proposal is validated and applied conservatively; invalid or
|
||||
unusable proposals retain the deterministic result with retry or fallback
|
||||
diagnostics. The registry's source references establish registry provenance,
|
||||
not evidence for later artifacts.
|
||||
|
||||
## Consumers and publication
|
||||
|
||||
`dnd/location-occurrences` requires one approved location registry through its
|
||||
`location_registry` reference slot. Its prompt receives contextual selectors
|
||||
containing a canonical name and registry references; Notarius resolves a
|
||||
selection into the unchanged exact durable ID/name pair. Registry references
|
||||
must not be treated as occurrence evidence. See the
|
||||
[location-occurrence artifact](dnd-location-occurrence-artifacts.md)
|
||||
for that contract, [Configuration](../config.md#references-and-ordered-handoffs)
|
||||
for binding rules, and the [JSON output contract](json-output.md) for
|
||||
publication.
|
||||
@@ -1,69 +0,0 @@
|
||||
# D&D NPC Artifact
|
||||
|
||||
This contract defines the durable NPC registry produced by `dnd/npcs`. It is a
|
||||
minimal, source-grounded identity registry for other D&D artifacts, not a
|
||||
character sheet or a relationship summary.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/npc-list` |
|
||||
| Schema ID | `notarius.dnd.npcs` |
|
||||
| Schema name | `notarius_dnd_npcs_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
| Identity policy | `dnd.npcs.identity.v1` |
|
||||
|
||||
`v1` accepts one strict JSON object with required `npcs`; the array may be
|
||||
empty. NPC and source-reference objects reject unknown fields. An incompatible
|
||||
artifact shape or identity-policy change uses a new version or policy.
|
||||
|
||||
## Wire shape and identity
|
||||
|
||||
Each NPC has these required fields:
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `id` | `npc:sha256:` followed by 64 lowercase hexadecimal characters. |
|
||||
| `name` | Non-empty canonical display name. |
|
||||
| `source_refs` | One or more transcript evidence ranges for the identity. |
|
||||
|
||||
A source reference has exactly `source_id`, `start_unit_id`, and `end_unit_id`.
|
||||
The source ID identifies the transcript, unit IDs are positive inclusive unit
|
||||
identifiers, and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"npcs": [
|
||||
{
|
||||
"id": "npc:sha256:99a16589618a04f535a7d21fdcc71a0b1c05d22f752cd492065b1086d97bc3d7",
|
||||
"name": "Mira Thorn",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 4, "end_unit_id": 5}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The ID is deterministic: normalize the name to Unicode NFKC, normalize the
|
||||
supported apostrophe forms, collapse whitespace, case-fold it, SHA-256 the
|
||||
result, then prefix the lowercase hexadecimal digest with `npc:sha256:`. Each
|
||||
canonical identity and ID appears at most once. Normalization collapses records
|
||||
with the same canonical identity, retains their earliest position, and merges
|
||||
their canonicalized evidence; it does not add aliases, roles, descriptions, or
|
||||
relationship fields.
|
||||
|
||||
## Scope and consumers
|
||||
|
||||
Only individually identifiable NPC names with transcript evidence belong in
|
||||
this artifact. Groups, generic roles, invented labels, and descriptive
|
||||
enrichment are excluded. Its source references prove registry provenance; they
|
||||
do not become evidence for a spell, interaction, or combat occurrence.
|
||||
|
||||
This registry can ground actor or caster names in the [spell](dnd-spell-artifacts.md)
|
||||
and [combat-turn](dnd-combat-turn-artifacts.md) artifacts. It is required to
|
||||
resolve the canonical `name` in an [NPC interaction](dnd-npc-interaction-artifacts.md).
|
||||
The [JSON output contract](json-output.md) defines publication, and
|
||||
[D&D module internals](../internal/dnd.md) owns pipeline mechanics.
|
||||
@@ -1,7 +1,7 @@
|
||||
# D&D NPC Interaction Artifact
|
||||
# D&D NPC Occurrence Artifact
|
||||
|
||||
This contract defines the durable occurrence list produced by
|
||||
`dnd/npc-interactions`. It records discrete, source-grounded interactions with
|
||||
`dnd/npc-occurrences`. It records discrete, source-grounded occurrences with
|
||||
NPCs already present in a normalized registry; it does not extend that registry
|
||||
or summarize the session.
|
||||
|
||||
@@ -9,35 +9,37 @@ or summarize the session.
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/npc-interaction-list` |
|
||||
| Schema ID | `notarius.dnd.npc_interactions` |
|
||||
| Schema name | `notarius_dnd_npc_interactions_v1` |
|
||||
| Artifact kind | `dnd/npc-occurrence-list` |
|
||||
| Schema ID | `notarius.dnd.npc_occurrences` |
|
||||
| Schema name | `notarius_dnd_npc_occurrences_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
|
||||
`v1` is a strict JSON object with required `interactions`; the array may be
|
||||
empty. Interaction and source-reference objects reject unknown fields. An
|
||||
`v1` is a strict JSON object with required `occurrences`; the array may be
|
||||
empty. Occurrence and source-reference objects reject unknown fields. An
|
||||
incompatible shape change requires a new schema version.
|
||||
|
||||
## Wire shape
|
||||
|
||||
Each interaction has these required fields:
|
||||
Each occurrence has these required fields:
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `npc_id` | Exact durable ID from the required NPC registry. |
|
||||
| `name` | Non-empty canonical display name from the required NPC registry. |
|
||||
| `kind` | One of the interaction categories below. |
|
||||
| `kind` | One of the occurrence categories below. |
|
||||
| `source_refs` | One or more transcript evidence ranges. |
|
||||
|
||||
Each source reference has exactly `source_id`, `start_unit_id`, and
|
||||
`end_unit_id`. It identifies an inclusive range in the current transcript;
|
||||
unit IDs are positive and the start may not follow the end. Extraction evidence
|
||||
for an interaction is confined to its accepted chunk.
|
||||
for an occurrence is confined to its accepted chunk.
|
||||
|
||||
```json
|
||||
{
|
||||
"interactions": [
|
||||
"occurrences": [
|
||||
{
|
||||
"npc_id": "npc:sha256:example",
|
||||
"name": "Mira Thorn",
|
||||
"kind": "dialogue",
|
||||
"source_refs": [
|
||||
@@ -48,7 +50,7 @@ for an interaction is confined to its accepted chunk.
|
||||
}
|
||||
```
|
||||
|
||||
## Interaction categories
|
||||
## Occurrence categories
|
||||
|
||||
| Kind | Meaning |
|
||||
| --- | --- |
|
||||
@@ -65,14 +67,24 @@ for uncertain classification.
|
||||
|
||||
## Identity, evidence, and order
|
||||
|
||||
The required normalized [NPC artifact](dnd-npc-artifacts.md) resolves `name`.
|
||||
Registry references are provenance only and never replace an interaction's own
|
||||
evidence. Normalization canonicalizes recognized registry names, orders and
|
||||
deduplicates exact source references, then orders interactions by valid source
|
||||
The required normalized [NPC registry artifact](dnd-npc-registry-artifacts.md)
|
||||
supplies names-only contextual grounding to the model. Notarius resolves the
|
||||
selected name and writes the exact `{npc_id, name}` pair. An unknown or
|
||||
ambiguous selection rejects the complete model result; normalization does not
|
||||
repair names by similarity. Registry references are provenance only and never
|
||||
replace an occurrence's own evidence.
|
||||
The registry may include an identity established by a factual third-party
|
||||
mention; that provenance alone does not create a `mentioned` occurrence. Each
|
||||
occurrence remains a separately cited fact in the current transcript.
|
||||
Normalization validates the exact pair, orders and
|
||||
deduplicates exact source references, then orders occurrences by valid source
|
||||
chronology, NPC comparison identity, display name, kind, and reference sequence.
|
||||
Only entries with the same canonical name, kind, and complete valid evidence
|
||||
Only entries with the same NPC ID, canonical name, kind, and complete valid evidence
|
||||
sequence are collapsed; distinct categories or evidence remain separate.
|
||||
|
||||
See the [combat-turn artifact](dnd-combat-turn-artifacts.md) for combat-action
|
||||
occurrences and the [JSON output contract](json-output.md) for publication.
|
||||
Pipeline mechanics are described in [D&D module internals](../internal/dnd.md).
|
||||
occurrences. The [enemy-event artifact](dnd-enemy-event-artifacts.md) consumes
|
||||
only `combat_opponent` occurrences as grounding; they never establish an enemy
|
||||
event or outcome. The [JSON output contract](json-output.md) defines
|
||||
publication. Pipeline mechanics are described in
|
||||
[D&D module internals](../internal/dnd.md).
|
||||
92
docs/integrations/dnd-npc-registry-artifacts.md
Normal file
92
docs/integrations/dnd-npc-registry-artifacts.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# D&D NPC Registry Artifact
|
||||
|
||||
This contract defines the durable NPC registry produced by `dnd/npc-registry`. It is a
|
||||
minimal, source-grounded identity registry for other D&D artifacts, not a
|
||||
character sheet or a relationship summary.
|
||||
|
||||
## Identity and compatibility
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Artifact kind | `dnd/npc-registry` |
|
||||
| Schema ID | `notarius.dnd.npc_registry` |
|
||||
| Schema name | `notarius_dnd_npc_registry_v1` |
|
||||
| Schema version | `v1` |
|
||||
| Media type | `application/json` |
|
||||
| Identity policy | `dnd.npc_registry.identity.v1` |
|
||||
|
||||
`v1` accepts one strict JSON object with required `npcs`; the array may be
|
||||
empty. NPC and source-reference objects reject unknown fields. An incompatible
|
||||
artifact shape or identity-policy change uses a new version or policy.
|
||||
|
||||
## Wire shape and identity
|
||||
|
||||
Each NPC has these required fields:
|
||||
|
||||
| Field | Contract |
|
||||
| --- | --- |
|
||||
| `id` | `npc:sha256:` followed by 64 lowercase hexadecimal characters. |
|
||||
| `name` | Non-empty canonical display name. |
|
||||
| `source_refs` | One or more transcript evidence ranges for the identity. |
|
||||
|
||||
A source reference has exactly `source_id`, `start_unit_id`, and `end_unit_id`.
|
||||
The source ID identifies the transcript, unit IDs are positive inclusive unit
|
||||
identifiers, and the start may not follow the end.
|
||||
|
||||
```json
|
||||
{
|
||||
"npcs": [
|
||||
{
|
||||
"id": "npc:sha256:35ba5f679aee69e07ae3bd65c44278f29539d5dc9bb5225db1c0060555b23221",
|
||||
"name": "Mira Thorn",
|
||||
"source_refs": [
|
||||
{"source_id": "session-7", "start_unit_id": 4, "end_unit_id": 5}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The ID is deterministic: normalize the name to Unicode NFKC, normalize the
|
||||
supported apostrophe forms, collapse whitespace, case-fold it, then serialize
|
||||
`["dnd.npc_registry.identity.v1", comparison_name]` as compact JSON. SHA-256
|
||||
those UTF-8 bytes and prefix the lowercase hexadecimal digest with
|
||||
`npc:sha256:`. Each canonical identity and ID appears at most once.
|
||||
Normalization collapses records with the same canonical identity, retains their
|
||||
earliest position, and merges
|
||||
their canonicalized evidence; it does not add aliases, roles, descriptions, or
|
||||
relationship fields.
|
||||
|
||||
When evidence supports a semantically duplicate group, the canonical display
|
||||
name is one of that group's supplied candidates. A complete, stable proper name
|
||||
is preferred over an abbreviation. An unadorned proper name is preferred over
|
||||
the same name plus a contextual class, role, title, or relationship descriptor
|
||||
unless the transcript establishes that descriptor as part of the person's
|
||||
name. A longer candidate is not preferred solely because it includes such a
|
||||
descriptor.
|
||||
|
||||
## Scope and consumers
|
||||
|
||||
Only individually identifiable NPC names with transcript evidence belong in
|
||||
this artifact. A factual third-party mention can establish an identity even if
|
||||
the NPC is not present, speaking, or acting in the cited passage. Names used
|
||||
only in hypothetical, speculative, or imagined examples are excluded, as are
|
||||
groups, generic roles, invented labels, and descriptive enrichment. Its source
|
||||
references prove registry provenance; they do not become evidence for a spell,
|
||||
occurrence, combat, or enemy-event occurrence.
|
||||
|
||||
Registry evidence establishes an identity, not an [NPC occurrence](dnd-npc-occurrence-artifacts.md).
|
||||
That later artifact independently records any current-transcript occurrence
|
||||
with its own cited evidence and category.
|
||||
|
||||
This registry can ground actor or caster names in the [spell](dnd-spell-artifacts.md)
|
||||
and [combat-turn](dnd-combat-turn-artifacts.md) artifacts. It is required to
|
||||
resolve the canonical `name` in an [NPC occurrence](dnd-npc-occurrence-artifacts.md).
|
||||
Occurrence consumers receive names-only grounding; Notarius resolves the
|
||||
selected canonical name and writes the unchanged exact durable ID/name pair.
|
||||
Spells, combat turns, and the [enemy-event artifact](dnd-enemy-event-artifacts.md)
|
||||
also receive names-only grounding for actor or subject display. None of these
|
||||
projections supply later-artifact evidence. [Configuration](../config.md#d-d-reference-slots)
|
||||
owns the `npc_registry` binding rules.
|
||||
The [JSON output contract](json-output.md) defines publication, and
|
||||
[D&D module internals](../internal/dnd.md) owns pipeline mechanics.
|
||||
@@ -62,8 +62,9 @@ durable fields, or the same source range with different kind, title, or
|
||||
summary, is invalid. It does not merge adjacent ranges, alter prose, or infer
|
||||
missing scenes.
|
||||
|
||||
The [combat-turn artifact](dnd-combat-turn-artifacts.md) uses an exact matching
|
||||
The [combat-turn artifact](dnd-combat-turn-artifacts.md) and
|
||||
[enemy-event artifact](dnd-enemy-event-artifacts.md) use an exact matching
|
||||
`combat` scene only as eligibility control; scene title, summary, and source
|
||||
reference never become combat evidence. Publication is defined by the
|
||||
reference never become their evidence. Publication is defined by the
|
||||
[JSON output contract](json-output.md); implementation details live in
|
||||
[D&D module internals](../internal/dnd.md).
|
||||
|
||||
@@ -61,7 +61,7 @@ only when it has the same canonical spell, the same case- and
|
||||
whitespace-insensitive caster identity, and the same complete valid reference
|
||||
sequence. Remaining entries retain their merged order.
|
||||
|
||||
The optional normalized [NPC artifact](dnd-npc-artifacts.md) can ground a
|
||||
The optional normalized [NPC registry artifact](dnd-npc-registry-artifacts.md) can ground a
|
||||
caster name. Its own references remain registry provenance and are never copied
|
||||
into `source_refs`.
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@ including a collision with the embedded catalog. Matching uses the catalog’s
|
||||
case, whitespace, and apostrophe normalization, so authors should avoid names
|
||||
or aliases that normalize to another spell.
|
||||
|
||||
Spell extraction receives the effective catalog as deterministic canonical-name
|
||||
and alias pairs. An alias in the transcript selects its associated canonical
|
||||
name; the extractor is instructed to return that canonical spelling. The
|
||||
projection contains no catalog source metadata or provenance, and aliases
|
||||
remain recognition context rather than transcript evidence.
|
||||
|
||||
The overlay is a recognition aid only. The durable spell-artifact schema and
|
||||
source-evidence rules are defined by the
|
||||
[D&D spell artifact contract](dnd-spell-artifacts.md).
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# Published Evidence Context
|
||||
|
||||
This contract defines the optional `source/evidence-context` artifact emitted
|
||||
by the production JSON output. Its configuration is owned by
|
||||
[Configuration](../config.md#module-bindings-and-validators); its logical-file
|
||||
discovery is owned by [Published JSON Output](json-output.md).
|
||||
by the production JSON output. It is a selected source-unit excerpt for
|
||||
convenient reading alongside normalized lane artifacts; it is not a second
|
||||
citation or provenance model. Its configuration is owned by
|
||||
[Configuration](../config.md#module-bindings-and-validators), and its
|
||||
logical-file discovery is owned by [Published JSON Output](json-output.md).
|
||||
|
||||
## Identity And Discovery
|
||||
|
||||
@@ -26,35 +28,13 @@ its absence means evidence publication was not enabled for that bundle.
|
||||
|
||||
## Payload
|
||||
|
||||
The v1 payload is a JSON object with required `source_id`, `source_digest`,
|
||||
`window_units`, `selected_lanes`, and `contexts` fields. `selected_lanes` and
|
||||
`contexts` are always arrays; an enabled configuration with no accepted direct
|
||||
evidence publishes `contexts: []`.
|
||||
The v1 payload is a top-level JSON array of generic source units. There is no
|
||||
wrapper, source-level metadata, context grouping, lane identifier, or evidence
|
||||
reference in the payload. An enabled configuration with no contributing
|
||||
accepted evidence publishes `[]`.
|
||||
|
||||
```json
|
||||
{
|
||||
"source_id": "session-alpha",
|
||||
"source_digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
||||
"window_units": 1,
|
||||
"selected_lanes": ["npcs", "spells"],
|
||||
"contexts": [
|
||||
{
|
||||
"context_ref": {
|
||||
"source_id": "session-alpha",
|
||||
"start_unit_id": 10,
|
||||
"end_unit_id": 20
|
||||
},
|
||||
"evidence_refs": [
|
||||
{
|
||||
"lane_id": "spells",
|
||||
"source_ref": {
|
||||
"source_id": "session-alpha",
|
||||
"start_unit_id": 10,
|
||||
"end_unit_id": 10
|
||||
}
|
||||
}
|
||||
],
|
||||
"units": [
|
||||
[
|
||||
{
|
||||
"id": 10,
|
||||
"kind": "transcript_segment",
|
||||
@@ -76,41 +56,52 @@ evidence publishes `contexts: []`.
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Each context requires a `context_ref` object and `evidence_refs` and `units`
|
||||
arrays. `context_ref` identifies the first and last included unit. Each
|
||||
evidence entry contains a selected `lane_id` and an original `source_ref`. A
|
||||
unit uses the existing source-unit shape: required `id`, `kind`, `text`, and
|
||||
self `ref`, plus optional JSON-object `metadata`. Fixed payload objects reject
|
||||
unknown fields; unit metadata may contain application-defined JSON values.
|
||||
Each source unit has required `id`, `kind`, `text`, and self `ref` fields.
|
||||
`ref` contains `source_id`, `start_unit_id`, and `end_unit_id`, and both unit
|
||||
endpoints identify that unit's `id`. A unit may also contain source-owned
|
||||
`metadata`, an open-ended JSON object. Fixed unit and reference fields are
|
||||
strict: consumers must reject unknown fixed fields, malformed units, invalid
|
||||
self-references, units whose `source_id` differs from other units in the same
|
||||
excerpt, and a payload that is not the array described here.
|
||||
|
||||
## Citations And Context
|
||||
The excerpt preserves each selected unit exactly as represented by the
|
||||
validated generic source document. It does not add evidence-context-specific
|
||||
annotations or reshape source-owned metadata.
|
||||
|
||||
`evidence_refs` are the authoritative citations. They identify the direct
|
||||
references emitted by accepted normalized artifacts. `context_ref` and the
|
||||
units collection include those cited units plus nearby source units selected by
|
||||
the configured window. They are explanatory context, not widened citations.
|
||||
## Selection And Citations
|
||||
|
||||
Only accepted outputs from the configured lane allowlist contribute. Rejected,
|
||||
failed, absent, and lane-filtered outputs do not contribute. The artifact never
|
||||
contains raw input bytes, prompts, model responses, auxiliary reference
|
||||
content, credentials, or filesystem paths.
|
||||
The framework obtains direct source references only through typed evidence
|
||||
projections of accepted normalized artifacts in the configured lane allowlist.
|
||||
It validates each reference against the current source document, expands its
|
||||
range by `window_units` source-unit positions on each side, clamps at document
|
||||
boundaries, and takes the union of all expanded ranges. The output contains
|
||||
each selected source unit once in source-document position order, regardless
|
||||
of numeric unit IDs. Repeated references, overlapping windows, and citations
|
||||
from multiple lanes do not duplicate a unit. Rejected, failed, absent,
|
||||
inactive, and unselected lanes contribute nothing.
|
||||
|
||||
## Ordering And Compatibility
|
||||
Normalized lane artifacts remain authoritative for citations and for which lane
|
||||
cited a range. The excerpt has no lane attribution and must not be used to
|
||||
reconstruct it. Its included nearby units provide reading context only; they
|
||||
do not widen any citation in a lane artifact.
|
||||
|
||||
The selected lane allowlist is lexical. Contexts and units are in source
|
||||
document position order, not numeric unit-ID order. Direct evidence entries
|
||||
are deterministically ordered by lane and source reference. Overlapping or
|
||||
contiguous windows merge, and each source unit appears at most once in the
|
||||
resulting contexts.
|
||||
The excerpt contains at most every generic source unit once. It can therefore
|
||||
equal the complete generic source document when coverage is broad or the
|
||||
window is large. No byte-, token-, or compression-size guarantee is made, and
|
||||
the framework does not truncate the excerpt to meet an arbitrary size limit.
|
||||
|
||||
## Consumer Responsibilities And Data Handling
|
||||
|
||||
The artifact is additive to the JSON bundle and is not a lane payload,
|
||||
normalized-output count, checkpoint, or generated reference. Consumers that
|
||||
do not need it must tolerate the absent optional descriptor. Consumers that do
|
||||
use it should preserve the artifact and its schema identity with the run
|
||||
provenance, and should treat its source text and metadata as sensitive durable
|
||||
content.
|
||||
do not need it must tolerate an absent descriptor. Consumers that do use it
|
||||
should validate the descriptor and payload before use, retain the artifact with
|
||||
its schema identity when needed for a run record, and read citations from the
|
||||
corresponding normalized lane artifacts.
|
||||
|
||||
The excerpt contains source-unit text and source-owned metadata and is durable
|
||||
output. Treat it as sensitive source content, apply appropriate access controls
|
||||
and retention, and do not assume its selected form is materially smaller or
|
||||
less sensitive than the original input.
|
||||
|
||||
@@ -24,7 +24,7 @@ root for the logical discovery described here.
|
||||
| `warnings.json` | Accepted-output and run warnings. |
|
||||
| `lanes/<safe-lane-id>.json` | One normalized artifact payload for each lane. |
|
||||
| `chunk-map.json` | Optional accepted chunk map, when its export is enabled and available. |
|
||||
| `evidence-context.json` | Optional source-context artifact, when evidence publication is enabled. |
|
||||
| `evidence-context.json` | Optional selected source-unit excerpt, when evidence publication is enabled. |
|
||||
|
||||
JSON files are pretty-printed with a trailing newline. Lane payloads are
|
||||
accepted only when their media type is `application/json`.
|
||||
@@ -71,11 +71,15 @@ output encoding fail.
|
||||
Each `lanes/<safe-lane-id>.json` file is the codec-owned normalized JSON for
|
||||
that lane. Consumers should use the index descriptor’s schema identity rather
|
||||
than infer a lane schema from its name. The current D&D payload contracts are
|
||||
[spells](dnd-spell-artifacts.md), [NPCs](dnd-npc-artifacts.md),
|
||||
[NPC interactions](dnd-npc-interaction-artifacts.md),
|
||||
[spells](dnd-spell-artifacts.md), [NPC registry](dnd-npc-registry-artifacts.md),
|
||||
[NPC occurrences](dnd-npc-occurrence-artifacts.md),
|
||||
[combat turns](dnd-combat-turn-artifacts.md),
|
||||
[item events](dnd-item-event-artifacts.md), and
|
||||
[scene descriptions](dnd-scene-description-artifacts.md).
|
||||
[item registry](dnd-item-registry-artifacts.md),
|
||||
[item occurrences](dnd-item-occurrence-artifacts.md),
|
||||
[scene descriptions](dnd-scene-description-artifacts.md),
|
||||
[enemy events](dnd-enemy-event-artifacts.md),
|
||||
[location registry](dnd-location-registry-artifacts.md), and
|
||||
[location occurrences](dnd-location-occurrence-artifacts.md).
|
||||
|
||||
## `manifest.json`
|
||||
|
||||
@@ -88,7 +92,7 @@ group into the following externally observable summaries:
|
||||
| Run identity and result | `run_id`, `pipeline_id`, `pipeline_digest`, `schema_version`, `validation_status`, `started_at`, `completed_at` |
|
||||
| Resolved components | `input_module`, `chunker`, `extractors`, `merger`, `normalizer`, `output_encoder`, `artifact_lanes`, `validator_chains`, `module_metadata` |
|
||||
| Source and references | `source_digests`, `references` |
|
||||
| Published result summaries | `normalized_outputs`, `rejected_outputs` |
|
||||
| Published result summaries | `normalized_outputs`, `rejected_outputs`, `validation_summaries` |
|
||||
| Execution summaries | `chunk_plan`, `checkpoint_decisions`, `llm_profiles`, `metadata` |
|
||||
|
||||
`references` records provenance such as the target, slot, origin, digest,
|
||||
@@ -98,12 +102,45 @@ summarize results without embedding lane payload bytes. A chunk-plan summary is
|
||||
provenance for the plan used by this run; cache records, debug artifacts, and
|
||||
other operational state are not published as bundle files.
|
||||
|
||||
Each `validation_summaries` entry is a bounded outcome for one producer result.
|
||||
It has required `status`, `producer_attempt_count`, and `terminal_action`;
|
||||
the stage and affected step, lane, module, or chunk identity are present when
|
||||
applicable. `status` is `complete`, `rejected`, or `incomplete`.
|
||||
`rejecting_validators`, `reason_codes`, and `incomplete_validators` preserve
|
||||
configured validator order and omit later duplicates. Entries contain no raw
|
||||
candidate response, correction guidance, validator diagnostic message, or
|
||||
artifact payload. The same shape may appear as `validation` on an affected
|
||||
rejection entry.
|
||||
|
||||
When present, `metadata.session_id` is the effective non-secret routing
|
||||
correlation identifier used for the run. It can be visible to providers and is
|
||||
not a substitute for a cache or checkpoint identity. Its generation and
|
||||
override behavior are defined by the [CLI reference](../cli.md#run).
|
||||
|
||||
Each `llm_profiles` entry identifies effective, non-secret LLM execution
|
||||
provenance:
|
||||
|
||||
| Field | Required | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `id` | Yes | Selected PromptKit profile identifier. |
|
||||
| `provider` | No | Notarius adapter provider identifier. |
|
||||
| `model` | No | Effective provider model identifier. |
|
||||
| `backend_id` | No | Effective PromptKit backend registration identifier. Endpoint-only profiles omit it. |
|
||||
| `reasoning_effort` | No | Effective opaque provider reasoning setting. An empty or explicitly cleared setting is omitted. |
|
||||
|
||||
These values describe observed execution; they are not a backend-registration
|
||||
interface. Entries that differ by backend or effective reasoning remain
|
||||
distinct even when their profile, provider, and model are otherwise equal.
|
||||
|
||||
## Rejections And Warnings
|
||||
|
||||
`rejected.json` is always an object with a `rejected` array. Each entry has
|
||||
required `stage` and `message`; `step_id`, `lane_id`, `module_key`, `chunk_id`,
|
||||
`chunk_index`, `validator_name`, `reason_code`, `attempt_count`, and
|
||||
`diagnostic_artifact_path` are present only when applicable.
|
||||
`diagnostic_artifact_path` are present only when applicable. An entry may also
|
||||
contain the bounded `validation` summary described above; the existing singular
|
||||
validator and reason fields remain the first configured rejection for
|
||||
compatibility.
|
||||
|
||||
`warnings.json` is always an object with a `warnings` array. Each warning has
|
||||
`reason_code` and `message`; `scope` is optional. Both arrays are empty when
|
||||
|
||||
148
docs/integrations/pkg-promptkit.md
Normal file
148
docs/integrations/pkg-promptkit.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# PromptKit Integration
|
||||
|
||||
Notarius pins
|
||||
[`gitea.maximumdirect.net/eric/promptkit` v0.9.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0)
|
||||
as its in-process prompt engine. The upstream
|
||||
[Go package consumer guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/consumers/pkg-promptkit.md)
|
||||
owns the public engine API, and the upstream
|
||||
[format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md)
|
||||
owns prompt, profile, and schema file contracts.
|
||||
|
||||
## Supported Boundary
|
||||
|
||||
Notarius relies on the root `promptkit` package to:
|
||||
|
||||
- construct an `Engine` with filesystem-backed prompt, schema, and optional
|
||||
operator and application-fallback profile sources;
|
||||
- prepare one frozen execution from a `RunRequest` with named inline artifacts,
|
||||
variables, a direct session ID, prompt identity, profile selection, and
|
||||
optional appended rendered messages, then
|
||||
record credential-redacted details and run that exact execution;
|
||||
- return rendered debug material, validated structured output, selected
|
||||
profile, backend, effective model metadata, and token usage;
|
||||
- register the optional conventional `local` backend through `BackendLocal`,
|
||||
`LocalBackend`, and `WithBackend`;
|
||||
- distinguish structured-output validation failure from execution failure; and
|
||||
- identify a missing explicit profile through `ErrProfileNotFound` and backend
|
||||
admission exhaustion through `ErrCapacityExceeded`.
|
||||
|
||||
The pinned
|
||||
[`BackendLocal`, `LocalBackend`, and `WithBackend` API](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/backends.go)
|
||||
owns the registration and backend-capacity contract.
|
||||
|
||||
For one completion, the adapter calls `PrepareExecution`, takes a
|
||||
caller-owned `Details` snapshot, and calls `RunPrepared` for that same opaque
|
||||
prepared execution. It defers `Discard` for every unexecuted handle. Explicit
|
||||
profile preflight uses `Engine.InspectProfile`; it does not prepare a synthetic
|
||||
prompt. PromptKit's prepared handle, inspection result, and capacity-error
|
||||
types stay inside the Notarius LLM adapter.
|
||||
|
||||
When a PromptKit profile and runtime override leave `temperature`, `max_tokens`,
|
||||
or `top_p` unset, Notarius leaves that control unset as well. Compatible
|
||||
providers therefore apply their own defaults; an operator that requires a
|
||||
specific sampling value must select it explicitly in the profile or runtime
|
||||
override.
|
||||
|
||||
Notarius does not use PromptKit's optional `ArtifactReader`. It materializes
|
||||
source and reference content itself and supplies owned inline artifacts at the
|
||||
adapter boundary. It also retains responsibility for pipeline retries,
|
||||
scheduling, debug persistence, redaction, profile provenance, and conversion
|
||||
from private model responses into durable domain artifacts.
|
||||
|
||||
Notarius sends one stable effective session through PromptKit's direct session
|
||||
field, which is authoritative for provider session behavior. It also retains
|
||||
the same value as the `session_id` prompt variable for maintained prompt
|
||||
compatibility. The generated identifier is 76 ASCII characters, within
|
||||
PromptKit v0.9.0's 256-code-point session limit. Session IDs are non-secret
|
||||
correlation identifiers and may be exposed to providers and provider
|
||||
observability. The CLI contract owns generation and override behavior.
|
||||
|
||||
Notarius records PromptKit's selected backend ID and effective reasoning
|
||||
setting as optional run-manifest provenance. Endpoint-only profiles have no
|
||||
backend ID. Debug prompt material also retains the selected backend ID and
|
||||
PromptKit's stable lower-case `effective_model_params` JSON, which may include
|
||||
`backend_id`. Notarius production configuration exposes one optional
|
||||
conventional `local` registration. It does not expose a general user-defined
|
||||
PromptKit backend registry. Endpoint-only profiles remain supported unchanged.
|
||||
|
||||
Notarius retains its application-wide scheduled client around the PromptKit
|
||||
adapter. PromptKit may apply a narrower limit for the selected backend;
|
||||
endpoint-only profiles have no such backend limit. The adapter translates
|
||||
PromptKit capacity rejection into the provider-neutral Notarius
|
||||
`ErrLLMCapacityExceeded` contract. It may include the normalized selected
|
||||
backend ID in safe diagnostic context, without exposing PromptKit's capacity
|
||||
error type, and leaves retries to the calling pipeline stage.
|
||||
|
||||
## Profile Sources And Compatibility
|
||||
|
||||
Notarius gives PromptKit the configured operator profile source, registered
|
||||
application fallback profile assets, and optional backend registration through
|
||||
the same construction path for inspection and execution. PromptKit owns the
|
||||
resulting source precedence and strict profile parsing: a matching operator
|
||||
profile is a complete replacement for a fallback or built-in profile, while an
|
||||
invalid matching document fails instead of falling through. The operator
|
||||
configuration and deployment workflow are defined in
|
||||
[Configuration](../config.md#promptkit-profiles) and
|
||||
[Operations](../operations.md#promptkit-profile-deployment).
|
||||
|
||||
PromptKit owns `base_profile` resolution under its
|
||||
[pinned format rules](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.9.0/docs/formats.md).
|
||||
Notarius records the selected leaf identity and resolved target without parsing
|
||||
or merging inheritance. An unset filesystem `api_key_env` is optional and may
|
||||
reach the provider without authorization, which can result in a 401 or 403.
|
||||
|
||||
PromptKit v0.9.0 accepts only the `developer`, `system`, `user`, and
|
||||
`assistant` text-chat roles after normalizing case and surrounding whitespace.
|
||||
Maintained Notarius prompt definitions use only `system` and `user`.
|
||||
|
||||
For application-owned semantic correction, Notarius uses PromptKit v0.9.0's
|
||||
`RunRequest.AppendedMessages` after the ordinary rendered prompt. It supplies
|
||||
exactly two messages in order: the latest validated producer response with
|
||||
role `assistant`, then deterministic validation guidance with role `user`.
|
||||
It never exposes a general caller-selected role API, accumulates earlier
|
||||
correction turns, or changes the ordinary prompt prefix. Ordinary requests
|
||||
leave appended messages unset.
|
||||
|
||||
PromptKit preserves supplied content but does not own Notarius's correction
|
||||
bounds. Notarius rejects invalid UTF-8, blank, or oversized assistant material
|
||||
(at most 1 MiB), guidance (at most 64 KiB), and combined content (at most
|
||||
1,114,112 bytes) before preparing the request. The transport-neutral
|
||||
application contract owns defensive copying and these limits. Default request
|
||||
and terminal summaries retain only safe counts, digests, identities, and usage;
|
||||
complete appended messages remain limited to the explicitly requested detailed
|
||||
debug trace.
|
||||
|
||||
PromptKit now obtains its maintained OpenRouter and Rakestrawhome backend and
|
||||
profile catalogs from independently versioned transitive modules. Notarius
|
||||
does not import or register either catalog; PromptKit retains catalog source,
|
||||
identity, precedence, credential, and capacity ownership.
|
||||
|
||||
Notarius supports this boundary against PromptKit v0.9.0. Its fallback source,
|
||||
prepared-execution, inspection, and typed capacity APIs are used as public
|
||||
upstream contracts; other PromptKit APIs or file-format behavior are not
|
||||
implicitly supported. A dependency upgrade requires reviewing the adapter,
|
||||
profile-source construction, and this compatibility statement against the
|
||||
pinned upstream documentation.
|
||||
|
||||
## Notarius Ownership
|
||||
|
||||
[LLM Runtime Internals](../internal/llm.md) describes how Notarius mounts
|
||||
module assets, maps its transport-neutral completion contract, prepares and
|
||||
executes requests, validates output, records provenance, captures debug
|
||||
material, redacts errors, and preserves timeout ownership.
|
||||
|
||||
PromptKit provider error details do not cross the ordinary completion boundary.
|
||||
Notarius exposes a provider-neutral generation category and optional status;
|
||||
redacted provider details are retained only in requested debug material.
|
||||
[D&D Module Internals](../internal/dnd.md) owns the embedded
|
||||
`dnd-extraction` fallback profile and the maintained D&D prompt defaults.
|
||||
[Configuration](../config.md#promptkit-profiles) defines how a Notarius
|
||||
configuration selects one PromptKit profile source and optionally registers
|
||||
the conventional local backend.
|
||||
|
||||
PromptKit API or format changes outside this boundary are not implicitly
|
||||
supported. Updating the pinned version requires reviewing the adapter and
|
||||
profile/configuration contracts against the upstream documentation. Maintained
|
||||
production prompts use PromptKit's bounded structural-repair contract; their
|
||||
current declaration is one additional repair attempt. Notarius retains the
|
||||
transport-neutral boundary and does not expose PromptKit types to modules.
|
||||
@@ -22,11 +22,15 @@ The current schema version is `notarius.run-result.v1`.
|
||||
| `rejected_output_count` | Yes | Number of recorded rejected outputs. |
|
||||
| `warning_count` | Yes | Number of final run warnings. |
|
||||
| `validation_status` | Yes | The final run manifest validation status. |
|
||||
| `validation_summaries` | No | Bounded per-producer validation outcomes; present when producer work ran. |
|
||||
| `debug_directory` | No | Absolute path to the run-specific debug bundle when requested debug capture completed. |
|
||||
|
||||
For the production `json` output module, `index_file` is present only when the
|
||||
completed run returned exactly one logical output file named `index.json`.
|
||||
For another output module, its absence does not indicate a failed run.
|
||||
`validation_status` is `approved`, `rejected`, or `incomplete`; `incomplete`
|
||||
means one or more otherwise accepted results advanced under validator-failure
|
||||
`warn_continue`.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -38,7 +42,17 @@ For another output module, its absence does not indicate a failed run.
|
||||
"normalized_output_count": 6,
|
||||
"rejected_output_count": 2,
|
||||
"warning_count": 1,
|
||||
"validation_status": "rejected"
|
||||
"validation_status": "incomplete",
|
||||
"validation_summaries": [
|
||||
{
|
||||
"stage": "extract",
|
||||
"lane_id": "spells",
|
||||
"status": "incomplete",
|
||||
"incomplete_validators": ["dnd/spells/source_refs"],
|
||||
"producer_attempt_count": 1,
|
||||
"terminal_action": "warn_continue"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -48,8 +62,11 @@ For another output module, its absence does not indicate a failed run.
|
||||
paths. They identify the paths used by Notarius and do not resolve symlinks.
|
||||
`output_directory` is the run-specific bundle, not the configured output root.
|
||||
|
||||
The receipt is a summary and discovery document. It does not contain lane
|
||||
descriptors, payloads, manifest data, rejections, warnings, or file contents.
|
||||
The receipt is a summary and discovery document. Its optional validation
|
||||
summaries contain only stable status, identity, validator names, reason codes,
|
||||
attempt counts, and terminal actions. It does not contain lane descriptors,
|
||||
payloads, manifest payloads, rejection messages, warnings, raw model responses,
|
||||
correction guidance, or file contents.
|
||||
For the production JSON output, resolve `index_file` beneath
|
||||
`output_directory`, reject path escapes, and use the
|
||||
[Published JSON Output contract](json-output.md) to discover logical files and
|
||||
|
||||
@@ -24,10 +24,14 @@ preparation, and runner mechanics after their inputs are supplied.
|
||||
|
||||
## Dispatch And Configuration Handoff
|
||||
|
||||
The root dispatcher handles help, configuration validation, pipeline listing,
|
||||
and a pipeline run. It normalizes injectable options before dispatch so that a
|
||||
missing production dependency fails as a command error rather than reaching
|
||||
execution.
|
||||
The root dispatcher handles help, version reporting, configuration validation,
|
||||
pipeline listing, and a pipeline run. Version reporting resolves build
|
||||
information through `internal/buildinfo` before production composition, so the
|
||||
diagnostic remains available without configuration or runtime collaborators.
|
||||
The public syntax, streams, exit classes, and version semantics are defined by
|
||||
the [CLI reference](../cli.md). Other root commands normalize injectable
|
||||
options before dispatch so that a missing production dependency fails as a
|
||||
command error rather than reaching execution.
|
||||
|
||||
Commands that need configuration use one shared loader. The CLI discovers the
|
||||
file, parses it through **internal/core/config**, starts from defaults, applies
|
||||
@@ -38,9 +42,14 @@ in [Configuration Internals](configuration.md).
|
||||
|
||||
Configuration validation without a selected pipeline checks structural
|
||||
configuration only. Validation with a selected pipeline also builds the
|
||||
effective catalog, resolves the pipeline, and verifies explicitly selected
|
||||
Scriptorium profiles. Pipeline listing validates configuration before returning
|
||||
normalized, sorted identifiers.
|
||||
effective catalog, resolves the pipeline, and verifies every explicit effective
|
||||
PromptKit profile. Selected LLM-backed input, chunk, lane, output, and validator
|
||||
profiles are inspected
|
||||
against the configured PromptKit source and backend registrations without
|
||||
loading a prompt or performing generation, so an unknown or invalid profile
|
||||
fails before pipeline preparation. Credential availability remains an
|
||||
execution-time concern. Pipeline listing validates configuration before
|
||||
returning normalized, sorted identifiers.
|
||||
|
||||
## Production Composition
|
||||
|
||||
@@ -51,12 +60,24 @@ catalog used for resolution and the concrete constructors used for preparation.
|
||||
Tests may provide a catalog or registries instead; production code must not
|
||||
silently merge an injected partial catalog with production registrations.
|
||||
|
||||
The production LLM factory builds the Scriptorium-backed client from resolved
|
||||
configuration, creates one scheduler from the effective global LLM limit, and
|
||||
wraps the client before it reaches modules. Registration and LLM construction
|
||||
errors are returned before a pipeline is prepared. Concrete module keys and
|
||||
validator chains are public configuration choices and remain documented in
|
||||
[Configuration](../config.md).
|
||||
The production LLM factory builds one PromptKit-backed client from the resolved
|
||||
**promptkit.profile_dir** or **promptkit.profile_file** source, attaches the
|
||||
profile-provenance recorder, creates one scheduler from the effective global
|
||||
LLM limit, and wraps the client before it reaches modules. Registration and LLM
|
||||
construction errors are returned before a pipeline is prepared. Configuration
|
||||
field definitions remain in [Configuration](../config.md#promptkit-profiles);
|
||||
the D&D registrar's fallback profile assets and the adapter mechanics remain in
|
||||
[LLM Runtime](llm.md).
|
||||
|
||||
The factory also accepts `LLMRuntimeOverrides`, whose reasoning pointer
|
||||
preserves inherit, replace, and clear states across the composition boundary.
|
||||
Run orchestration constructs this value from the mutually exclusive
|
||||
`--reasoning-effort` and `--clear-reasoning-effort` controls. Absence preserves
|
||||
a nil pointer, replacement is trimmed, and clear uses a non-nil empty string.
|
||||
The same override reaches the one shared production client, checkpoint
|
||||
identity, and debug invocation metadata. Persistent reasoning configuration
|
||||
remains owned by PromptKit profiles; Notarius configuration has no reasoning
|
||||
field.
|
||||
|
||||
## Run Orchestration
|
||||
|
||||
@@ -68,12 +89,15 @@ handoff:
|
||||
2. create and validate a safe run identity, then allocate a debug bundle only
|
||||
when requested;
|
||||
3. build the effective catalog, resolve requested reference changes, resolve
|
||||
the effective pipeline, and verify explicit Scriptorium profiles;
|
||||
the effective pipeline, and inspect its explicit effective PromptKit
|
||||
profiles;
|
||||
4. materialize external or generated references and record redacted invocation
|
||||
and resolution provenance when debug capture is enabled;
|
||||
5. construct registries, the scheduled LLM client, prepared modules, and the
|
||||
requested cache/checkpoint collaborators;
|
||||
6. read the source input and invoke the framework runner; and
|
||||
5. construct registries, the scheduled LLM client, and prepared modules;
|
||||
6. read the source input once, resolve its effective session from the explicit
|
||||
override or resolved input module and raw bytes, then construct requested
|
||||
checkpoint collaborators and invoke the framework runner with that same
|
||||
value; and
|
||||
7. write the runner's logical output files only after a successful run, then
|
||||
complete the command report and user-facing result.
|
||||
|
||||
@@ -84,6 +108,13 @@ final command result. Detailed state lifecycle, resume handling, and physical
|
||||
path confinement are maintained in [Run State Internals](state.md) and
|
||||
[Operations](../operations.md).
|
||||
|
||||
The CLI owns the versioned generated-session policy and resolves the sole
|
||||
effective value before checkpoint construction. It records that value in the
|
||||
final debug invocation summary when capture is enabled and passes it unchanged
|
||||
to checkpoint identity and `pipeline.RunInput`. The public flag and stability
|
||||
contract are defined by the [CLI reference](../cli.md#run); framework and LLM
|
||||
packages only transport the supplied value.
|
||||
|
||||
For `run --json`, the CLI constructs and encodes its private run-result receipt
|
||||
after a successful runner result is available, before it publishes logical
|
||||
output files. It writes the prepared receipt to standard output only after
|
||||
|
||||
@@ -39,14 +39,22 @@ This establishes the public precedence order without giving environment input a
|
||||
second file schema. Loading and application reject malformed YAML, unsupported
|
||||
file versions, unknown fields, invalid values, and identifiers that are empty
|
||||
or collide after whitespace normalization. The file application also makes the
|
||||
effective extraction-worker default follow the effective LLM limit.
|
||||
effective extraction-worker default follow the effective LLM limit. A present
|
||||
PromptKit local-backend object requires and trims its endpoint, defaults its
|
||||
omitted concurrency limit to zero, and is copied so the parsed file model
|
||||
cannot alias the populated **Config**. A pipeline `llm_profile` is
|
||||
presence-aware: omission remains empty, while a present blank value is
|
||||
rejected and a non-empty file value is trimmed before it reaches **Config**.
|
||||
|
||||
**Config.Validate** checks configuration-only invariants before resolution. It
|
||||
rejects incompatible profile sources, invalid state-surface values, unsupported
|
||||
concurrency settings, malformed bindings and references, invalid retries, and
|
||||
invalid pipeline, step, or lane structure. Its errors retain the closest known
|
||||
pipeline, lane, and binding context. It deliberately does not require modules
|
||||
to be registered: that requires a catalog and belongs to resolution.
|
||||
invalid pipeline, step, or lane structure. PromptKit local-backend validation
|
||||
accepts only an absolute HTTP or HTTPS endpoint with a host and no user
|
||||
information, query, or fragment, and rejects a negative local concurrency
|
||||
limit. Its errors retain the closest known pipeline, lane, and binding context.
|
||||
It deliberately does not require modules to be registered: that requires a
|
||||
catalog and belongs to resolution.
|
||||
|
||||
The exact user-selectable values and validation rules are defined in
|
||||
[Configuration](../config.md). Keep additions to the file model, an
|
||||
@@ -56,22 +64,34 @@ environment override, its validation, and that reference in the same change.
|
||||
|
||||
**Config.Resolve** first recomputes derived concurrency defaults and validates
|
||||
the configuration. It normalizes the requested pipeline ID, copies the selected
|
||||
profile, applies a non-empty command-level LLM profile override to the
|
||||
LLM-capable stage bindings, and calls the framework resolver with the requested
|
||||
lane selection and reference changes.
|
||||
profile, and passes the non-empty command-level LLM profile override, requested
|
||||
lane selection, and reference changes to the framework resolver.
|
||||
|
||||
The command-level override does not replace an explicitly selected validator
|
||||
profile. Validator bindings remain part of the resolved validator chain and
|
||||
are resolved under their own declared configuration.
|
||||
After module and validator selection, the resolver applies the effective
|
||||
profile policy to LLM-backed bindings only: command override, binding profile,
|
||||
pipeline profile, then the prompt default. Deterministic bindings remain
|
||||
profile-free, and no second inheritance decision occurs during execution. The
|
||||
public field definitions and precedence are owned by
|
||||
[Configuration](../config.md#pipelines).
|
||||
|
||||
The resolver retains configured `validation_policy` overrides and derives one
|
||||
detached concrete terminal policy for the chunk producer and every lane's
|
||||
extract, merge, and normalize producers. That field-by-field inheritance is
|
||||
complete before preparation, and the effective values contribute to pipeline
|
||||
and checkpoint identity; execution does not interpret configuration defaults.
|
||||
|
||||
The framework resolver supplies defaults, selects lanes, resolves validator
|
||||
chains, checks registered module and artifact compatibility, validates module
|
||||
options, and returns the fixed ordered pipeline shape. The resulting
|
||||
**EffectiveConfig** retains the selected ID, requested selection and reference
|
||||
options, and returns the fixed ordered pipeline shape. Positive validator retry
|
||||
budgets require an LLM-backed selected validator; deterministic validators are
|
||||
rejected during resolution. Eligible LLM-backed producer specifications also
|
||||
contribute their declared correction protocol to the resolved metadata. The
|
||||
resulting **EffectiveConfig** retains the selected ID, requested selection and reference
|
||||
changes, a clone of the input configuration, and the resolved pipeline.
|
||||
Callers may therefore retain or modify their input slices and maps without
|
||||
changing the resolved result, and later consumers cannot mutate the original
|
||||
configuration through the effective value.
|
||||
configuration through the effective value. This ownership includes the nested
|
||||
PromptKit local-backend value.
|
||||
|
||||
Resolution failures stop before module construction and source parsing. They
|
||||
include an error path for an unconfigured pipeline, missing module, missing
|
||||
@@ -83,7 +103,8 @@ runtime error class described in the [CLI reference](../cli.md#output-streams-an
|
||||
|
||||
The framework assigns the resolved pipeline a deterministic SHA-256 digest
|
||||
after defaults, lane selection, module bindings, reference bindings, validator
|
||||
chains, and artifact schema identity have been resolved. The digest excludes
|
||||
chains, selected correction protocols, effective LLM profiles, and artifact
|
||||
schema identity have been resolved. The digest excludes
|
||||
its own stored value. It identifies resolved composition rather than raw YAML
|
||||
bytes, a debug payload, or all runtime state. The CLI records it as invocation
|
||||
provenance before execution; cache and checkpoint identity have additional
|
||||
@@ -94,9 +115,12 @@ Configuration summaries must use **Redacted**, **RedactedSummaryPayload**, or
|
||||
Those methods copy every binding and nested option container, replace values
|
||||
whose key is credential-shaped with **[REDACTED]**, and omit materialized
|
||||
reference content while retaining safe binding and reference provenance. The
|
||||
payload must not alias the source configuration or resolved pipeline. This
|
||||
redaction is deliberately narrow: it protects configuration summaries and does
|
||||
not authorize recording arbitrary environment values or provider requests.
|
||||
payload must not alias the source configuration or resolved pipeline.
|
||||
PromptKit's local endpoint and concurrency limit are preserved as non-secret
|
||||
configuration metadata in the independently owned summary; the object contains
|
||||
no credential value. This redaction is deliberately narrow: it protects
|
||||
configuration summaries and does not authorize recording arbitrary environment
|
||||
values or provider requests.
|
||||
|
||||
## Invariants To Preserve
|
||||
|
||||
|
||||
@@ -7,25 +7,36 @@ selectable keys, bindings, reference syntax, and default validator chains.
|
||||
|
||||
## Durable Artifact Contracts
|
||||
|
||||
The six lanes have separate durable wire contracts. This guide deliberately
|
||||
The ten lanes have separate durable wire contracts. This guide deliberately
|
||||
does not repeat their JSON shapes or schemas.
|
||||
|
||||
| Lane | Durable contract |
|
||||
| --- | --- |
|
||||
| Spells | [spell artifacts](../integrations/dnd-spell-artifacts.md) |
|
||||
| NPCs | [NPC artifacts](../integrations/dnd-npc-artifacts.md) |
|
||||
| NPC registry | [NPC registry artifacts](../integrations/dnd-npc-registry-artifacts.md) |
|
||||
| Combat turns | [combat-turn artifacts](../integrations/dnd-combat-turn-artifacts.md) |
|
||||
| Item events | [item-event artifacts](../integrations/dnd-item-event-artifacts.md) |
|
||||
| NPC interactions | [NPC-interaction artifacts](../integrations/dnd-npc-interaction-artifacts.md) |
|
||||
| Item occurrences | [item-occurrence artifacts](../integrations/dnd-item-occurrence-artifacts.md) |
|
||||
| Item registry | [item-registry artifacts](../integrations/dnd-item-registry-artifacts.md) |
|
||||
| NPC occurrences | [NPC-occurrence artifacts](../integrations/dnd-npc-occurrence-artifacts.md) |
|
||||
| Scene descriptions | [scene-description artifacts](../integrations/dnd-scene-description-artifacts.md) |
|
||||
| Enemy events | [enemy-event artifacts](../integrations/dnd-enemy-event-artifacts.md) |
|
||||
| Location registry | [location-registry artifacts](../integrations/dnd-location-registry-artifacts.md) |
|
||||
| Location occurrences | [location-occurrence artifacts](../integrations/dnd-location-occurrence-artifacts.md) |
|
||||
|
||||
## Family Composition
|
||||
|
||||
The D&D registrar registers the family’s artifact codecs, extractors, typed
|
||||
append-order mergers, normalizers, validators, prompt assets, and default
|
||||
validator chains. Each extractor and normalizer has a stable module spec,
|
||||
strict option decoding, and a typed builder. Configuration remains the
|
||||
canonical owner of the exact keys and validator order.
|
||||
append-order mergers, normalizers, validators, prompt assets, fallback LLM
|
||||
profile asset, and default validator chains. Each extractor and normalizer has
|
||||
a stable module spec, explicit execution class, strict option decoding, and a
|
||||
typed builder. Scene chunking, every extractor, and NPC, location, and item-registry
|
||||
normalization are registered as `llm_backed`; the remaining current D&D mergers
|
||||
and normalizers are `deterministic`. The metadata is available to catalog inspection and
|
||||
resolved-pipeline debug data and determines which selected bindings inherit the
|
||||
pipeline profile. The registry normalizers use `single_response_v1`, forwarding
|
||||
corrections to their reconciliation completion and retaining the accepted raw
|
||||
proposal only as an owned model candidate. Configuration remains the canonical owner of the exact keys,
|
||||
profile precedence, and validator order.
|
||||
|
||||
Private structured-LLM response schemas are deliberately minimal. They reject
|
||||
invalid JSON structure, missing required fields, incompatible types, and
|
||||
@@ -33,21 +44,78 @@ unknown fields, while preserving semantic candidates for deterministic
|
||||
validation. Do not promote a private response envelope into a durable schema;
|
||||
the contracts above define durable data.
|
||||
|
||||
A D&D producer that declares `single_response_v1` forwards any supplied
|
||||
semantic correction to its structured completion and returns an owned copy of
|
||||
that completion's exact validated raw response as its model candidate. It does
|
||||
not serialize normalized artifacts to create that candidate, so deterministic
|
||||
identity, evidence, warning, and durable-schema behavior remains separate from
|
||||
the model transport material.
|
||||
|
||||
## Prompt Construction
|
||||
|
||||
D&D extractors assemble prompts from an ordered manifest of shared and
|
||||
module-owned assets. Reuse the shared D&D system, evidence, identity,
|
||||
reference, and transcript assets instead of copying their text into individual
|
||||
modules. A manifest’s declared sequence, including cache-control placement, is
|
||||
part of the prompt behavior, and the chunk transcript is the final message.
|
||||
Preserve that order when changing an extractor or its assets so prompt-cache
|
||||
behavior remains stable.
|
||||
D&D LLM-facing content lives beneath `assets/dnd/`. Each module contributes a
|
||||
local `prompt.yaml` declaration and `instructions.md`; input-specific files
|
||||
such as a catalog, registry, grounding projection, or candidate collection are
|
||||
local only when that module needs them. New extractor content uses its feature
|
||||
subtree, while families with both extraction and normalization content use their
|
||||
`extract` and `normalize` subtrees. Shared visual-provenance fragments use
|
||||
the `common-dnd-` prefix. Production lane code belongs with its D&D codec,
|
||||
extractor, normalizer, and validator packages; registry projections and
|
||||
identity helpers remain in their owning entity packages rather than in a
|
||||
consumer lane.
|
||||
|
||||
All extractors use the shared prompt-input preparation rules. The current chunk
|
||||
is copied into transcript material; player, party, glossary, and compatible
|
||||
campaign references are context for disambiguation, not source evidence.
|
||||
Reference prompt material is canonically ordered before it is rendered, which
|
||||
keeps equivalent inputs stable across runs.
|
||||
The owning module’s manifest is the source of truth for which local and shared
|
||||
assets are selected, their mount paths, their message order, cache controls,
|
||||
and the files included in its prompt fingerprint. Shared fragments belong to
|
||||
the D&D shared implementation and are selected by name rather than copied into
|
||||
module directories. The root `assets` package is a content-only boundary; its
|
||||
physical ownership and rationale are defined by
|
||||
[ADR-0011](../adr/0011-centralize-llm-assets.md).
|
||||
|
||||
Put each rule at its narrowest owner:
|
||||
|
||||
- universal behavior belongs in the shared system asset;
|
||||
- D&D-family behavior belongs in a selected `common-dnd-` asset;
|
||||
- rules for an input projection belong with that input asset;
|
||||
- lane-specific policy belongs in the module’s `instructions.md`; and
|
||||
- transport-envelope shape belongs in the private response schema.
|
||||
|
||||
A rule is eligible for the system prompt only when every D&D LLM prompt needs
|
||||
it regardless of lane, inputs, or response shape. Module instructions must not
|
||||
repeat rules selected from shared assets or schemas. Reintroduce such repetition
|
||||
only after observational evaluation with representative transcripts shows that
|
||||
it improves results at the intended target models and cost; structural prompt
|
||||
tests alone are not that evidence.
|
||||
|
||||
Every maintained D&D LLM prompt selects `dnd-extraction` as its default
|
||||
profile. The D&D registrar registers the fallback, while an operator can
|
||||
replace it with a complete profile of the same ID from the configured PromptKit
|
||||
source. Deployment profile selection is documented in
|
||||
[Configuration](../config.md#promptkit-profiles).
|
||||
|
||||
The D&D transcript assets have distinct consumers. Scene chunking consumes the
|
||||
complete-session `common-dnd-transcript-full.md`, while extraction prompts
|
||||
consume the current-chunk `common-dnd-transcript-chunk.md`. NPC, location, and
|
||||
item normalization instead mount the generic semantic-reconciliation
|
||||
candidate and transcript-window presentation assets. Player, party, glossary,
|
||||
and compatible campaign references provide disambiguating context only when
|
||||
declared by the active prompt; they never establish evidence. Reference
|
||||
material is canonically ordered before rendering so equivalent inputs remain
|
||||
stable.
|
||||
|
||||
Extraction prompts render the common system and identity messages first, then
|
||||
cached campaign references and the cached chunk transcript. Evidence policy and
|
||||
any lane-specific registry, catalog, or grounding projection follow that
|
||||
prefix. The final module instructions message is ephemeral. This keeps the
|
||||
reusable extraction prefix identical while preserving the lane-specific suffix.
|
||||
|
||||
Scene chunking intentionally uses a different order: system, cached campaign
|
||||
references, uncached module instructions, then the final ephemeral full
|
||||
transcript. Entity normalization also has its own order: D&D system, mandatory
|
||||
generic protocol, ephemeral domain semantic instructions, generic candidate
|
||||
presentation, and final ephemeral generic transcript windows. These orders and
|
||||
cache controls are prompt behavior; change them only through the owning
|
||||
manifest and prompt declaration.
|
||||
|
||||
## Evidence, Candidates, And Normalization
|
||||
|
||||
@@ -60,19 +128,70 @@ result.
|
||||
|
||||
Default chains keep responsibilities separate: structural validators assess the
|
||||
candidate, source-reference validators resolve cited ranges against the current
|
||||
source, durable-schema validation checks an approved representation, and
|
||||
source and require extraction evidence to stay within the current chunk,
|
||||
durable-schema validation checks an approved representation, and
|
||||
relatedness validators report advisory evidence concerns. The configured order
|
||||
is documented in
|
||||
[Configuration](../config.md#production-validator-keys-and-default-chains).
|
||||
|
||||
Normalizers are deterministic for spells, combat turns, item events, NPC
|
||||
interactions, and scene descriptions. They canonicalize display values and
|
||||
evidence, use source-document order for stable output, and issue bounded
|
||||
warnings for changes or collapsed duplicates. The NPC normalizer is the
|
||||
intentional exception: it first produces a deterministic candidate set, then
|
||||
uses a bounded structured-LLM proposal to reconcile identity groups. Invalid
|
||||
or unusable proposals retain the deterministic result and surface retry or
|
||||
fallback diagnostics; the model does not directly replace durable records.
|
||||
Every D&D rejection describes the correction in transcript-grounded domain
|
||||
terms, using contextual names, artifact fields, and source segment ranges when
|
||||
useful. The guidance must not ask the model to reproduce durable entity IDs,
|
||||
hashes, validator module keys, or reason codes. Those identifiers remain in
|
||||
ordinary validation provenance; only the actionable semantic guidance is
|
||||
eligible for the correction prompt.
|
||||
|
||||
Enemy-event extraction additionally rejects a second `engaged` observation for
|
||||
the same comparison identity within one scene-scoped result. Normalization may
|
||||
combine results from distinct scenes, so it intentionally does not apply that
|
||||
rule. Configuration owns the exact validator key and chain position.
|
||||
|
||||
Normalizers are deterministic for spells, combat turns, item occurrences, NPC
|
||||
occurrences, scene descriptions, enemy events, and location occurrences. They
|
||||
canonicalize display values and evidence, use source-document order for stable
|
||||
output, and issue bounded warnings for changes or collapsed duplicates. NPC,
|
||||
item, and location registry normalizers are intentional exceptions: each first
|
||||
produces a deterministic candidate set, then may use a bounded structured-LLM
|
||||
proposal to reconcile identity groups.
|
||||
|
||||
## Semantic Registry Reconciliation
|
||||
|
||||
The three registry normalizers instantiate the domain-neutral
|
||||
`internal/framework/semanticreconcile` engine with default bounds. Each
|
||||
eligible candidate receives a contiguous, one-based `candidate_id` for that
|
||||
request. The model sees that handle, the candidate label and source-free
|
||||
evidence ranges, plus bounded transcript windows; it returns only duplicate
|
||||
groups of supplied handles and one supplied canonical handle per group. It
|
||||
never returns names, evidence, durable IDs, or replacement records. Identical
|
||||
labels and evidence remain independently selectable because their handles are
|
||||
distinct.
|
||||
|
||||
The generic core owns the mandatory handle protocol, candidate and transcript
|
||||
presentation, the private response schema, source-reference validation,
|
||||
candidate and combined-material limits, structured completion, proposal
|
||||
assessment, stable group ordering, and typed plan-application mechanics. The
|
||||
D&D prompt contributes its system message and registry-specific semantic
|
||||
instructions. The generic registrar registers the shared prompt and schema;
|
||||
the D&D registrar registers each consuming prompt and the fallback profile.
|
||||
|
||||
Fewer than two eligible candidates skips the LLM without a semantic warning.
|
||||
An exceeded bound also skips the call and preserves the deterministic
|
||||
preprocessed registry, adding the registry's bounded fallback warning. Invalid
|
||||
structured output or discarded proposal groups use the normalizer's existing
|
||||
retry contract; retry exhaustion preserves the safe deterministic or
|
||||
partially applied result and emits its bounded fallback warning. Provider,
|
||||
transport, cancellation, and context-material failures remain execution
|
||||
errors.
|
||||
|
||||
Application remains typed and registry-owned. All three policies select the
|
||||
canonical member's normalized display name, union member evidence in source
|
||||
order, preserve ungrouped records, and derive durable identity only after
|
||||
consolidation. NPC IDs derive from the final name. Item IDs also derive from
|
||||
the final name, and a typed guard prevents currency aliases from crossing
|
||||
denominations or mixing currency with non-currency records. Location IDs
|
||||
derive from the final name and final evidence, preserving same-name,
|
||||
parent/child, and distinct physical-place identities. Registry warning scopes,
|
||||
reason codes, and postconditions remain outside the generic core.
|
||||
|
||||
## Generated References And Grounding
|
||||
|
||||
@@ -82,30 +201,55 @@ producer provenance; consumers resolve the handed-off artifact into an
|
||||
immutable, validated projection for each operation. External files are checked
|
||||
during preparation, while generated artifacts are resolved at the handoff.
|
||||
|
||||
NPC registries are names-only grounding projections: they may canonicalize
|
||||
actors for spells and combat turns and are required for NPC interactions, but
|
||||
they do not supply evidence. Scene-description registries are eligibility-only
|
||||
projections: they retain the current chunk’s classification data, not scene
|
||||
prose or evidence, and exist to route combat extraction.
|
||||
NPC and item registry consumers receive names-only grounding. Location
|
||||
consumers receive a contextual selector containing the canonical name and the
|
||||
registry references needed to distinguish same-name places. The calling module
|
||||
resolves those supplied selections locally and maps them into the unchanged
|
||||
durable ID/name pair; an unknown or ambiguous selection rejects the complete
|
||||
occurrence result rather than accepting a partial mapping. The NPC registry
|
||||
additionally supplies names-only actor grounding to spells, combat turns, and
|
||||
enemy events.
|
||||
|
||||
Registry references establish a registry identity and may disambiguate a
|
||||
selection, but never become occurrence evidence. Each occurrence keeps its own
|
||||
current-transcript source references, even when it was grounded through the
|
||||
same registry record.
|
||||
Scene descriptions are eligibility-only projections: they retain current-chunk
|
||||
classification data, not scene prose or evidence, and exist to route combat
|
||||
extraction. Enemy-event extraction also projects combat turns to `actor` and
|
||||
`turn_kind` and filters NPC occurrences to `combat_opponent` names and kinds.
|
||||
These projections are guidance only and never event evidence.
|
||||
|
||||
## Lane-Specific Rules
|
||||
|
||||
The following differences are intentional and should remain explicit when a
|
||||
shared helper changes.
|
||||
|
||||
Shared D&D text comparison is identified by `dnd.text_comparison.v1`. Any
|
||||
semantic change requires an explicit policy-version review for every affected
|
||||
identity, mapping, normalization, and validator policy; helper source is not a
|
||||
checkpoint fingerprint.
|
||||
|
||||
| Lane | Intentional behavior |
|
||||
| --- | --- |
|
||||
| Spells | May use a spell-catalog overlay and optional NPC grounding; the catalog validator supplies domain-specific semantic checks. |
|
||||
| NPCs | Does not consume an NPC registry. Its normalizer is the LLM-assisted reconciliation exception described above. |
|
||||
| NPC registry | Establishes transcript-grounded NPC identities, including factual third-party mentions, without assigning occurrence categories. It does not consume an NPC registry, and its normalizer is the LLM-assisted reconciliation exception described above. |
|
||||
| Combat turns | Requires a scene-description artifact. It calls the LLM only for an exact `combat` classification; exact non-combat classifications return an accepted empty result, while missing or mismatched classifications return an empty result with a bounded warning. Optional NPC grounding never becomes evidence. |
|
||||
| Item events | Uses campaign context for disambiguation but has no NPC-registry or scene-description dependency. |
|
||||
| NPC interactions | Requires the normalized NPC registry at extraction and normalization, using it for canonical actor grounding only. |
|
||||
| Item occurrences | Requires the normalized item registry for exact deterministic grounding at extraction and normalization. Campaign context may disambiguate, but the registry never becomes occurrence evidence. |
|
||||
| Item registry | Produces source-grounded item types and unique designations. Its LLM-assisted reconciliation is proposal-only, preserves distinct currency denominations and item types, and does not create per-instance identities. |
|
||||
| NPC occurrences | Requires the normalized NPC registry at extraction and normalization, using it for canonical actor grounding only. It separately emits cited current-transcript occurrence facts, including `mentioned`, rather than deriving them from registry provenance. |
|
||||
| Scene descriptions | Produces the classifications consumed by combat routing; it does not consume an NPC registry or provide evidence for combat artifacts. |
|
||||
| Enemy events | Requires NPC, scene-description, combat-turn, and NPC-occurrence artifacts. It calls the LLM only for an exact `combat` classification, records ordered observations rather than terminal state, and normalizes recognized names through the NPC registry while preserving grounded collective labels. |
|
||||
| Location registry | Produces a source-anchored, session-scoped registry from stable proper names or unique in-world designations. Its LLM-assisted reconciliation is proposal-only and never collapses same-name places without validated identity and evidence rules. |
|
||||
| Location occurrences | Requires the normalized location registry for both extraction and normalization. Its [durable occurrence categories](../integrations/dnd-location-occurrence-artifacts.md#occurrence-categories) distinguish explicit speculation from unsupported inference; the deterministic normalizer enforces exact registry grounding and never turns registry provenance into occurrence evidence. |
|
||||
|
||||
The combat and scene-description contracts describe their exact handoff and
|
||||
empty-result behavior in more detail:
|
||||
[combat turns](../integrations/dnd-combat-turn-artifacts.md) and
|
||||
[scene descriptions](../integrations/dnd-scene-description-artifacts.md).
|
||||
The [enemy-event contract](../integrations/dnd-enemy-event-artifacts.md)
|
||||
defines its durable semantics; [Configuration](../config.md) owns its
|
||||
selectable bindings and validation chains.
|
||||
|
||||
## Focused Verification
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# LLM Runtime Internals
|
||||
|
||||
`internal/framework/llm` is Notarius’s provider-independent structured
|
||||
completion boundary. It adapts framework requests to Scriptorium, bounds
|
||||
completion boundary. It adapts framework requests to PromptKit, bounds
|
||||
provider calls, assembles registered prompt and schema assets, records selected
|
||||
profiles, and redacts provider errors. The architectural boundary is defined in
|
||||
[Architecture](../policy/architecture.md#llm-boundary); profile sources,
|
||||
credentials, and concurrency settings belong in
|
||||
[Configuration](../config.md#scriptorium-profiles) and
|
||||
[Configuration](../config.md#promptkit-profiles) and
|
||||
[Configuration](../config.md#concurrency-output-cache-and-debug).
|
||||
|
||||
## Structured Completion Boundary
|
||||
@@ -24,25 +24,102 @@ adapter does not own source evidence, artifact conversion, normalization, or
|
||||
durable schemas. Those responsibilities remain with the module and its
|
||||
[integration contract](../integrations/).
|
||||
|
||||
`ScriptoriumClient` validates the request target and prompt identity, maps each
|
||||
named material to a Scriptorium inline artifact while preserving its origin URI,
|
||||
forwards session and profile selection, then prepares and runs the prompt. It
|
||||
returns Scriptorium’s validated raw bytes rather than re-encoding the decoded
|
||||
target. An empty optional material is represented as one space so its named
|
||||
input is retained by Scriptorium.
|
||||
The calling module also resolves contextual entity selections and attaches any
|
||||
application identity; PromptKit and this adapter do not own entity identity.
|
||||
|
||||
An empty request profile lets the prompt select its configured default. The CLI
|
||||
prepares every explicitly selected binding profile before a run begins, so a
|
||||
missing explicit profile fails before stage execution. Calls record the profile
|
||||
actually selected by Scriptorium; the recorder deduplicates non-secret profile
|
||||
identity, provider, and model values for manifest use.
|
||||
`PromptKitClient` validates the request target and prompt identity, maps each
|
||||
named material to a PromptKit inline artifact while preserving its origin URI,
|
||||
passes the supplied request session through to PromptKit's direct per-run
|
||||
session field, retains the same value as the `session_id` prompt variable for
|
||||
maintained prompt compatibility, and forwards profile selection. It does not
|
||||
derive or replace session values; the CLI owns that policy. It then creates one
|
||||
frozen prepared execution, captures its caller-owned credential-redacted
|
||||
details for debug material, and executes that exact snapshot through
|
||||
PromptKit's prepared-execution boundary. The direct field
|
||||
is authoritative for provider session behavior. A session ID is a stable,
|
||||
non-secret correlation identifier and may be exposed to providers and provider
|
||||
observability. The adapter returns PromptKit’s validated raw bytes rather than
|
||||
re-encoding the decoded target. An empty optional material is represented as
|
||||
one space so its named input is retained by PromptKit.
|
||||
|
||||
When a request includes semantic correction material, the adapter validates and
|
||||
defensively copies it before preparation, then appends exactly two messages
|
||||
after the ordinarily rendered prompt: the prior response as an assistant
|
||||
message and the correction guidance as a user message. Requests without a
|
||||
correction do not add messages or introduce caller roles. Ordinary request
|
||||
summaries record correction byte counts and digests only; complete messages are
|
||||
available solely in an explicitly requested debug trace.
|
||||
|
||||
The adapter leaves the ordinary rendered message prefix, named inputs,
|
||||
variables, session, profile, execution overrides, prepared-execution path, and
|
||||
PromptKit repair policy unchanged for a corrected request. It never imports a
|
||||
PromptKit message type into a module or pipeline contract. PromptKit reports
|
||||
actual structural repair count and cumulative token usage per completion; the
|
||||
pipeline's safe terminal debug record projects those values without copying
|
||||
message content.
|
||||
|
||||
Client construction may also receive a run-wide reasoning-effort override from
|
||||
the CLI factory boundary. The adapter copies the caller-owned pointer and
|
||||
creates a fresh PromptKit execution override for each request: a nil pointer
|
||||
inherits the selected profile, a non-empty value replaces it, and an empty
|
||||
value clears inherited reasoning. The CLI's mutually exclusive
|
||||
`--reasoning-effort` and `--clear-reasoning-effort` controls select those
|
||||
states. With neither flag, profile behavior remains unchanged. Because
|
||||
production constructs one shared client, the selected state applies uniformly
|
||||
to module calls, retries, and LLM-backed validators for the whole run.
|
||||
|
||||
An empty request profile lets the prompt select its configured default. Before a
|
||||
run begins, the CLI asks the adapter to inspect every explicit profile on the
|
||||
resolved selected LLM-backed bindings and validators, including inherited
|
||||
pipeline profiles. Inspection resolves the profile and its selected backend and
|
||||
target without loading a prompt, reading credentials, admitting capacity, or
|
||||
contacting a provider, so a missing or invalid explicit profile fails before
|
||||
stage execution while a valid `api_key_env` may remain unset. Calls record the
|
||||
profile actually selected by PromptKit. The recorder trims and deduplicates
|
||||
non-secret profile identity, provider, model, selected backend ID, and
|
||||
effective reasoning values for manifest use. Entries that differ in backend or
|
||||
reasoning remain distinct and deterministically ordered. Endpoint-only profiles
|
||||
retain an empty backend ID, which the published JSON omits. Successful
|
||||
completion responses and recorded profile manifests identify the adapter
|
||||
provider as `promptkit`.
|
||||
|
||||
The CLI's profile-inspection engine and the production adapter use the same
|
||||
profile-source construction to apply the configured profile directory or file,
|
||||
the optional registered fallback profile assets, and the optional conventional
|
||||
`local` backend. Preflight therefore resolves the same profile sources and
|
||||
backend membership as runtime without performing generation. Fallback assets
|
||||
are mounted only when at least one source is registered. The production D&D
|
||||
registrar contributes its `dnd-extraction` fallback, and the maintained D&D
|
||||
prompts select that logical ID by default. PromptKit owns source precedence and
|
||||
profile parsing and inheritance: an operator-provided matching profile takes precedence over a
|
||||
fallback profile without Notarius merging either document.
|
||||
When the registration is absent, a profile selecting `backend: local` fails
|
||||
inspection instead of falling back to a built-in or endpoint-only target.
|
||||
|
||||
Before execution, the adapter also contributes a non-secret checkpoint
|
||||
fingerprint for the effective PromptKit profile source. It combines the
|
||||
identity of PromptKit's compiled-in profile catalog with a deterministic digest
|
||||
of every YAML profile in the configured profile directory, or of the configured
|
||||
profile file, and a deterministic digest of the flattened fallback profile
|
||||
assets. The fingerprint contains neither profile content nor source paths. It
|
||||
covers inherited pipeline profiles, explicit binding profiles, and
|
||||
prompt-selected defaults, so changing a model or other profile setting cannot
|
||||
reuse checkpoints created under the
|
||||
prior profile source. This cache identity is independent of durable
|
||||
profile provenance: run manifests continue to list only profiles actually
|
||||
observed during LLM calls. When the local backend is registered, a second
|
||||
fingerprint hashes its trimmed endpoint behind a stable marker. Changing that
|
||||
semantic execution target invalidates checkpoint reuse. The raw endpoint is not
|
||||
stored in checkpoint identity, and the local concurrency limit is excluded
|
||||
because it changes scheduling rather than execution semantics.
|
||||
|
||||
## Shared Provider-Call Limit
|
||||
|
||||
Production construction creates one Scriptorium client and wraps it in one
|
||||
Production construction creates one PromptKit client and wraps it in one
|
||||
scheduled client. The scheduler has a fixed, positive permit limit, serves
|
||||
queued calls in FIFO order, and removes a queued call when its context is
|
||||
cancelled. A granted permit is released exactly once on every completion path.
|
||||
cancelled. It rechecks the caller context after admission and before dispatch.
|
||||
A granted permit is released exactly once on every completion path.
|
||||
|
||||
The scheduled wrapper surrounds every `CompleteStructured` call, so concurrent
|
||||
lanes, pipeline retries, and LLM-backed validators share the same provider-call
|
||||
@@ -51,22 +128,57 @@ worker counts cannot exceed the configured LLM limit. The configuration field
|
||||
and its effective default are owned by
|
||||
[Configuration](../config.md#concurrency-output-cache-and-debug).
|
||||
|
||||
PromptKit applies a second, independent admission limit when the selected
|
||||
profile names a limited backend. It sits beneath the Notarius scheduled client,
|
||||
so it may narrow but cannot expand the application-wide limit. Built-in
|
||||
OpenRouter profiles select PromptKit's reserved backend and its upstream
|
||||
capacity policy. A positive configured local-backend limit bounds active local
|
||||
generations inside PromptKit; zero leaves that backend unlimited there.
|
||||
Endpoint-only profiles do not select a PromptKit backend and remain limited
|
||||
only by the Notarius scheduler.
|
||||
|
||||
## Prompt And Schema Assets
|
||||
|
||||
An `AssetRegistry` collects prompt and schema filesystems from production module
|
||||
families. It flattens registered roots into the Scriptorium filesystems and
|
||||
rejects invalid roots, unreadable assets, duplicate paths, and missing prompt
|
||||
or schema files during preparation. The framework’s `promptfs` helper combines
|
||||
module-owned prompt files with reusable domain fragments without making the
|
||||
An `AssetRegistry` collects prompt, schema, and optional fallback-profile
|
||||
filesystems from production module families. It flattens registered roots into
|
||||
the corresponding PromptKit filesystems and rejects invalid roots, unreadable
|
||||
assets, duplicate paths, and missing prompt or schema files during preparation.
|
||||
Fallback assets receive a safe content digest for checkpoint identity; raw
|
||||
paths and bytes are never included. The framework’s `promptfs` helper combines
|
||||
module-selected prompt files with reusable domain fragments without making the
|
||||
framework depend on D&D content.
|
||||
|
||||
Each LLM-backed module owns its prompt declaration, package-specific assets,
|
||||
and private response schema. Shared D&D wording is owned by the D&D shared
|
||||
asset package; the detailed D&D conventions are in
|
||||
[D&D Module Internals](dnd.md). The mounted prompt assets used by a module also
|
||||
determine its prompt fingerprint. Schema loaders validate JSON, attach identity
|
||||
and digest metadata, make defensive copies, and expose diagnostics without raw
|
||||
schema bytes.
|
||||
LLM-facing content is embedded once by the root `assets` package. Each consumer
|
||||
uses only its scoped subtree, while the module retains ownership of its prompt
|
||||
declaration, ordered manifest, private response-schema identity, and
|
||||
registration. Shared D&D fragments are selected by D&D's shared implementation;
|
||||
the detailed convention is in [D&D Module Internals](dnd.md). This physical
|
||||
arrangement and its data-only boundary are defined by
|
||||
[Architecture](../policy/architecture.md) and
|
||||
[ADR-0011](../adr/0011-centralize-llm-assets.md), rather than by this runtime
|
||||
guide.
|
||||
|
||||
The generic registrar is the sole production registration owner for the
|
||||
semantic-reconciliation default prompt and private response schema. The
|
||||
domain-neutral reconciliation package also exposes only its mandatory protocol
|
||||
and candidate/transcript presentation files for domain prompt manifests. D&D
|
||||
registry normalizers mount those files while retaining ownership and hashing
|
||||
of their D&D system message, semantic instructions, and complete prompt
|
||||
declaration. The response schema is therefore registered once even though
|
||||
several typed normalizers select it.
|
||||
|
||||
Mounted prompt assets determine a module's fingerprint. The fingerprint hashes
|
||||
only the module and shared files explicitly selected by its manifest, so an
|
||||
unrelated asset does not invalidate a checkpoint. Schema loaders validate JSON,
|
||||
attach identity and digest metadata, make defensive copies, and expose
|
||||
diagnostics without raw schema bytes.
|
||||
|
||||
Semantic-reconciliation normalizers extend this identity with the shared
|
||||
response-schema digest, framework policy version, and complete limit-policy
|
||||
digest. Their manifest metadata records the same content-free prompt, schema,
|
||||
policy, and limit identities together with domain identity and normalization
|
||||
policies. Request-local handles, source material, proposal content, and raw
|
||||
asset bytes are not checkpoint metadata.
|
||||
|
||||
Private response schemas validate a model transport envelope. They are not the
|
||||
durable artifact schema and should not be documented as an external wire
|
||||
@@ -76,54 +188,115 @@ contract. Durable formats and compatibility rules remain in the
|
||||
## Prompt Maintenance And Backend Caching
|
||||
|
||||
Prompt message order and shared asset bytes are runtime behavior. Backend cache
|
||||
reuse depends on the same preceding messages and content, not merely equivalent
|
||||
meaning. Keep reusable shared assets byte-identical and keep stable material
|
||||
before the inputs that vary per request wherever a prompt’s declared sequence
|
||||
supports caching. Preserve the existing manifest order and cache-control hints
|
||||
when editing a prompt.
|
||||
reuse depends on identical preceding roles, rendered bytes, and cache-control
|
||||
metadata—not merely equivalent meaning. Keep reusable shared assets
|
||||
byte-identical and preserve each prompt’s declared ordering and cache controls
|
||||
when editing it.
|
||||
|
||||
D&D extraction manifests place the changing chunk transcript at the end of the
|
||||
prompt after their reusable context. Scene chunking and NPC normalization use
|
||||
their own declared message sequences because their inputs and work differ. The
|
||||
family-specific asset and ordering rules belong in [D&D Module Internals](dnd.md).
|
||||
Do not add tests that enforce a fixed message-prefix length; prompt-asset tests
|
||||
should instead verify the meaningful asset sequence, inputs, and cache controls
|
||||
of the prompt being changed.
|
||||
For sibling prompts that can reuse the same source material, order universal
|
||||
shared context first, request source material next, and module-specific
|
||||
suffixes last. Put a cache boundary at a reusable prefix that is useful to the
|
||||
backend. Redundant intermediate cache boundaries do not extend that reusable
|
||||
prefix and add no value.
|
||||
|
||||
Prompt-family owners may choose a different sequence when their inputs and
|
||||
reuse pattern differ. The D&D family’s extraction, scene-chunking, and NPC
|
||||
normalization policies are maintained in [D&D Module Internals](dnd.md#prompt-construction).
|
||||
Do not add tests that enforce prompt prose; prompt tests should verify the
|
||||
meaningful input placement and cache controls of the prompt being changed.
|
||||
|
||||
## Validation, Repair, And Retries
|
||||
|
||||
Scriptorium performs prompt rendering, provider execution, and the prompt’s
|
||||
PromptKit performs prompt rendering, provider execution, and the prompt’s
|
||||
structured-output validation. The adapter reports an empty result, validation
|
||||
failure, empty structured body, or decode failure as
|
||||
`ErrInvalidStructuredOutput`, while retaining the returned raw bytes and debug
|
||||
material when they exist. Provider failures remain operational errors rather
|
||||
than output-validation failures.
|
||||
than output-validation failures. Apart from documented context, capacity, and
|
||||
invalid-output categories, provider error values and types do not cross the
|
||||
adapter error chain; callers receive only a credential-redacted diagnostic.
|
||||
|
||||
Prompt-declared repair is executed within Scriptorium’s structured-output flow.
|
||||
The current production D&D prompt manifests set repair attempts to zero. That
|
||||
setting does not replace pipeline retry behavior: a binding’s configured retry
|
||||
count reruns its stage attempt after an error or rejection, and an exhausted
|
||||
rejection is a recorded output rather than a provider error. The pipeline owns
|
||||
attempt lifecycle, validation chains, and retry diagnostics; see
|
||||
[Pipeline Internals](pipeline.md#validation-retries-and-output) and the
|
||||
When PromptKit rejects backend admission before generation, the adapter maps
|
||||
`promptkit.ErrCapacityExceeded` to
|
||||
`contracts.ErrLLMCapacityExceeded`, retaining prompt context and a redacted
|
||||
upstream diagnostic without exposing the PromptKit sentinel or capacity-error
|
||||
type as a framework contract. When supplied, the normalized selected backend
|
||||
ID appears only in that safe application-owned diagnostic context. A canceled
|
||||
caller context takes precedence. The adapter does not retry capacity failures;
|
||||
the pipeline's existing binding attempt policy sees the operational error and
|
||||
decides whether to rerun the complete operation.
|
||||
|
||||
PromptKit executes structural repair within its structured-output flow. The
|
||||
maintained production prompt manifests declare one additional repair attempt.
|
||||
When a resolved binding supplies a repair value, the adapter inspects the
|
||||
prompt, copies its complete output contract, changes only the repair limit, and
|
||||
passes that complete replacement contract to PromptKit. This preserves the
|
||||
prompt's output format, validation mode, schema, and provider structured-output
|
||||
settings.
|
||||
|
||||
A successful repair is an ordinary successful completion, not a warning. The
|
||||
adapter reports PromptKit's actual repair count and its cumulative usage
|
||||
directly, without adding the initial and corrective counts again. Debug prompt
|
||||
material records the configured complete contract; debug response material
|
||||
records the repaired response and actual validation result. If the repair
|
||||
budget is exhausted, the adapter retains the final raw bytes and debug material
|
||||
and reports `ErrInvalidStructuredOutput`. Generation failures during an initial
|
||||
or corrective call remain provider-neutral operational errors with the same
|
||||
redaction boundary.
|
||||
|
||||
Structural repair does not replace pipeline retry behavior: a binding's
|
||||
configured retry count reruns its complete stage attempt after an operational
|
||||
or structural error, module-requested retry, or actionable semantic rejection.
|
||||
The pipeline owns attempt lifecycle, validation chains, and retry diagnostics;
|
||||
see [Pipeline Internals](pipeline.md#validation-retries-and-output) and the
|
||||
[binding reference](../config.md#module-bindings-and-validators).
|
||||
|
||||
## Timeout Ownership
|
||||
|
||||
The caller context remains the outer cancellation authority. PromptKit applies
|
||||
a positive effective generation timeout as an inner request deadline; an
|
||||
explicit zero disables only that generation deadline. The HTTP client timeout
|
||||
is a separate transport-wide cap. Notarius forwards the caller context and
|
||||
does not install another timeout wrapper around PromptKit.
|
||||
|
||||
The selected PromptKit profile owns generation settings. Notarius binding
|
||||
retries remain outside the adapter and repeat the complete module operation
|
||||
and validation chain. PromptKit does not add a provider retry loop.
|
||||
Operator-facing behavior is summarized in
|
||||
[Operations](../operations.md#operational-limits), and the pinned upstream
|
||||
contract is identified in
|
||||
[PromptKit Integration](../integrations/pkg-promptkit.md).
|
||||
|
||||
## Observability And Redaction
|
||||
|
||||
When debug recording is enabled, the pipeline decorates the shared client. The
|
||||
wrapper records prepared prompt and response material, timing, selected profile
|
||||
and model, and call identifiers in the run’s debug bundle, including material
|
||||
available from a failed structured completion. For a successful completion, a
|
||||
debug-write failure is surfaced; when the completion already failed, its call
|
||||
error remains the result. Debug-bundle location, retention, and handling are
|
||||
operational concerns documented in [Operations](../operations.md#debug-bundles).
|
||||
and backend, effective model parameters, and call identifiers in the run’s
|
||||
debug bundle, including material available from a failed structured completion.
|
||||
Effective parameters use PromptKit's stable lower-case JSON field names and may
|
||||
include `backend_id`. For a successful completion, a debug-write failure is
|
||||
surfaced; when the completion already failed, its call error remains the
|
||||
result. Debug-bundle location, retention, and handling are operational concerns
|
||||
documented in [Operations](../operations.md#debug-bundles).
|
||||
|
||||
Run manifests receive selected profile summaries and component identities, not
|
||||
prompt, schema, source, reference, or response content. Provider error text is
|
||||
wrapped with prompt context and bearer credentials are redacted before it
|
||||
crosses the runtime boundary. Known-secret redaction is available to other
|
||||
runtime collaborators; it does not make prompt or response contents safe for
|
||||
general logging.
|
||||
The attempt-terminal summary is a separate safe trace record: it contains
|
||||
attempt kinds, validator outcome counts and reason codes, effective policy,
|
||||
terminal action, and repair/usage references. It excludes raw assistant
|
||||
responses and correction text. Those values can appear only in the explicitly
|
||||
requested detailed prompt and response artifacts, which require sensitive-data
|
||||
handling.
|
||||
|
||||
Run manifests receive selected profile summaries, including optional effective
|
||||
backend and reasoning provenance, and component identities—not prompt, schema,
|
||||
source, reference, or response content. The published field semantics belong
|
||||
to the [JSON output contract](../integrations/json-output.md#manifestjson).
|
||||
Provider error text is wrapped with prompt context and bearer credentials are
|
||||
redacted before it crosses the runtime boundary. Known-secret redaction is
|
||||
available to other runtime collaborators; it does not make prompt or response
|
||||
contents safe for general logging.
|
||||
|
||||
Generation failures expose an application-owned category and optional HTTP
|
||||
status. Provider code, type, and message remain debug-only, after redaction.
|
||||
|
||||
## Failure Boundaries
|
||||
|
||||
@@ -131,6 +304,8 @@ general logging.
|
||||
sources, invalid asset registration, or a non-positive scheduler limit.
|
||||
- Preparation failures, unavailable explicit profiles, provider failures, and
|
||||
context cancellation propagate to the calling stage with context.
|
||||
- Backend admission exhaustion is a provider-neutral operational error and is
|
||||
not classified as invalid structured output or validator rejection.
|
||||
- Malformed or schema-invalid provider output is classified separately as
|
||||
invalid structured output so the module or pipeline can apply its own retry
|
||||
and rejection policy.
|
||||
|
||||
@@ -12,9 +12,24 @@ exceptions. See [D&D Module Internals](dnd.md) rather than adding them here.
|
||||
|
||||
A module is a typed implementation registered for one pipeline stage. Its
|
||||
`ModuleSpec` is the public-to-the-framework declaration of its stable key,
|
||||
stage, required and provided capabilities, artifact kind, and accepted
|
||||
reference slots. The framework uses that declaration to resolve a configured
|
||||
binding before it builds the implementation.
|
||||
stage, execution class, required and provided capabilities, artifact kind, and
|
||||
accepted reference slots. The execution class states whether a module is
|
||||
`deterministic` or `llm_backed`; registries retain it for catalog inspection and
|
||||
resolved-pipeline debug data without constructing the module. The framework
|
||||
uses the declaration to resolve a configured binding before it builds the
|
||||
implementation. After selection, the resolver applies profile inheritance only
|
||||
to bindings whose declared execution class is `llm_backed` and rejects a
|
||||
binding-specific profile on a deterministic module. The user-facing precedence
|
||||
contract belongs in [Configuration](../config.md#pipelines).
|
||||
|
||||
An eligible LLM-backed chunk, extract, merge, or normalize producer may also
|
||||
declare correction protocol `single_response_v1`. That declaration is a
|
||||
promise that the implementation accepts one attempt-local semantic correction
|
||||
and returns an owned copy of the exact one model response that directly
|
||||
controlled the candidate. It must forward correction only to its structured
|
||||
completion request; it must not manufacture prior-response material by
|
||||
serializing a normalized artifact or expose opaque application IDs. Input,
|
||||
output, validator, and deterministic specs cannot declare the protocol.
|
||||
|
||||
Implementations that accept options must provide both an option validator and
|
||||
a builder. The validator is used while resolving configuration; the builder
|
||||
@@ -30,45 +45,103 @@ they need, register each leaf implementation, and add any family-owned assets
|
||||
or default validator chains. They return contextual errors so production
|
||||
composition fails at startup rather than at the first run.
|
||||
|
||||
A validator that returns a completed rejection must supply two separate
|
||||
bounded values: a stable `ReasonCode` for provenance and actionable
|
||||
`CorrectionGuidance` for the producer. Guidance identifies the semantic defect
|
||||
and the constraints on one complete corrected replacement. It must not contain
|
||||
validator keys, diagnostic paths, opaque application IDs, or other internal
|
||||
identifiers. An operator-facing `Message` may explain the same event, but the
|
||||
framework never copies it into a model request. Missing or invalid guidance is
|
||||
a validator contract failure.
|
||||
|
||||
An artifact family can register an optional typed evidence projector alongside
|
||||
its codec. The projector returns defensive copies of the artifact's direct
|
||||
generic source references and must use the codec's exact Go type. It does not
|
||||
interpret surrounding context or publish files; the pipeline validates the
|
||||
capability during preparation and the output boundary owns publication. See
|
||||
the [Published Evidence Context contract](../integrations/evidence-context.md)
|
||||
for the durable result.
|
||||
for the durable source-unit excerpt. Lane artifacts retain citation and lane
|
||||
provenance; the framework does not add either to that published excerpt.
|
||||
|
||||
An artifact family is broader than a module: it owns the cohesive domain
|
||||
feature across its artifact type, codec, stage modules, validators, prompt
|
||||
policy, schemas, identity helpers, and reference projections. An extractor and
|
||||
normalizer in one artifact family remain independently registered modules in
|
||||
their respective pipeline stages. This ownership vocabulary does not create a
|
||||
new registry or change the fixed pipeline.
|
||||
|
||||
## Production Composition
|
||||
|
||||
Production composition is intentionally split by family:
|
||||
|
||||
- The generic registrar provides the unit chunker, generic JSON validators,
|
||||
and JSON output encoder.
|
||||
JSON output encoder, and shared semantic-reconciliation prompt and response
|
||||
schema assets.
|
||||
- The Seriatim registrar provides the transcript input adapter. Its external
|
||||
input behavior is defined by the [Seriatim contract](../integrations/seriatim.md).
|
||||
- The D&D registrar provides its codecs, extractors, mergers, normalizers,
|
||||
validators, prompt assets, and default chains. Its behavioral conventions
|
||||
validators, prompt assets, fallback profile asset, and default chains. Its behavioral conventions
|
||||
are documented in [D&D Module Internals](dnd.md).
|
||||
|
||||
The CLI owns the composition that invokes these registrars. A module package
|
||||
may register its own family but must not assemble the CLI or make framework
|
||||
packages depend on production extensions.
|
||||
|
||||
## Semantic Reconciliation
|
||||
|
||||
`internal/framework/semanticreconcile` is a domain-neutral strategy used by a
|
||||
typed normalize module; it is not itself a selectable stage module. A
|
||||
source-backed artifact-family normalizer projects its deterministic records
|
||||
into contextual candidates and owned typed record envelopes, supplies its
|
||||
chosen prompt identity and resolved LLM profile, and constructs an engine with
|
||||
explicit limits. The core filters invalid evidence, assigns contiguous
|
||||
request-local integer handles, renders bounded candidate and transcript
|
||||
materials, invokes the structured-completion boundary, and assesses the
|
||||
returned duplicate groups into a stable non-overlapping plan.
|
||||
|
||||
The normalizer then applies that plan through a typed `ApplicationPolicy`. The
|
||||
core preserves ungrouped records, contribution order, and provenance while the
|
||||
artifact family owns group guards, field and evidence consolidation, durable
|
||||
ID derivation, retry and fallback presentation, warnings, and postconditions.
|
||||
Request-local handles do not enter the typed value or durable artifact. Fewer
|
||||
than two eligible candidates skips model invocation; exceeding a candidate or
|
||||
combined-material bound preserves the deterministic result under the family's
|
||||
fallback policy. Provider, transport, cancellation, and context-construction
|
||||
failures remain execution errors.
|
||||
|
||||
When the engine actually makes a proposal call, its typed result carries the
|
||||
owned exact proposal response under the same correction contract as other
|
||||
eligible producers. Deterministic skip, limit, and fallback outcomes carry no
|
||||
model candidate, so a later rejection applies terminal policy without spending
|
||||
an ineffective semantic retry.
|
||||
|
||||
The core supplies a conservative generic prompt and the single private
|
||||
response schema. A domain prompt may substitute its semantic instructions but
|
||||
mounts the core-owned protocol and candidate/transcript presentation assets.
|
||||
Prompt, schema, policy, and limit identities participate in manifest metadata
|
||||
and checkpoint fingerprints. The generic registrar owns production
|
||||
registration of those shared assets; a consuming domain registrar owns only
|
||||
its domain prompt.
|
||||
|
||||
## Adding Or Changing A Module
|
||||
|
||||
1. Choose the pipeline stage and the typed artifact boundary. Put external
|
||||
input or durable artifact formats in the relevant integration contract,
|
||||
not in this guide or in a private LLM response type.
|
||||
2. Define a stable `ModuleSpec` with the exact capabilities and reference
|
||||
slots needed for the operation. Model a producer/consumer handoff as an
|
||||
artifact-compatible slot; configuration then chooses an external file or a
|
||||
generated binding.
|
||||
2. Define a stable `ModuleSpec` with an explicit execution class, the exact
|
||||
capabilities, and reference slots needed for the operation. Model a
|
||||
producer/consumer handoff as an artifact-compatible slot; configuration
|
||||
then chooses an external file or a generated binding.
|
||||
3. Implement strict option decoding, construction, and the typed stage
|
||||
interface. Preserve caller ownership: do not retain mutable request data
|
||||
and return defensive copies where an implementation exposes stored data.
|
||||
If declaring correction capability, forward the request correction and
|
||||
retain only the exact validated response that controlled the result.
|
||||
4. Register the module through its typed registry helper and add it to the
|
||||
owning family registrar. Add a default validator chain only when that
|
||||
family owns the behavior; otherwise require an explicit compatible chain.
|
||||
Every rejection path in a validator must provide actionable correction
|
||||
guidance while retaining its stable internal reason code.
|
||||
5. Update the selectable-key and chain reference in
|
||||
[Configuration](../config.md#production-module-keys), the applicable
|
||||
integration contract, and focused tests. Keep the configuration document
|
||||
|
||||
@@ -25,10 +25,13 @@ physical state roots.
|
||||
| Area | Implemented owners | Responsibility |
|
||||
| --- | --- | --- |
|
||||
| Executable and command boundary | **cmd/notarius**, **internal/cli** | Process entry, command dispatch, configuration discovery, production composition, runtime collaborator setup, durable file placement, and user-facing reporting. |
|
||||
| Build information | **internal/buildinfo** | Resolves a stable linked release tag or build metadata for the diagnostic root version command. |
|
||||
| Configuration | **internal/core/config** | Defaults, strict YAML parsing, environment overrides, structural validation, effective resolution, redaction, and resolved-composition summaries. |
|
||||
| Generic models | **internal/core/source**, **internal/core/artifacts**, **internal/framework/contracts** | Source documents and chunks, manifests and provenance, plus typed artifact, reference, validation, output, and structured-completion contracts. |
|
||||
| Pipeline framework | **internal/framework/pipeline** | Registries, profile and reference resolution, typed preparation, validation, retry coordination, ordered execution, handoff, and result assembly. |
|
||||
| LLM and prompt runtime | **internal/framework/llm**, **internal/framework/promptfs** | Provider-neutral structured completions, scheduling, profile recording, prompt assets, schema registration, and credential-shaped-value redaction. |
|
||||
| Semantic reconciliation | **internal/framework/semanticreconcile** | Bounded source-backed candidate preparation, request-local handle proposals, deterministic assessment, typed plan application, and reconciliation identity metadata; see [Module Internals](modules.md#semantic-reconciliation) and [D&D Module Internals](dnd.md#semantic-registry-reconciliation). |
|
||||
| Embedded LLM content | **assets** | Read-only centralized LLM-facing content, scoped by its consuming package; see [LLM Runtime](llm.md#prompt-and-schema-assets) and [D&D Module Internals](dnd.md#prompt-construction). |
|
||||
| Runtime state | **internal/core/fileio**, **internal/core/debugbundle**, **internal/framework/checkpoint**, **internal/framework/chunkplan**, **internal/framework/chunkmap**, **internal/framework/debug** | Confined atomic files, debug bundles, checkpoint and chunk-plan state, accepted chunk maps, and pipeline-facing debug recording. |
|
||||
| Production extensions | **internal/modules/generic**, **internal/modules/seriatim**, **internal/modules/dnd** | Domain-neutral extensions, Seriatim input support, and D&D extraction families registered into the production catalog. |
|
||||
|
||||
@@ -48,8 +51,9 @@ the CLI composition boundary.
|
||||
composition, and path safety.
|
||||
- [LLM Runtime](llm.md): structured completion, scheduling, prompt assets,
|
||||
profiles, and secret handling.
|
||||
- [Module Internals](modules.md): generic extension registration, module
|
||||
construction, validation, and reference mechanics.
|
||||
- [Module Internals](modules.md): generic extension registration, artifact
|
||||
families, module construction, semantic reconciliation, validation, and
|
||||
reference mechanics.
|
||||
- [D&D Module Internals](dnd.md): shared D&D extractor conventions, generated
|
||||
reference projections, and lane-specific exceptions. Durable D&D and
|
||||
Seriatim data shapes remain in the [integration contracts](../integrations/).
|
||||
|
||||
@@ -10,11 +10,11 @@ own durable output shapes. Concrete production extensions are covered by
|
||||
## Boundary
|
||||
|
||||
The pipeline framework accepts a resolved composition, registries, shared
|
||||
dependencies, input bytes, and state/debug collaborators. It returns logical
|
||||
output files, normalized artifacts, recorded rejections and warnings, manifest
|
||||
provenance, and checkpoint decisions. The CLI owns process arguments,
|
||||
configuration discovery, physical roots, and placement of returned output
|
||||
files.
|
||||
dependencies, input bytes, a supplied prompt session, and state/debug
|
||||
collaborators. It returns logical output files, normalized artifacts, recorded
|
||||
rejections and warnings, manifest provenance, and checkpoint decisions. The
|
||||
CLI owns process arguments, configuration discovery, session resolution,
|
||||
physical roots, and placement of returned output files.
|
||||
|
||||
The framework has one fixed shape:
|
||||
|
||||
@@ -32,8 +32,26 @@ Resolution turns a configured pipeline profile into a **ResolvedPipeline**.
|
||||
It normalizes the pipeline and lane identities, applies stage defaults, selects
|
||||
requested lanes where that is supported, resolves validator chains, checks
|
||||
module capabilities and typed artifact compatibility, validates options, and
|
||||
assigns a deterministic resolved-composition digest. The resolved pipeline
|
||||
contains bindings and declared reference targets, not external reference bytes.
|
||||
assigns a deterministic resolved-composition digest. A correction protocol is
|
||||
selected from each eligible LLM-backed producer specification and becomes part
|
||||
of that resolved identity; only `single_response_v1` is currently supported.
|
||||
Preparation rejects an LLM-backed producer that combines a non-empty validator
|
||||
chain with positive producer retries unless it declares that protocol. Producers
|
||||
without validators or without retries remain valid without correction support.
|
||||
The resolved pipeline contains bindings and declared reference targets, not
|
||||
external reference bytes.
|
||||
After selection, the resolver applies command, binding, and pipeline profile
|
||||
precedence to LLM-backed bindings and validators only; prompt defaults remain
|
||||
an empty resolved binding profile. It resolves structural output repair
|
||||
separately: a binding's `structured_output_repair_attempts` value wins, then a
|
||||
pipeline value applies to LLM-backed bindings and validators, and omission
|
||||
leaves the prompt-owned policy intact. An explicit repair value on a
|
||||
deterministic binding is rejected. Resolved bindings own copied repair values,
|
||||
and these effective values are part of the digest, so execution and checkpoint
|
||||
consumers do not repeat profile inheritance or configuration resolution.
|
||||
Each LLM request receives its own copy of that resolved value. PromptKit spends
|
||||
it only for structural correction inside one completion; the runner's binding
|
||||
retry policy remains the separate outer budget for complete stage attempts.
|
||||
Configuration resolution supplies the selected profile and catalog; see
|
||||
[Configuration Internals](configuration.md).
|
||||
|
||||
@@ -41,16 +59,20 @@ External reference materialization happens before preparation. The materializer
|
||||
checks that each slot is declared by the selected module, resolves a file path
|
||||
relative to the correct configuration or working-directory origin, reads
|
||||
UTF-8 text, verifies media type and size limits, and retains bounded
|
||||
provenance. A generated-artifact selector remains declared but has no bytes
|
||||
until its producing step completes.
|
||||
provenance. For a positive slot limit, it reads at most the limit plus one byte
|
||||
and rejects overflow before retaining content. A generated-artifact selector
|
||||
remains declared but has no bytes until its producing step completes.
|
||||
|
||||
Preparation is the construction boundary. It validates the resolved shape and
|
||||
registry set, clones the resolved data, then constructs the input adapter,
|
||||
chunker, stage-local validators, every typed lane, and output encoder with
|
||||
cloned options, references, and shared dependencies. It also collects stable
|
||||
checkpoint fingerprints. Missing registrations, incompatible typed entries,
|
||||
nil implementations, and constructor failures are reported before source
|
||||
parsing or any stage operation begins.
|
||||
chunker, stage-local validators, every typed lane, and output encoder. The
|
||||
prepared producer metadata preserves each selected correction protocol, and
|
||||
the resolved digest carrying that metadata participates in checkpoint identity.
|
||||
Each registered builder receives its own cloned build request immediately
|
||||
before its module-owned code runs. Preparation also collects stable checkpoint
|
||||
fingerprints. Missing registrations, incompatible typed entries, nil
|
||||
implementations, and constructor failures are reported before source parsing
|
||||
or any stage operation begins.
|
||||
|
||||
An output encoder can opt into source-evidence publication through its output
|
||||
policy. Preparation keeps the configured lane allowlist and active lanes
|
||||
@@ -79,6 +101,10 @@ incompatible producer prevents the consumer step from starting.
|
||||
|
||||
The runner validates its input, installs no-op state collaborators when none
|
||||
were supplied, and serially performs source parsing and chunk-plan selection.
|
||||
It transports the supplied session unchanged to prompt-facing operations and
|
||||
run-manifest metadata; it neither derives a session nor substitutes a parsed
|
||||
source document identifier. The public session contract is owned by the
|
||||
[CLI reference](../cli.md#run).
|
||||
An accepted plan is materialized into source-addressed chunks and passes the
|
||||
configured chunk validators before any lane runs. A chunk rejection is a
|
||||
recorded pipeline outcome: lanes do not start, but the output stage can encode
|
||||
@@ -106,15 +132,49 @@ for started workers, and prevents output encoding.
|
||||
|
||||
Every chunk, extract, merge, and normalize candidate passes its resolved
|
||||
validator chain. Validators receive immutable canonical input appropriate to
|
||||
their target: chunks, typed values, or serialized codec bytes. They may
|
||||
approve, approve with warnings, reject, or fail. A rejection is an ordinary
|
||||
pipeline result; a validator error is a framework error.
|
||||
their target: chunks, codec-decoded typed candidates, or serialized codec
|
||||
bytes. Each typed validator receives a newly decoded value from the one
|
||||
candidate serialization for that attempt, while serialized validators receive
|
||||
separately owned representation bytes and schema metadata. They may approve,
|
||||
approve with warnings, reject, fail, or be skipped when a runtime prerequisite
|
||||
is unavailable. The shared executor settles every configured validator in
|
||||
order. A failed LLM-backed validator retries only itself against the same
|
||||
immutable candidate; it does not regenerate the producer or alter the
|
||||
validator request. Rejections stop that validator, while other configured
|
||||
validators still run. The executor retains ordered results, bounded
|
||||
deduplicated correction guidance from rejections, and only the final exhausted
|
||||
failure outcome for each validator. The correction builder keeps first
|
||||
occurrence order, omits internal reason codes, validator names, and operator
|
||||
messages, and requests one complete replacement. Missing guidance or an
|
||||
oversized aggregate is a framework contract error; guidance is never inferred
|
||||
or truncated.
|
||||
|
||||
The runner applies the binding's retry policy around a stage operation and its
|
||||
complete validation chain. It preserves warnings only from the final accepted
|
||||
or rejected attempt. Cancellation stops retries. Normalizer-specific retry
|
||||
directives consume this same budget and validate any final safe fallback through
|
||||
the normalizer chain.
|
||||
or rejected attempt, plus one fixed warning per validator whose execution
|
||||
budget was exhausted under `warn_continue`. Cancellation stops retries.
|
||||
Normalizer-specific retry directives consume this same budget and validate any
|
||||
final safe fallback through the normalizer chain.
|
||||
|
||||
The artifact-neutral producer-attempt state machine owns that shared budget,
|
||||
attempt provenance, semantic-correction material, and terminal-policy
|
||||
selection. It accepts producer and complete-validation closures, so artifact
|
||||
materialization, cache handling, checkpoints, and debug output stay at the
|
||||
operation boundary. It distinguishes operational, structural, module-requested,
|
||||
and semantic retries. A semantic retry is available only for a valid latest
|
||||
`single_response_v1` candidate; a deterministic or no-model rejection instead
|
||||
settles the semantic policy immediately. Structural-output errors alone use the
|
||||
structural policy, and validation failure without rejection settles the
|
||||
validator-failure policy without regenerating the producer.
|
||||
|
||||
Chunk planning uses this state machine for generated plans. A rejected or
|
||||
validation-incomplete automatic cache hit is not model material and therefore
|
||||
falls through to a fresh initial generation at producer attempt one; it neither
|
||||
receives a correction, consumes retry budget, promotes cached-candidate
|
||||
warnings, nor overwrites the stored record. An incomplete cache validation
|
||||
under `fail_run` terminates instead. Only a newly generated, completely
|
||||
validated plan is published to the chunk-plan store. Rejected plans never
|
||||
advance, and validation-incomplete plans remain unpublishable.
|
||||
|
||||
After terminal lane work, the runner assembles manifest provenance, normalized
|
||||
artifacts, rejections, warnings, and an optional accepted chunk map. When an
|
||||
@@ -128,6 +188,15 @@ The CLI publishes those files only after the runner returns without a framework
|
||||
error. Logical file names and schemas are defined by the [output integration
|
||||
contracts](../integrations/).
|
||||
|
||||
For every completed producer disposition, the runner projects one bounded
|
||||
validation summary to the manifest, the affected rejection when present, and
|
||||
the CLI result receipt. The summary records status, configured-order rejecting
|
||||
validators and reason codes, incomplete validators, producer-attempt count,
|
||||
and terminal action. It contains no operator message, correction guidance, or
|
||||
model response. `complete`, `rejected`, and `incomplete` describe the final
|
||||
candidate disposition; a run-level `incomplete` status indicates at least one
|
||||
current-run output advanced under `warn_continue`.
|
||||
|
||||
## Checkpoint And Debug Hooks
|
||||
|
||||
The runner receives checkpoint and debug interfaces rather than roots. It
|
||||
@@ -137,6 +206,20 @@ handoff. Generated-reference dependencies participate in checkpoint decisions.
|
||||
Selective recomputation can require a canonical accepted normalized predecessor
|
||||
before a dependent lane starts.
|
||||
|
||||
The runner writes successful checkpoint artifacts only after complete accepted
|
||||
validation. Chunk plans follow the same rule for publication. A rejection,
|
||||
invalid structured response, or incomplete validation is never reusable state;
|
||||
the current run may still hand off an otherwise valid `warn_continue` result
|
||||
according to its terminal policy. The runner carries private reuse eligibility
|
||||
through extract, merge, normalize, and generated-reference handoff. Any stage
|
||||
derived from incomplete validation skips both checkpoint lookup and all
|
||||
checkpoint publication even when that stage's own validation completes.
|
||||
External references and fully validated generated references remain eligible.
|
||||
Attempt debug records retain safe kind,
|
||||
validator, repair-usage, policy, and terminal-decision provenance. Full
|
||||
assistant and correction content remains confined to the requested detailed
|
||||
LLM trace.
|
||||
|
||||
Debug recording is attempt-scoped and application-owned. A failure to persist
|
||||
required debug data is a framework error. State roots, persistence, reason-code
|
||||
meanings, resume, and cleanup are intentionally owned by
|
||||
|
||||
@@ -39,12 +39,17 @@ codecs, loader, and recorder. The CLI constructs a recorder whenever checkpoint
|
||||
recording is enabled and constructs a loader only for a `--resume` invocation.
|
||||
Identity incorporates explicit stable semantic fingerprints collected from
|
||||
prepared modules and validators in addition to configuration, input,
|
||||
references, runtime overrides, and LLM profiles.
|
||||
references, runtime overrides, observed LLM profiles, and the LLM runtime's
|
||||
non-secret effective profile-source identity. A profile source change therefore
|
||||
causes a cold miss even when the configured profile ID remains unchanged.
|
||||
The serialized
|
||||
`workspace_schema_version` identifiers are frozen wire-compatibility fields;
|
||||
they do not describe a current public state surface.
|
||||
|
||||
Ordered-step lane checkpoints include the step identity in their storage scope.
|
||||
Accepted step and lane identities are encoded injectively before becoming
|
||||
filesystem path components, while ordinary safe identifiers retain their
|
||||
readable paths.
|
||||
When a later lane consumes a generated artifact, its dependency fingerprints
|
||||
include the producer's artifact kind, complete schema identity, media type,
|
||||
canonical content digest, and size. Ordinary resume compares those fingerprints
|
||||
|
||||
@@ -5,6 +5,23 @@ This is the canonical guide for operating Notarius runtime state. The
|
||||
[Configuration](config.md) owns fields, defaults, and precedence. Maintainers
|
||||
who need implementation mechanics should read [Run State Internals](internal/state.md).
|
||||
|
||||
## Source Deployment
|
||||
|
||||
Linux is the supported deployment platform. Install a pinned source release
|
||||
with the Go version declared in `go.mod` (currently Go 1.25.5):
|
||||
|
||||
~~~sh
|
||||
GOWORK=off go install \
|
||||
gitea.maximumdirect.net/eric/notarius/cmd/notarius@vMAJOR.MINOR.PATCH
|
||||
~~~
|
||||
|
||||
Pin the exact tag in deployment automation rather than following a branch.
|
||||
Use [`notarius --version`](cli.md#command-summary) as a diagnostic after
|
||||
installation; its syntax and semantics are owned by the [CLI reference](cli.md).
|
||||
The maintainer publication process, including tag guards and verification,
|
||||
belongs to [Source Releases](release.md). macOS builds are best-effort for
|
||||
development, and Windows is unsupported.
|
||||
|
||||
## State Surfaces
|
||||
|
||||
Each run can use independent roots with different retention and access-control
|
||||
@@ -42,6 +59,45 @@ evidence publication. Apply an appropriate umask and output-root access policy
|
||||
before enabling that option; the requested output modes alone may not be
|
||||
suitable for transcript-bearing bundles.
|
||||
|
||||
## PromptKit Profile Deployment
|
||||
|
||||
Profile deployment has four distinct layers:
|
||||
|
||||
| Layer | Owner | Operational role |
|
||||
| --- | --- | --- |
|
||||
| Prompts and schemas | Notarius module families | Embedded request and structured-output definitions. They are not deployment profile files. |
|
||||
| Fallback profiles | Notarius module families | Embedded application defaults, including D&D's `dnd-extraction` profile. |
|
||||
| Built-in profiles | PromptKit | Upstream catalog entries available when no higher-precedence source defines an ID. |
|
||||
| Operator profiles | Deployment filesystem | Complete environment-specific definitions selected by `promptkit.profile_file` or `promptkit.profile_dir`. |
|
||||
|
||||
The maintained D&D pipeline uses the workload ID `dnd-extraction`. The
|
||||
embedded fallback makes that ID usable without an operator file. Production,
|
||||
development, and local deployments can each install a different complete
|
||||
definition for the same ID, retaining the pipeline while choosing their own
|
||||
model, backend, timeout, or reasoning policy. An operator definition wins over
|
||||
the fallback; it is not merged with it. The configuration field and full
|
||||
precedence rules are owned by [Configuration](config.md#promptkit-profiles).
|
||||
|
||||
Use a profile source owned by the service account, keep it readable only by
|
||||
the intended operator, and supply provider credentials through the service
|
||||
environment—not in the Notarius configuration or profile YAML. The maintained
|
||||
[operator profile](../examples/profiles/dnd-extraction.yml) is secret-free and
|
||||
can be copied as a format starting point. Validate a deployment without a
|
||||
provider call or credentials:
|
||||
|
||||
~~~sh
|
||||
notarius config validate --config /etc/notarius/config.yml --pipeline dnd-session
|
||||
~~~
|
||||
|
||||
An unset optional `api_key_env` reaches the provider without authorization and
|
||||
may receive a 401 or 403 response.
|
||||
|
||||
Profile paths are currently resolved from the process working directory, not
|
||||
from the configuration file. The complete example's
|
||||
`./examples/profiles/dnd-extraction.yml` path is valid for a repository-root
|
||||
invocation only. Use absolute paths such as
|
||||
`/etc/notarius/profiles/dnd-extraction.yml` for services and containers.
|
||||
|
||||
## Run Lifecycle
|
||||
|
||||
Use the [run command](cli.md#run) to start a pipeline. A valid invocation loads
|
||||
@@ -53,6 +109,33 @@ On success, the command reports the output bundle path. A warning-bearing run
|
||||
still succeeds and reports its warning count on standard error. Errors and
|
||||
their exit classes are defined in the [CLI reference](cli.md#output-streams-and-exit-statuses).
|
||||
|
||||
## Validation Retries And Terminal Outcomes
|
||||
|
||||
Each producer binding has one outer **retries** budget. It covers complete
|
||||
producer attempts for operational failures, invalid structured output,
|
||||
normalizer fallback retry, and semantic correction. It is independent from
|
||||
PromptKit's structural-repair calls inside one completion and from an
|
||||
LLM-backed validator's own retry budget. A semantic correction rebuilds the
|
||||
ordinary producer request and supplies only the latest rejected model response
|
||||
plus aggregated validator guidance; it is not a conversation replay.
|
||||
|
||||
After the applicable budgets are exhausted, the resolved
|
||||
[`validation_policy`](config.md#pipelines) determines the result. Structural
|
||||
failure and semantic rejection normally fail the run; an explicit
|
||||
`reject_output` records a rejection and allows unrelated work to finish. A
|
||||
validator execution failure normally uses `warn_continue`, which keeps an
|
||||
otherwise accepted result in the current run with `incomplete` validation
|
||||
provenance. It emits one bounded warning for every validator whose execution
|
||||
budget was exhausted. A corrected result that later passes validation does not
|
||||
retain abandoned-attempt warnings.
|
||||
|
||||
Treat a successful process exit as a completed run, not as proof that every
|
||||
candidate was fully validated. Inspect the receipt's `validation_status`,
|
||||
`validation_summaries`, rejection count, and warning count when an orchestrator
|
||||
requires complete validation. The durable fields and their meanings are owned
|
||||
by the [run-result receipt](integrations/run-result.md) and
|
||||
[published JSON output contract](integrations/json-output.md).
|
||||
|
||||
## Output Bundles
|
||||
|
||||
Each successful run receives a generated safe run identifier and writes beneath:
|
||||
@@ -74,9 +157,9 @@ are defined in [Accepted Chunk Map](integrations/chunk-map.md). An optional
|
||||
[evidence context](integrations/evidence-context.md) contains source-unit text
|
||||
and metadata. It is not a cache or debug artifact: retain it with the output
|
||||
bundle only for as long as consumers need it, and apply source-content access
|
||||
controls to the entire bundle. Selected lanes may collectively cite most of a
|
||||
transcript, so a broad allowlist can make the evidence artifact nearly as
|
||||
sensitive and large as the source itself.
|
||||
controls to the entire bundle. Its selected source-unit excerpt may include
|
||||
every source unit once when coverage is broad or its configured window is
|
||||
large, so do not assume a byte or token reduction or reduced sensitivity.
|
||||
|
||||
## Chunk-Plan Cache
|
||||
|
||||
@@ -102,7 +185,9 @@ The configured cache mode controls one invocation:
|
||||
A reused plan is still materialized and validated against the current source.
|
||||
If a prior plan no longer gives acceptable results, use a refresh run rather
|
||||
than editing cache files. Deleting a plan is recoverable but can repeat costly
|
||||
chunking work.
|
||||
chunking work. A plan accepted only under incomplete validation is not
|
||||
published, and a rejected cache hit falls through to ordinary generation rather
|
||||
than becoming a correction candidate.
|
||||
|
||||
## Checkpoint Recording, Resume, And Recompute
|
||||
|
||||
@@ -117,9 +202,21 @@ compatible recorded work. A resume request fails when checkpoint recording is
|
||||
disabled. Without **--resume**, a recording-enabled run executes normally and
|
||||
does not load checkpoint state. Compatibility includes the resolved pipeline,
|
||||
input, selected lanes, runtime overrides, reference provenance, LLM-profile
|
||||
provenance, and prepared-component fingerprints. A changed identity produces a
|
||||
cold miss; Notarius does not migrate, rewrite, or delete older checkpoint
|
||||
directories.
|
||||
provenance, the effective PromptKit profile-source fingerprint, and
|
||||
prepared-component fingerprints. When a local PromptKit backend is configured,
|
||||
compatibility also includes a non-secret fingerprint of its endpoint. Changing
|
||||
profile content or the local endpoint causes a cold miss; changing only the
|
||||
local concurrency limit does not. A changed identity produces a cold miss;
|
||||
Notarius does not migrate, rewrite, or delete older checkpoint directories.
|
||||
Reasoning-effort inheritance, replacement, and explicit clearing are distinct
|
||||
runtime identities, so checkpoints created under one state are not reused by
|
||||
either of the others.
|
||||
|
||||
Only accepted, completely validated chunk, extract, merge, and normalize
|
||||
results are checkpointed for reuse. Rejected, structurally invalid, and
|
||||
validation-incomplete producer results remain non-reusable, even when a
|
||||
`warn_continue` result advanced during its original run. A resumed invocation
|
||||
therefore reruns that producer rather than treating degraded state as accepted.
|
||||
|
||||
Checkpoint state is confined below an identity-specific path:
|
||||
|
||||
@@ -175,11 +272,16 @@ Only a [debug-enabled run](cli.md#run) creates a bundle:
|
||||
~~~
|
||||
|
||||
The summary contains redacted invocation and resolution information plus run,
|
||||
warning, checkpoint, chunk-plan, and terminal reporting artifacts. The trace
|
||||
contains allowlisted application diagnostic records and can include source or
|
||||
derived application data. Neither surface is a cache input. Do not treat a
|
||||
debug bundle as safe to share merely because its configuration summary is
|
||||
redacted.
|
||||
warning, checkpoint, chunk-plan, and terminal reporting artifacts. Attempt
|
||||
terminal records contain bounded attempt kinds, validator outcomes, policy,
|
||||
decision, PromptKit repair count, and usage; they do not contain assistant
|
||||
responses or complete correction messages. The trace contains allowlisted
|
||||
application diagnostic records and can include source, model, and correction
|
||||
content. Neither surface is a cache input. Do not treat a debug bundle as safe
|
||||
to share merely because its configuration summary is redacted. Invocation
|
||||
metadata omits reasoning effort when it is inherited, records the replacement
|
||||
value when one is supplied, and records an empty value when inherited reasoning
|
||||
was explicitly cleared.
|
||||
|
||||
Notarius never creates debug state without an explicit request and never
|
||||
automatically deletes a requested bundle. If allocation succeeds, the command
|
||||
@@ -207,10 +309,71 @@ or automatic cleanup command.
|
||||
|
||||
## Operational Limits
|
||||
|
||||
Provider retries and timeouts are supplied by the selected Scriptorium profile.
|
||||
Module retry settings and concurrency limits are configuration contracts; see
|
||||
[module bindings](config.md#module-bindings-and-validators) and
|
||||
Provider execution settings and the generation timeout come from the selected
|
||||
PromptKit profile. The invocation-only **--reasoning-effort** and
|
||||
**--clear-reasoning-effort** controls may replace or clear that profile setting
|
||||
for all LLM-backed calls in one run without changing the profile. PromptKit
|
||||
structural output repair happens within one structured-completion call. Its
|
||||
effective `structured_output_repair_attempts` limit is resolved from the
|
||||
selected binding, then the pipeline, then the prompt declaration; see
|
||||
[module bindings](config.md#module-bindings-and-validators). This is distinct
|
||||
from Notarius binding **retries**, which rerun the complete module operation
|
||||
and validation chain and do not consume or replenish the structural-repair
|
||||
limit. The maintained production prompts declare one repair attempt, paid only
|
||||
after a structural failure. One structured completion with repair budget **R**
|
||||
makes at most **R + 1** serial provider calls. If one stage attempt performs
|
||||
**C** structured completions, a binding with **retries: N** has a maximum of
|
||||
**(N + 1) * C * (R + 1)** provider calls; LLM-backed validators have their own
|
||||
corresponding invocation counts and budgets. This is an upper bound, not a
|
||||
promise that every call reaches a provider.
|
||||
|
||||
Timeouts are layered. Caller cancellation is the outer authority. A positive
|
||||
effective generation timeout adds an inner request deadline, while zero
|
||||
disables only that generation deadline. The HTTP client timeout remains a
|
||||
transport-wide cap. Notarius does not add another timeout around PromptKit.
|
||||
Repairs are serial within the same caller context, so their worst-case latency
|
||||
and cost follow the provider-call bound above; provision run deadlines and
|
||||
provider budgets accordingly. Credentials remain optional unless the selected
|
||||
PromptKit profile requires one, in which case preparation fails before a
|
||||
provider call when its configured credential is unavailable.
|
||||
The pinned upstream boundary and profile-format links are in
|
||||
[PromptKit Integration](integrations/pkg-promptkit.md).
|
||||
|
||||
Concurrency has two independent layers. Notarius **total_llm** defaults to 16
|
||||
and is the application-wide provider-call limit shared by all backends,
|
||||
modules, retries, and validators. PromptKit may impose a narrower admission
|
||||
limit for the selected backend. The effective active-generation bound is the
|
||||
intersection of the Notarius limit, any PromptKit backend limit, and work made
|
||||
available by the pipeline. Built-in OpenRouter profiles use PromptKit's
|
||||
upstream backend limit; endpoint-only profiles have no PromptKit backend limit
|
||||
and remain bounded by Notarius. For the configured local backend, a zero
|
||||
**concurrency_limit** leaves only the Notarius scheduler as a call limit. A
|
||||
positive value makes the effective active local-generation bound the smaller
|
||||
of **total_llm** and that local limit, so a local limit of four permits no more
|
||||
than four active local generations.
|
||||
|
||||
The Notarius scheduler admits one logical structured completion and holds that
|
||||
permit while PromptKit performs its serial corrective calls. PromptKit applies
|
||||
its selected-backend admission to each provider call; Notarius does not
|
||||
reacquire a permit or add another scheduler for a repair.
|
||||
|
||||
For a positive local limit, PromptKit owns its default waiting capacity and
|
||||
admission behavior. When a PromptKit backend has admitted all active and queued
|
||||
work, a new call fails as capacity exhaustion before generation. The adapter
|
||||
maps that failure to Notarius's existing provider-neutral capacity error and
|
||||
does not retry it. The calling stage's configured retry policy applies
|
||||
normally, and the run fails if those attempts are exhausted. Caller
|
||||
cancellation remains authoritative. Configuration contracts are documented
|
||||
under [PromptKit profiles](config.md#promptkit-profiles) and
|
||||
[concurrency](config.md#concurrency-output-cache-and-debug). Extract-worker
|
||||
limits and actual provider-call limits are independent. Notarius writes local
|
||||
filesystem state only; remote storage, archival, and retention automation are
|
||||
outside the implemented CLI.
|
||||
|
||||
Every run has an effective prompt session used for provider routing and run
|
||||
provenance. The generated default is stable for the same input module and raw
|
||||
input bytes; use [**--session-id**](cli.md#run) only when intentionally grouping
|
||||
different invocations. Both generated and explicit values can be visible to
|
||||
providers, manifests, checkpoints, and requested debug bundles. Do not put
|
||||
credentials or other secrets in an explicit session identifier; command-line
|
||||
values are not a credential mechanism.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user