Files
ThothII/docs/contracts/workspace-evidence-v3.md
T

6.8 KiB

Workspace Evidence v3 contract

This is the canonical public contract for the optional evidence object in a schema-v3 workspace descriptor. Evidence is optional: a valid v3 descriptor without it remains operational. When present, evidence is strict: it contains source and a defaulted strict policy; every source variant and the policy reject unknown keys.

Filesystem source

A filesystem source uses the exact URI workspace-content/<workspace.id>/evidence. patterns is a nonempty list of unique, normalized relative POSIX globs. Its defaults are patterns: ["**/*.md"] and max_bytes: 10485760.

Example: filesystem

evidence:
  source:
    type: filesystem
    uri: workspace-content/example/evidence
    patterns:
      - "**/*.md"
    max_bytes: 10485760
  policy:
    max_chunk_chars: 4000
    retain_published_generations: 3

Safe: workspace-content/example/evidence. Unsafe filesystem identities include /srv/evidence, workspace-content/another/evidence, and workspace-content/example/../another/evidence because absolute, cross-namespace, and traversal paths are not canonical.

HTTP source

uris is a nonempty, unique list of canonical HTTP or HTTPS provenance identities. Each URI must have no whitespace, control character, backslash, userinfo, query, or fragment. Public mode uses authentication: none; signed mode uses authentication: signed_urls_file. Defaults are authentication: none, connect_timeout_ms: 5000, read_timeout_ms: 30000, max_bytes: 10485760, max_redirects: 5, allow_private_hosts: false, and max_cache_bytes: 67108864.

Example: http

evidence:
  source:
    type: http
    uris:
      - https://evidence.example.invalid/report.md
    authentication: signed_urls_file
    connect_timeout_ms: 5000
    read_timeout_ms: 30000
    max_bytes: 10485760
    max_redirects: 5
    allow_private_hosts: false
    max_cache_bytes: 67108864
  policy:
    max_chunk_chars: 4000
    retain_published_generations: 3

The shown provenance URI is safe and query-free. An HTTP fragment identity such as https://evidence.example.invalid/report.md#section is unsafe. Query-bearing and userinfo-bearing HTTP identities are rejected; public documentation must not spell or publish a signed transport URL.

S3 source

uri is a canonical s3:// identity with a valid bucket and no port, userinfo, query, or fragment. endpoint_url, when present, is an origin-only HTTP(S) URL; region, when present, is nonblank. Defaults are credentials: ambient, trusted_endpoint: false, allow_private_endpoint: false, allow_insecure_endpoint: false, max_bytes: 10485760, max_objects: 10000, max_pages: 100, and page_size: 1000 (and page size cannot exceed 1000). A custom endpoint requires trusted_endpoint: true; an HTTP endpoint additionally requires allow_insecure_endpoint: true. Static mode uses credentials: static_files, requires access-key and secret-key files together, and permits an optional session-token file.

Example: s3

evidence:
  source:
    type: s3
    uri: s3://example-evidence/curated/
    credentials: static_files
    trusted_endpoint: false
    allow_private_endpoint: false
    allow_insecure_endpoint: false
    max_bytes: 10485760
    max_objects: 10000
    max_pages: 100
    page_size: 1000
  policy:
    max_chunk_chars: 4000
    retain_published_generations: 3

Safe: s3://example-evidence/curated/. Unsafe identities include s3://Invalid_Bucket/evidence and s3://example-evidence/evidence#section. S3 userinfo and query identities are rejected in prose and implementation; no credential-bearing example is published.

Policy

The strict policy defaults to max_chunk_chars: 4000 and retain_published_generations: 3.

Installation files

The namespace is the workspace ID uppercased with every - changed to _. All Evidence variables hold file paths, never credential or signed-URL values.

Mode Variable File contract
Signed HTTP THT_WS_<NAMESPACE>_EVIDENCE_SIGNED_URLS_FILE Required for signed_urls_file; nonempty JSON string array in declared-URI order; query-stripped identities must match uris.
Static S3 pair THT_WS_<NAMESPACE>_EVIDENCE_ACCESS_KEY_FILE and THT_WS_<NAMESPACE>_EVIDENCE_SECRET_KEY_FILE Required together for static_files.
Static S3 session THT_WS_<NAMESPACE>_EVIDENCE_SESSION_TOKEN_FILE Optional, and valid only with the required access/secret pair.

Every variable is an absolute path to a readable regular file whose resolved target is strictly below one of the roots configured by THT_WORKSPACE_SECRET_ROOTS. Scalar S3 files are nonempty UTF-8 tokens without whitespace. Public docs, exports, and rendered YAML never expose file contents. changeme, replace-me, YOUR_SECRET, <secret>, access-key-looking strings, and any credential-bearing or query-bearing URI are forbidden as public placeholder values.

One shared registry repository

All workspace namespaces live in one Git repository:

registry.git/
├── workspaces/
│   ├── example.yaml
│   └── another.yaml
├── workspace-content/
│   ├── example/evidence/...
│   └── another/evidence/...
└── workspace-docs/
    ├── example/{contract.env.example,README.md}
    └── another/{contract.env.example,README.md}

Curators change only workspace-content/<id>/evidence/** through a normal clone. The API publishes only workspaces/<id>.yaml and workspace-docs/<id>/{contract.env.example,README.md}. It never writes Evidence source bytes.

Registry revision and phase ownership

Relationship Contract
Revision identity The descriptor blob and filesystem Evidence root tree are checked at the same 40-hex Git commit.
Content-only revision An Evidence-only commit changes authoritative revision.commit even when the descriptor blob is unchanged.
Browser Create and edit flows preserve and show a read-only Evidence summary.
Export Export remains exactly manifest, descriptor, contract, and README; it excludes Evidence bytes.
P1 Validates the lexical URI and proves the declared filesystem root object is a Git tree at that same commit; it does not recursively inspect nested symlinks.
P6 Owns commit-addressed materialization, realpath and recursive containment, nested-symlink checks, and race checks.

P1 performs no acquisition, extraction, preprocessing/indexing, embeddings, Qdrant writes, ACTIVE publication, retention, or GC.

Operator validation

After the runtime configuration is rendered or acquired, validate it with the exact per-command option ordering:

tht config check -c <path>

Stop after validation. P2/P6 later owns preprocessing and materialization.

Acceptance states

These gates are independent and are not implied by this documentation contract.

automated integration: PENDING manual acceptance: PENDING