OIP Developer Guide
Document class: Practical (implementation)
Version: v0.1 Companion to:
OIP-Specification-v1.0.md (Normative) ·
OIP-Reference-Architecture-v0.1.md (Informative)
Audience: engineers implementing an OIP publisher,
registry, runtime, or agent client
How to use this guide. The Specification is the source of truth for every field; the Reference Architecture explains the why. This guide is the fast path to a working implementation: the objects you must produce, the endpoints you must call, the order to do them in, and one complete end-to-end example (the Travel Genie Da Nang object) from authoring through a verified outcome that moves trust. JSON here is illustrative and abbreviated — consult the Specification's schemas for
additionalProperties: false, required fields, and the null↔︎unknown pairing rules.
Agent Skills / SKILL.md compatibility
OIP complements Agent Skills / SKILL.md. SKILL.md packages agent-usable capabilities. OIP adds outcome identity, evidence, trust, provenance, licensing, and accountability around those capabilities. OIP should reference or export validated SKILL.md packages rather than replacing them.
Future adapter: skill_md_export.v1.
0. Pick your role
What you build depends on which actor you are. Most teams implement one or two of these.
| You are building… | You must… | Key sections |
|---|---|---|
| Publisher | Author + sign a manifest and trust manifest; register it. | §2, §3, §4 |
| Registry | Serve discovery/trust/ratings/license endpoints; recompute trust. | §5, §6, §7 |
| Runtime | Resolve install refs; execute; emit Execution Records + Configurations. | §8 |
| Agent client | Discover → evaluate trust → verify → license → install. | §5, §9 |
1. Environment & conventions
- Transport: HTTPS + JSON. REST is the baseline; MCP and A2A are thin wrappers over the same data (§5.4).
- IDs are namespaced URIs:
oi:outcome intelligence,pkg:package,epi:/did:-style identity,mf_manifest version,er_execution record,lic_license,re_rating event. - Hashing:
sha256; package and manifest hashes are mandatory. - Signatures:
ed25519over the manifest hash and package hash. - Time: RFC3339 UTC.
- Honesty rule (enforced by validator): an absent
value is
nulland carries anunknowns[]entry with a reason code. Never default, never guess.skip ≠ no.
2. Authoring an Outcome Manifest (Publisher)
The manifest is the source of truth for what the object is. Minimum viable manifest (abbreviated — see Spec §7 for all fields):
{
"schema_version": "oip.outcome-manifest.v1",
"outcome_id": "oi:travel_genie.danang_relocation",
"manifest_id": "mf_9f2a1c7b4e0d6a3c",
"display_name": "Travel Genie — Da Nang Relocation",
"short_description": "Guides a remote worker through relocating to Da Nang.",
"domain": "relocation",
"outcome_type": "guided_relocation",
"publisher": { "publisher_id": "pub:deepsenz", "identity_status": "first_party_verified",
"signature_ref": "tm_danang_reloc_v1#publisher_signature" },
"version": "1.0.0",
"lifecycle_status": "active",
"package_refs": [{ "package_id": "pkg:cap.travel_genie.danang_relocation.v1",
"package_type": "cap", "content_hash": "sha256:6b1f…e90a",
"host": "deepsenz", "uri": "https://packages.skillsenz.ai/cap/…/1.0.0.capsule" }],
"install_refs": [{ "for_package": "pkg:cap.travel_genie.danang_relocation.v1",
"runtime": "mysenz", "method": "capsule_install", "requires_license": true }],
"compatibility": { "runtimes": ["mysenz"],
"standards": { "mcp": {"supported": true}, "a2a": {"supported": true},
"skill_md": {"supported": true} } },
"trust": { "trust_manifest_ref": "https://api.skillsenz.ai/v1/outcomes/oi:travel_genie.danang_relocation/trust",
"overall_trust_score": 72, "trust_band": "Promising", "confidence_score": 76,
"sample_size_warning": true, "score_version": "trustsenz.score.v1" },
"freshness": { "freshness_date": "2026-06-08", "expires_date": "2026-09-08", "freshness_score": 0.74 },
"pricing": { "model": "one_time", "amount": 19.0, "currency": "USD", "free_preview": true },
"license": { "license_types": ["free_preview", "one_time"], "default_license_type": "one_time" },
"created_at": "2026-06-09T12:00:00Z", "updated_at": "2026-06-09T12:00:00Z",
"unknowns": []
}Authoring checklist
3. Authoring the Trust Manifest & first Trust Metric (Publisher + Registry)
Trust is two layers: the publisher signs a Trust Manifest (provenance, signatures, disclaimers, limitations); the registry's TrustSenz computes the values (the Metric) from evidence. A publisher never sets its own score.
A pre-launch object with one verified journey:
{
"schema_version": "oip.trust-metric.v1",
"outcome_id": "oi:travel_genie.danang_relocation",
"score_version": "trustsenz.score.v1",
"overall_trust_score": 72,
"trust_band": "Promising",
"confidence_score": 76,
"sample_size_warning": true,
"journey_count": 1,
"successful_journey_count": 1,
"outcome_success_rate": 1.0,
"outcome_success_rate_wilson_lb": 0.21,
"outcome_success_rate_beta_mean": 0.67,
"rating_count": 0,
"user_rating_average": null,
"community_score": null,
"evidence_score": 0.79,
"freshness_score": 0.74,
"conversion_score": 0.55,
"limitations": ["Single verified journey (n=1).", "Self-report-dominant evidence."],
"scoring_explanation": "Driven by strong first-party evidence (0.79) and freshness, held down by a Wilson-bounded conversion (0.55 from 1-of-1) and a confidence cap. Ratings contribute 0 (below n=20).",
"score_inputs": { "weights": "trustsenz.score.v1",
"components_null_dropped": ["combined_rating_average", "community_score"],
"journey_refs": ["er_danang_focus_run1"] }
}The three trust rules you must not break
Null is dropped, not zeroed. A missing component (no ratings yet) is excluded from the weighted mean and the remaining weights re-normalized. Never substitute 0.
Wilson before display. Compute the Wilson 95% lower bound on the success rate; use that (not the raw rate) for the conversion component. One success of one → ≈0.21, never 1.0.
# Wilson lower bound, 95% (z=1.96) from math import sqrt def wilson_lb(successes, n, z=1.96): if n == 0: return None p = successes / n d = 1 + z*z/n centre = p + z*z/(2*n) margin = z * sqrt((p*(1-p) + z*z/(4*n)) / n) return (centre - margin) / d wilson_lb(1, 1) # ≈ 0.2065Ratings are gated. Below
min_journey_threshold(default 20), ratings display but carry zero score weight.
4. Signing & publishing (Publisher → Registry)
1. canonicalize manifest JSON → manifest_bytes
2. manifest_hash = sha256(manifest_bytes)
3. package_hash = sha256(package_bytes)
4. publisher_signature = ed25519_sign(privkey, manifest_hash || package_hash)
5. POST the manifest + trust manifest to the registry
POST /v1/outcomes
Content-Type: application/json
{ "manifest": { … }, "trust_manifest": { … } }
Registry response on success: 201 Created with the
canonical links block. On failure, a stable refusal
code (never a silent fix):
| Refusal | Cause |
|---|---|
manifest_hash_mismatch |
recomputed hash ≠ supplied |
signature_invalid |
signature does not verify |
package_hash_mismatch |
package bytes ≠ declared hash |
trust_escalation_refused |
trust manifest claims verified without a verification
ref |
5. Discovery & the read API (Registry serves, Agent calls)
5.1 Capability document
GET /.well-known/oip.json
{ "protocol": "oip", "version": "1.0", "score_version": "trustsenz.score.v1",
"endpoints": { "outcomes": "/v1/outcomes", "openapi": "/openapi.json", "mcp": "/mcp" },
"license_types": ["free", "one_time"] }5.2 Core read endpoints
GET /v1/outcomes?domain=relocation
GET /v1/outcomes/{id}
GET /v1/outcomes/{id}/trust
GET /v1/outcomes/{id}/ratings
The list endpoint returns summaries that always carry band + confidence + sample-size warning — never a naked score:
{ "outcomes": [
{ "outcome_id": "oi:travel_genie.danang_relocation", "display_name": "Travel Genie — Da Nang Relocation",
"domain": "relocation", "overall_trust_score": 72, "trust_band": "Promising",
"confidence_score": 76, "sample_size_warning": true } ] }5.3 Agent evaluation loop (pseudo-code)
caps = get("/.well-known/oip.json")
hits = get("/v1/outcomes?domain=relocation")["outcomes"]
best = pick(hits, key=lambda o: (o["trust_band"], o["confidence_score"]))
trust = get(f"/v1/outcomes/{best['outcome_id']}/trust")
if trust["sample_size_warning"]:
log("early evidence — n=%d" % trust["journey_count"]) # decide if acceptable for the stakes
manifest = get(f"/v1/outcomes/{best['outcome_id']}")
assert my_runtime in manifest["compatibility"]["runtimes"]5.4 Same data over MCP and A2A
- MCP tools:
discover_outcomes,get_outcome_manifest,get_trust_manifest,get_outcome_ratings,request_license,verify_license,get_install_refs,submit_outcome_feedback. - A2A agent card capabilities:
discover,evaluate_trust,compare_trust,inspect_ratings,submit_feedback,license,install_reference.compare_trustMUST return band + confidence + warning alongside any score.
6. Licensing & verification (Registry/License Server, Agent)
6.1 Request a license
POST /v1/outcomes/oi:travel_genie.danang_relocation/license
{ "license_type": "one_time", "principal": "principal:brian",
"agent_authorization": { "agent_id": "agent:herman", "authorized": true },
"payment_ref": "acp:txn_… (if priced)" }
{ "license_id": "lic_8c2…", "license_token": "lt_…", "entitlement": "install_and_execute",
"expiration": null, "package_access": ["pkg:cap.travel_genie.danang_relocation.v1"] }6.2 Verify (recommended order — stop on first failure)
GET /v1/licenses/lt_…/verify
1. manifest authenticity → recompute manifest_id digest
2. publisher signature → ed25519 verify
3. package hash → sha256(bytes) == content_hash
4. license validity → entitlement covers package + principal
5. freshness → now < expires_date ? else warn "stale situational data"
6. trust score status → score_version understood; read band/confidence/warning
7. compatibility → runtime in manifest.compatibility
8. deprecation → lifecycle_status == active
6.3 Install
GET /v1/outcomes/oi:travel_genie.danang_relocation/package
Authorization: Bearer lt_…
→ resolves the install ref and returns (or redirects to) the package bytes. The runtime verifies the hash again before executing.
7. Submitting outcome feedback (Agent/Runtime → Registry)
POST /v1/outcomes/oi:travel_genie.danang_relocation/ratings
{ "schema_version": "oip.rating-event.v1", "rating_event_id": "re_…",
"license_id": "lic_8c2…", "journey_id": "jr_…", "submitter_type": "runtime",
"rating_score": 5, "outcome_success": "closed", "verified_execution": true,
"anti_gaming": { "license_bound": true, "journey_bound": true, "rate_limited": true },
"timestamp": "2026-07-02T10:00:00Z" }
What affects the score in v1: only
verified_execution: true events that are
journey-bound to a real Execution Record. Unverified
user/agent star ratings are stored and displayed but carry zero score
weight until the journey threshold is met. This is the anti-gaming
model: there is nothing to game in the v1 score.
8. Emitting evidence (Runtime)
A runtime's job after execution is to seal append-only evidence. Three objects, illustrative shapes:
Execution Configuration (content-addressed; an evidence dimension, no reputation field):
{ "config_id": "cfg_sha256:1a2b…", "dimensions": {
"planner": "herman", "model": "gpt-6", "reasoning_model": "o5", "agent_framework": "hermes",
"runtime": "mysenz", "device": "iphone-21-pro", "platform": "apple-intelligence",
"persona": "luxury_wellness_concierge", "tools": ["maps","calendar","booking","browser","mcp"] } }Execution Record (sealed once; references identities, config, manifest, delegation edges):
{ "execution_record_id": "er_…", "principal_ref": "principal:brian",
"execution_partner_ref": "epi:herman", "config_ref": "cfg_sha256:1a2b…",
"manifest_ref": "mf_9f2a1c7b4e0d6a3c",
"delegation_edges": [
{ "role": "research", "delegate_ref": "epi:gene", "parent_ref": "epi:herman", "at": "…" },
{ "role": "concierge", "delegate_ref": "epi:travel_genie_sea", "parent_ref": "epi:herman", "at": "…" } ],
"outcome_evaluation_ref": "ev_…", "sealed_at": "2026-07-02T09:55:00Z" }Outcome Evaluation (the verdict + experience + evidence class — becomes evidence, not a review):
{ "outcome_evaluation_id": "ev_…", "verdict": "closed",
"execution_quality": "completed", "outcome_quality": "great",
"experience_quality": ["stress_reduced","time_saved","would_use_again"],
"evidence_class": "sensor+self_report", "confidence": 0.78 }Rules: never edit a sealed record; a later contradiction is a new record that flags the affected projection for review. Configurations are correlated against, never credited. Delegation edges form a DAG (a delegate may appear under multiple roles/records).
9. Complete end-to-end example
The full lifecycle for
oi:travel_genie.danang_relocation, from publish to a
verified outcome that moves trust.
Diagram — view Mermaid source
sequenceDiagram
participant Pub as Publisher (DeepSenz)
participant Reg as Registry (SkillSenz)
participant Ag as Agent (Herman, for Brian)
participant RT as Runtime (MySenz)
participant TS as TrustSenz
Pub->>Reg: POST /v1/outcomes (signed manifest + trust manifest)
Reg-->>Pub: 201 Created (links)
Note over Reg,TS: TrustSenz computes initial metric → 72 / Promising / warn
Ag->>Reg: GET /.well-known/oip.json
Ag->>Reg: GET /v1/outcomes?domain=relocation
Ag->>Reg: GET /v1/outcomes/{id}/trust
Note over Ag: sample_size_warning=true; acceptable for $19 low-stakes
Ag->>Reg: POST /v1/outcomes/{id}/license (one_time, pays via ACP)
Reg-->>Ag: license_token lt_…
Ag->>Reg: GET /v1/licenses/lt_…/verify (8-step order)
Ag->>Reg: GET /v1/outcomes/{id}/package (Bearer lt_…)
Reg-->>Ag: package bytes (hash re-verified)
Ag->>RT: install + execute
RT->>RT: seal Execution Configuration (cfg_…)
RT->>RT: seal Execution Record (er_…) + delegation edges
RT->>RT: seal Outcome Evaluation (ev_…, verdict=closed)
RT->>Reg: POST /ratings (verified_execution=true, journey-bound)
Reg->>TS: recompute metric over evidence (journey_count=2)
Note over TS: Wilson lb rises (2-of-2); confidence ↑; band may stay Promising → Validated path begins
TS-->>Reg: new metric + append-only trust_delta
What changed, and why it's honest: after the second
verified closed journey, journey_count = 2,
the Wilson lower bound rises from ≈0.21 toward ≈0.34,
confidence_score increases, and an
append-only trust_delta is recorded. The
score did not jump to 100 on two successes — it moved the amount the
evidence supports. A failed second journey would have moved it
down, and that is the system working. Reputation also accrued
to epi:herman (the accountable partner) and to the domain
partners on the delegation edges — never to gpt-6, which is
recorded only as a configuration covariate.
10. Conformance checklist
A minimal conformant implementation:
11. Common pitfalls
| Pitfall | Why it's wrong | Do instead |
|---|---|---|
Defaulting a missing field to 0 / no |
Destroys the trust gradient; skip ≠ no |
null + unknowns[] entry |
| Publisher sets its own score | Trust laundering | Registry/TrustSenz computes from evidence only |
| Counting a star rating like a verified outcome | Gameable; popularity ≠ evidence | Gate ratings; weight verified events only |
| Crediting the model with reputation | Covariate ≠ cause; evaporates on deprecation | Credit the identity; record config as a dimension |
| Editing a sealed Execution Record | The past is a fact | Append a new record; flag the projection for review |
| Storing the reputation graph as the source of truth | It can drift from evidence | Recompute it from append-only Attributions |
| Requiring a the private extension profile field for a core op | Breaks the extension boundary | Keep core operations extension-free |
This is a practical companion to the normative
OIP-Specification-v1.0.md. Field-level authority always
rests with the Specification; this guide shows the working path through
it.