Skip to the content.

RFC 0022: Spec-Based Appraisal and Curated App List

Summary

Add an explicit appraisal layer on top of RFC 0020 facts: a curator publishes a small declarative spec, an evaluator judges an attested app’s facts plus source at tree_hash against that spec, and the result is a per-clause verdict. The verdict gates a curated homepage/listing view and supplies the failing clauses that RFC 0021 apps spend against.

This does not change RFC 0020’s rule that verify() returns facts, not a verdict. The curated list is one named curator’s policy: “apps that pass curator C’s spec S, judged by evaluator E.” The spec, evaluator version, inputs, and verdict are published so a consumer can adopt that curator, swap in a different one, or ignore the curation entirely.

Problem

RFC 0020 deliberately stops before appraisal. It proves a binding from endpoint to platform quote, on-chain approval, source repo/commit/tree_hash, and daemon binding quote, then returns facts. That is correct for software consumers, but it leaves two product gaps:

The hard constraint is RFC 0020’s “no universal safe.” A curated verdict must not pretend to be a platform truth. It is a named curator’s explicit policy over 0020 facts and source. Multiple curators and multiple specs are expected.

Files to Modify

Implementation

  1. Spec language. A spec is a small declarative set of clauses, not prose. Each clause has { id, claim, evidence_required, severity }, where evidence_required names what the evaluator must inspect: 0020 facts, RFC 0021 evidence artifacts, source files at tree_hash, or known substrate files. Example clauses grounded in this repo:
    • broker.socket_only: handler never receives raw docker.sock; broker access is through the filtered broker mount (proxy/runtimes.py, commit ddb088f7).
    • secrets.broker_only: raw upstream secrets are absent from handler env; secrets flow through RFC 0018 broker grants.
    • manifest.public_env_redacted: public project manifests redact env values (proxy/ingress.py, commit 1bb89b7f).
    • crypto.constant_time_compare: secret comparison paths use constant-time primitives; the timing-leak examples are negative fixtures (examples/timing-leak-demo, examples/rsa-timing-demo).
    • substrate.oci_runtime_corroborated: the app corroborates the daemon’s OCI-runtime claim using app-visible evidence (examples/isolation-probe, /_api/substrate).
  2. Evaluator input. The evaluator starts from RFC 0020 facts, fetches the source at Facts.source.tree_hash, and reads only the app handler, declared evidence artifacts, and the substrate references named by the spec. This is the automated form of the small per-app audit promised in index.md.
  3. Evaluator output. Emit { curator, spec_id, spec_hash, evaluator_id, evaluator_hash, facts_hash, source_tree_hash, verdict: pass|fail|needs_review, clauses[] }. Each clause result is { id, result, evidence: [{ path, line, note }], missing, remediation_hint }. A top-level verdict is derived only from the named spec’s clause rules; consumers should be able to ignore it and read the clause facts directly.
  4. Attested vs. consumer-run judge. The first implementation may be consumer-run policy: publish the spec, evaluator prompt/code/version, input hashes, and output so anyone can rerun it. A stronger deployment runs the evaluator itself as an attested app and publishes its own RFC 0020 evidence bundle, making “curator C using evaluator E” reproducible through the same mechanism as other apps. The daemon should model both by recording evaluator identity and hashes, not by trusting an opaque verdict string.
  5. Curated list. Add a curated view over the existing raw attested list. The public homepage shows apps whose latest verdict passes curator C’s active spec S, with per-clause badges and a link to the full verdict. The raw mode == "attested" JSON/list remains available because attestation evidence is still independent of curation.
  6. Feedback edge into RFC 0021. Failed clauses become spend targets: target = { spec_id, clause_id, current_evidence, remediation_hint }. An app spends tokens to change the handler or add evidence artifacts, re-promotes at a new tree_hash, and resubmits for appraisal. Closing the failing clause is the concrete self-improvement loop.

Testing & Validation Requirements

Report Requirements

Out of Scope