Files
notarius/docs/integrations/json-output.md

5.7 KiB

JSON Output

This document is the durable JSON output file-format contract produced by the implemented json output module and written by the CLI.

Output Directory

The CLI writes logical output files under:

<output-root>/<run-id>/

The default output root is ./notarius-output. Operational behavior is covered in Operations.

Files

The json output module writes:

  • index.json
  • manifest.json
  • artifacts/<artifact-type>.json, one file per approved artifact type
  • rejected.json
  • warnings.json

Files are pretty-printed JSON with a trailing newline.

index.json

Shape:

{
  "manifest_file": "manifest.json",
  "artifact_files": [
    {
      "artifact_type": "dnd.spell_cast",
      "file": "artifacts/dnd.spell_cast.json"
    }
  ],
  "rejected_file": "rejected.json",
  "warnings_file": "warnings.json"
}

artifact_files is sorted by artifact type. It is empty when no artifacts are approved.

manifest.json

manifest.json contains a run manifest:

{
  "run_id": "run-123",
  "pipeline_id": "dnd-session",
  "pipeline_digest": "sha256:...",
  "input_module": "seriatim",
  "chunker": "dnd/scenes",
  "module_metadata": {
    "chunker": {
      "prompt_id": "dnd.scenes",
      "prompt_version": "v1",
      "prompt_sha256": "sha256:...",
      "response_schema_key": "dnd_scenes",
      "response_schema_id": "notarius.dnd.scenes",
      "response_schema_name": "notarius_dnd_scenes_v1",
      "response_schema_version": "v1",
      "response_schema_sha256": "sha256:..."
    }
  },
  "source_digests": ["sha256:..."],
  "extractors": ["dnd/spells"],
  "merger": "appendorder",
  "normalizer": "noop",
  "output_encoder": "json",
  "artifact_lanes": [
    {
      "id": "spells",
      "extractor": "dnd/spells",
      "merger": "appendorder",
      "normalizer": "noop"
    }
  ],
  "llm_profiles": [
    {
      "id": "mistral-small-3",
      "provider": "scriptorium",
      "model": "configured-model"
    }
  ],
  "validation_status": "approved",
  "started_at": "2026-01-01T00:00:00Z",
  "completed_at": "2026-01-01T00:00:01Z"
}

Fields with empty values may be omitted by JSON encoding.

source_digests contains source document digests only. Bound references are recorded separately under references, which contains provenance only: target stage, lane ID when present, slot name, origin type and URI, digest, media type, byte size, and binding source. Reference content is not written to durable output.

Reference stage is chunk, extract, or normalize. lane_id is omitted for chunk references and present for extract and normalize references.

When references are bound, the manifest section has this shape:

{
  "references": [
    {
      "stage": "extract",
      "lane_id": "spells",
      "slot_name": "roster",
      "origin_type": "file",
      "origin_uri": "file:///absolute/path/roster.txt",
      "digest": "sha256:...",
      "media_type": "text/plain",
      "size_bytes": 123,
      "binding_source": "config"
    }
  ]
}

Reference media types are inferred from file extensions and recorded as canonical base media types. Unknown extensions are recorded as application/octet-stream.

module_metadata is omitted when no singleton module provides metadata.

validation_status is approved when no candidates were rejected and rejected when one or more candidates were rejected.

Top-level module_metadata is reserved for singleton pipeline modules (input, chunker, and output). Lane-owned module metadata remains under artifact_lanes[].metadata.

Artifact Files

Each artifact file has this shape:

{
  "artifact_type": "dnd.spell_cast",
  "artifacts": [
    {
      "extractor_key": "dnd/spells",
      "artifact_type": "dnd.spell_cast",
      "schema_version": "v1",
      "payload": {},
      "source_refs": [
        {
          "source_id": "session-alpha",
          "start_unit_id": 1,
          "end_unit_id": 1
        }
      ]
    }
  ]
}

Artifact envelope fields:

  • extractor_key: extractor module key.
  • artifact_type: artifact type.
  • schema_version: artifact schema version.
  • payload: artifact-type-specific JSON payload.
  • source_refs: optional generic source references.
  • metadata: optional artifact metadata.

Artifact file names are produced by sanitizing the artifact type:

  • characters outside A-Z, a-z, 0-9, ., _, and - become _;
  • repeated .. sequences are replaced;
  • leading and trailing ., _, and - are trimmed;
  • empty sanitized names are rejected.

For current D&D spell-cast artifacts, the file is artifacts/dnd.spell_cast.json.

rejected.json

Shape:

{
  "rejected": [
    {
      "candidate": {
        "index": 0,
        "extractor_key": "dnd/spells",
        "artifact_type": "dnd.spell_cast",
        "schema_version": "v1",
        "payload": {},
        "source_refs": []
      },
      "validator_name": "dnd/spells/source_refs",
      "reason_code": "missing_source_ref",
      "message": "spell cast candidate must include at least one source ref"
    }
  ]
}

rejected is an empty array when no candidates are rejected.

warnings.json

Shape:

{
  "warnings": [
    {
      "scope": "output",
      "reason_code": "example_warning",
      "message": "warning message"
    }
  ]
}

warnings is an empty array when no warnings are reported.

Path Safety

The output module returns slash-separated logical paths. The CLI also validates logical output names before writing:

  • names must be non-empty;
  • names must be relative;
  • names must be clean;
  • names must use /, not \;
  • names must not contain ..;
  • resolved paths must stay under the run output directory.

Durable writes are atomic per file.