Integration Authoring Guide
This guide explains how to create a new Universal Manifest integration lane. It is written for both human contributors and AI agents. Following this guide should produce a complete, valid integration document with zero additional context required.
When to Create an Integration Lane
Section titled “When to Create an Integration Lane”Create a new integration lane when:
- A new domain needs to use Universal Manifest (e.g., healthcare, education, automotive) and no existing lane covers its data model or consent requirements.
- A new use-case pattern emerges within an existing domain that requires distinct shards, pointers, or consent keys not covered by existing lanes.
- A new consent model is needed (e.g., a domain with unique privacy regulations like HIPAA, FERPA, or GDPR-specific requirements).
- A new platform or protocol wants to integrate with UM and needs guidance on how to map its concepts to manifest fields.
Do not create a new lane if an existing lane already covers the domain and use case. Instead, consider proposing amendments to the existing lane.
Prerequisites
Section titled “Prerequisites”Before starting, ensure you have access to:
- The integration lane template: TEMPLATE.md
- The v0.1 specification
- Example fixtures in the GitHub repository (for reference)
- The test harness:
packages/universal-manifest(for fixture validation)
Step-by-Step Process
Section titled “Step-by-Step Process”Step 1: Copy the Template
Section titled “Step 1: Copy the Template”cp integrations/TEMPLATE.md integrations/{your-lane-name}.mdUse kebab-case for the filename (e.g., healthcare-patient-consent.md, smart-home.md, education-credentials.md).
Step 2: Define the Domain and Use Cases
Section titled “Step 2: Define the Domain and Use Cases”Fill in the Overview section with:
- What systems, platforms, or standards this lane targets.
- Why this domain benefits from a portable manifest model.
- What problems UM solves in this domain.
Write 3-5 use cases as user stories in the format: “As a {role}, I want to {action} so that {benefit}.”
Step 3: Identify Natural Shards
Section titled “Step 3: Identify Natural Shards”Shards are named data compartments within the manifest. Ask:
- What distinct categories of data does this domain need to carry?
- What would a consumer need to extract and process independently?
Each shard should have:
- A descriptive
name(camelCase, e.g.,patientConsent,deviceIdentity). - A
@typeof"um:Shard"(additional domain types are optional). - An
entityobject with domain-relevant fields.
Naming convention: {domain}{DataCategory} in camelCase. Examples: patientConsent, academicCredential, deviceIdentity.
Step 4: Identify Natural Pointers
Section titled “Step 4: Identify Natural Pointers”Pointers are URL references to external systems or resources. Ask:
- What external systems should a manifest reference?
- What canonical data sources exist outside the manifest?
Each pointer should have:
- A
nameusing dot-notation:{domain}.{resourceName}(e.g.,health.record,edu.transcript). - A
urlpointing to the external resource.
Naming convention: {domain}.{resourceType} in dot-notation. Examples: health.insuranceProvider, edu.transcript, home.firmwareUpdate.
Step 5: Identify Natural Consents
Section titled “Step 5: Identify Natural Consents”Consents are default-deny permission toggles. Ask:
- What actions require explicit user permission in this domain?
- What data disclosures are sensitive?
- What regulatory requirements apply?
Each consent should have:
- A
nameusing dot-notation:{domain}.{permissionAction}(e.g.,health.shareRecords,edu.verifyDegree). - A
valueof"allowed"or"denied". - A default of
"denied"— consumers must treat missing consents as denied.
Naming convention: {domain}.{verb}{Object} in dot-notation. Examples: health.shareAllergies, edu.shareTranscript, home.allowRemoteAccess.
Step 6: Identify Natural Claims
Section titled “Step 6: Identify Natural Claims”Claims are role or permission assertions. Ask:
- What roles matter in this domain? (e.g., patient, practitioner, student, device-owner)
- What statuses or attestations need to be carried? (e.g., verified, enrolled, certified)
Each claim should have:
- A
nameusing dot-notation:{domain}.{claimType}(e.g.,health.role,edu.degreeStatus). - A
valuewith the assertion content. - An
issuerDID identifying who made the assertion.
Naming convention: {domain}.{claimCategory} in dot-notation. Examples: health.practitionerRole, edu.enrollmentStatus, home.deviceOwnership.
Step 7: Write Consumer and Issuer Behavior
Section titled “Step 7: Write Consumer and Issuer Behavior”Consumer behavior describes how a relying party should process manifests with this integration’s fields. Always include:
- Core UM validation (required fields, TTL check).
- Integration-specific field extraction and processing.
- Consent checks before acting on data.
- Unknown-field tolerance.
Issuer behavior describes how to construct manifests. Always include:
- Setting standard required fields with fresh values.
- Integration-specific shard, pointer, consent, and claim construction.
- Signature addition (optional in v0.1, expected in v0.2).
Step 8: Create an Example Fixture
Section titled “Step 8: Create an Example Fixture”Write a complete, valid v0.1 JSON-LD manifest that demonstrates the integration in action. Requirements:
- Must include all required fields:
@context,@id,@type,manifestVersion,subject,issuedAt,expiresAt,shards. @contextmust be"https://universalmanifest.net/ns/universal-manifest/v0.1/schema.jsonld".@idmust be aurn:uuid:with a valid UUID.@typemust be"um:Manifest".manifestVersionmust be"0.1".subjectmust be a DID or URI.issuedAtmust be a valid ISO 8601 timestamp.expiresAtmust be afterissuedAt.shardsmust be an array (may be empty, but should contain domain-relevant shards for a useful example).- Each shard must have
@type: "um:Shard".
Use realistic but fictional data. Do not use real people, organizations, or identifiers.
Step 9: Validate the Fixture
Section titled “Step 9: Validate the Fixture”Run the validation harness to confirm the fixture is structurally valid:
cd packages/universal-manifestnpm run testThe fixture must pass assertUniversalManifestV01. If it does not, fix the structure until it does.
Step 10: Submit for Review
Section titled “Step 10: Submit for Review”- Place the integration file in
integrations/{your-lane-name}.md. - Optionally create a site docs version in
site/src/content/docs/integrations/{your-lane-name}.mdwith Starlight frontmatter. - Submit for review. Current process: create the file and it will be reviewed by hand. In the future, this may involve a pull request workflow.
Naming Conventions Summary
Section titled “Naming Conventions Summary”| Element | Convention | Examples |
|---|---|---|
| File name | kebab-case | healthcare-patient-consent.md, smart-home.md |
| Shard name | camelCase, {domain}{DataCategory} | patientConsent, academicCredential |
| Pointer name | dot-notation, {domain}.{resourceType} | health.record, edu.transcript |
| Consent name | dot-notation, {domain}.{verbObject} | health.shareRecords, edu.verifyDegree |
| Claim name | dot-notation, {domain}.{claimCategory} | health.role, edu.degreeStatus |
Quality Checklist
Section titled “Quality Checklist”Before submitting, verify:
- Template complete: All template sections are filled in (no placeholder braces remain).
- Fixture validates: The example fixture passes
assertUniversalManifestV01. - Consent defaults to deny: All consent keys specify a default of “denied” in the table and the fixture demonstrates explicit “allowed”/“denied” values.
- No normative language: The document does not use “MUST”, “SHALL”, “REQUIRED” (RFC 2119 keywords) except when referring to core UM spec requirements. Integration guidance uses “should”, “recommended”, or “suggested”.
- Boundary declared: The Normative Boundary section is present and unmodified.
- Use cases concrete: Each use case is a specific, actionable user story.
- Shards well-scoped: Each shard represents a distinct data compartment, not a dump of all fields.
- Pointers reference external systems: Pointers link to resources outside the manifest, not to shard contents.
- Claims are attestations: Claims represent verifiable assertions, not data fields (data belongs in shard entities).
- Consumer behavior is defensive: Consumer steps include TTL checks, consent checks, and unknown-field tolerance.
- Issuer behavior is constructive: Issuer steps produce a valid manifest from scratch.
Common Mistakes
Section titled “Common Mistakes”- Putting data in claims instead of shards. Claims are assertions (“this person has role X”). Data belongs in shard entities (“this person’s name is Y”).
- Forgetting the consent default. Every consent key must default to “denied”. A missing consent means denied.
- Using normative language. Integration lanes are non-normative guidance. Do not write “The consumer MUST do X” — write “The consumer should do X” or “Recommended: do X”.
- Invalid fixture structure. Missing
@context, wrong@type,issuedAtafterexpiresAt, or shards not in an array are common fixture errors. - Namespace collisions. Use domain-specific prefixes for all pointer, consent, and claim names to avoid collisions with other lanes.
- Integration Catalog — Browse existing integration lanes.
- TEMPLATE.md — The fill-in-the-blank template.
- Specification (v0.1) — The core specification.
- Conformance (v0.1) — Conformance requirements and fixtures.