OpenTopology Core Specification
Short name: otop-core
Version: 0.2
Status: Draft
Audience: Tool authors, compiler implementers, repository indexers, AI-agent platform builders, governance tooling vendors
Normative Language
The terms MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are normative when they appear in uppercase, as described by RFC 2119 and RFC 8174. Lowercase uses of must, should, and may are also normative when they appear in conformance requirements or field definitions.
1. Introduction
OpenTopology, abbreviated as otop, is an open graph standard for representing relationships between software intent, constraints, policies, implementation artifacts, and verification evidence.
The purpose of otop is to provide a portable topology layer that allows independent tools to exchange structured knowledge about what software is intended to do, where that intent is implemented, what governs it, and what evidence supports it.
OpenTopology defines an application and intent topology layer. It is not a network topology, service mesh topology, VPC topology, deployment map, or infrastructure inventory standard, although those systems may be represented as Artifacts or referenced by extension profiles.
An otop graph allows tools to answer questions such as:
- What Intent did this Constraint come from?
- Which Policies govern this Constraint?
- Which Artifacts implement this Constraint?
- Which Evidence verifies this Constraint?
- Which Constraints lack implementation?
- Which Evidence has become stale?
- Which Constraints conflict?
1.1 Breaking Changes From 0.1
otop-core 0.2 makes chronology first-class and intentionally breaks compatibility with 0.1 manifests that omit chronology metadata.
- Object
metadatais now a core object field. - Chronology metadata is mandatory on objects and Evidence observations; relationship creation chronology is recommended and may fall back to graph or transport chronology.
- Evidence
produced_atis removed and replaced bymetadata.observed_at. - 0.1 manifests must be migrated before claiming 0.2 conformance.
2. Goals
The goals of otop-core are to define:
- A shared graph model.
- Core object kinds.
- Required object fields.
- Core relationship types.
- Stable identity rules.
- Artifact locator semantics.
- Evidence semantics.
- Extension rules.
- Basic conformance requirements.
3. Non-Goals
otop-core does not define:
- A specific database.
- A specific compiler.
- A specific parser.
- A specific AI-agent runtime.
- A specific transport protocol.
- A specific policy engine.
- A specific test framework.
- A specific requirements authoring workflow.
- A guarantee that all semantic conflicts can be detected automatically.
otop may be used by AI-agent systems, but AI-agent behavior is not part of otop-core.
4. Terminology
An otop graph is a directed labeled property graph.
A graph consists of:
- Objects, represented as typed graph nodes.
- Relationships, represented as typed graph edges.
- Properties, represented as structured metadata on objects and relationships.
The five core object kinds are:
- Intent
- Constraint
- Policy
- Artifact
- Evidence
The term "node" may be used when describing graph mechanics, but public object kinds should use the domain terms above.
5. Core Object Kinds
Every object must include id, kind, title, and metadata. Implementations may add optional fields and namespaced extension fields as described in the extension model.
Object metadata MUST include created_at. metadata.created_at records when the topology object record was created. It MUST be an RFC 3339 timestamp normalized to UTC and ending in Z.
Object metadata SHOULD include actor when the authoring human, automation, or tool identity is known. metadata.actor may be a string identifier or a structured object.
Tools generating manifests automatically SHOULD use deterministic timestamps for metadata.created_at where possible, such as the Git commit author timestamp, Git commit committer timestamp, release timestamp, source document timestamp, or another stable generation timestamp. Automated tools SHOULD NOT refresh metadata.created_at with the system wall-clock time when the represented graph record has not semantically changed.
Evidence object metadata MUST also include observed_at, as defined in Section 5.5.
Objects may include lifecycle. When present, lifecycle should use one of the core values defined in Section 5.6 or a namespaced extension value.
5.1 Intent
An Intent represents human-authored or tool-authored desired software behavior, system shape, product outcome, architecture decision, or requirement source.
Examples include product requirements, user stories, specification sections, architecture decisions, acceptance criteria, threat-model items, and customer outcomes.
Required fields:
id: intent.auth.session-validation
kind: intent
title: User session validation
metadata:
created_at: 2026-06-20T12:00:00Z
actor: user.alice
Recommended fields:
intent_type: requirement
source:
kind: markdown
path: specs/auth/session-validation.md
lifecycle: active
owner: platform-security
5.2 Constraint
A Constraint represents a specific obligation, invariant, rule, or acceptance criterion that can be checked, reviewed, implemented, or verified.
Examples include:
session.token.entropy >= 256api.timeout <= 200msuser.password.length >= 12all customer data deletion requests must be completed within 30 days
Required fields:
id: constraint.auth.session-token-entropy
kind: constraint
title: Session tokens must provide sufficient entropy
metadata:
created_at: 2026-06-20T12:00:00Z
actor: user.alice
Recommended fields:
modality: MUST
constraint_type: security
checkability: dynamic
assertion: session.token.entropy >= 256
expression_language: cel
severity: high
lifecycle: active
5.3 Policy
A Policy represents a governing source, rule set, standard, control, architectural rule, compliance requirement, or organizational guardrail.
A Policy usually governs one or more Constraints.
Examples include ISO 27001 cryptographic controls, GDPR data deletion policy, internal secure coding standards, approved platform architecture, engineering golden paths, and data retention policy.
Required fields:
id: policy.security.iso27001.crypto-controls
kind: policy
title: Cryptographic controls
metadata:
created_at: 2026-06-20T12:00:00Z
actor: user.alice
Recommended fields:
policy_type: security_control
authority: external
reference: ISO27001-A.10
lifecycle: active
5.4 Artifact
An Artifact represents a concrete implementation or project artifact.
Artifacts may be source code, tests, configuration, infrastructure, generated files, runtime endpoints, or deployment resources.
Examples include source files, functions, classes, API routes, test cases, configuration keys, Terraform resources, Kubernetes manifests, database migrations, and container images.
Required fields:
id: artifact.auth.validate-session
kind: artifact
title: validateSession
artifact_type: source_symbol
metadata:
created_at: 2026-06-20T12:00:00Z
actor: example-indexer
Recommended fields:
language: typescript
locator:
repository: github.com/example/app
path: src/auth/session.ts
symbol: validateSession
range:
start_line: 42
end_line: 87
digest: sha256:8f3c3a92b3
AST data may be used as part of an Artifact locator, but an Artifact is not itself required to be an AST node.
5.5 Evidence
Evidence represents proof, observation, result, attestation, waiver, or review record related to a Constraint, Policy, or Artifact.
Examples include unit test results, integration test results, static-analysis results, policy scans, runtime observations, manual reviews, security approvals, waivers, and external audit records.
Required fields:
id: evidence.auth.session-token-entropy.test.2026-06-20
kind: evidence
title: Session token entropy test result
evidence_type: unit_test_result
result: pass
metadata:
created_at: 2026-06-20T12:01:00Z
observed_at: 2026-06-20T12:00:00Z
actor: ci.github-actions
Recommended fields:
tool:
name: vitest
version: 2.1.0
confidence: deterministic
digest: sha256:44ac91
subjects:
- id: constraint.auth.session-token-entropy
kind: constraint
digest: sha256:7c91f0
version: 3
- id: artifact.auth.validate-session
kind: artifact
digest: sha256:8f3c3a92b3
commit: 8f3c3a92b3
provenance:
actor:
id: user.alice
type: human
producer:
name: vitest
version: 2.1.0
source:
kind: ci
run_id: 123456
signature:
algorithm: ed25519
key_id: user.alice.ssh
payload_digest: sha256:44ac91
signature: base64:MEUCIQD...
Valid evidence results are:
pass
fail
unknown
waived
not_applicable
subjects records the object or relationship states the Evidence is about. Each subject should include the target object or relationship id and may include kind, relationship_type, digest, commit, and version.
metadata.observed_at records the authoritative time the Evidence observation, test, scan, review, attestation, waiver, or other verification event occurred. metadata.created_at records when the Evidence topology object was created and may differ from metadata.observed_at.
produced_at is not part of otop-core 0.2 and MUST NOT be used as an alias for metadata.observed_at.
provenance records who or what produced the Evidence. It may describe a human actor, an automated producer, a source system, or all three.
signature records an optional cryptographic binding over the Evidence payload. otop-core defines the field shape but does not require a specific signing ecosystem, algorithm, key management system, or attestation framework.
When signature is present, payload_digest is required. otop-core 0.2 does not define canonical serialization for signed payloads. Profiles may define canonicalization, signing, and verification requirements.
Profiles that define signed Evidence should use an existing deterministic serialization where possible. Recommended baselines include RFC 8785 JSON Canonicalization Scheme (JCS) for JSON payloads, or an explicitly specified deterministic YAML serialization. Profiles should avoid signing presentation details that are likely to change during semantically equivalent parse and re-emit operations.
5.6 Lifecycle
Objects may include lifecycle to describe their lifecycle state.
Core lifecycle values are:
draft
active
deprecated
superseded
archived
Implementations should treat unknown unnamespaced lifecycle values as invalid. Custom lifecycle values should be namespaced through the extension model.
6. Core Relationship Types
Relationships connect objects in an otop graph.
Each relationship must include from, to, and type.
Relationships may also include:
id: a stable relationship identifier.metadata: structured relationship context.extensions: namespaced extension data.
Relationship metadata SHOULD include created_at when the relationship record has meaningful relationship-local creation chronology. When present, metadata.created_at records when the relationship record was created. It MUST be an RFC 3339 timestamp normalized to UTC and ending in Z.
If a relationship omits metadata.created_at, tools that need a relationship creation timestamp MUST use this fallback order: relationship metadata.created_at, then top-level graph.metadata.created_at, then the current commit, transport, or ingestion timestamp when such a timestamp is available. Tools MUST NOT treat an omitted relationship metadata.created_at as malformed solely because the fallback is used.
Relationship metadata may include fields such as confidence, actor, created_by, inferred_by, method, and note. Metadata is suitable for automation hints and review context. Authoritative proof, waivers, attestations, and conflict resolutions should be represented as Evidence.
Example:
id: rel.constraint.auth.session-token-entropy.derived-from.intent.auth.session-validation
from: constraint.auth.session-token-entropy
to: intent.auth.session-validation
type: derived_from
metadata:
confidence: high
created_at: 2026-06-20T12:00:00Z
actor: user.alice
method: human_review
6.1 derived_from
Connects a Constraint to the Intent, Policy, or source from which it was derived.
Constraint --derived_from--> Intent
6.2 governed_by
Connects an Intent, Constraint, or Artifact to a Policy.
Constraint --governed_by--> Policy
6.3 implemented_by
Connects an Intent or Constraint to an Artifact that implements it.
Constraint --implemented_by--> Artifact
implemented_by.metadata.implemented_at SHOULD record when the implementation relationship became true. When present, it MUST be an RFC 3339 timestamp normalized to UTC and ending in Z.
6.4 verified_by
Connects a Constraint, Policy, or Artifact to Evidence.
Constraint --verified_by--> Evidence
The verified_by relationship identifies that Evidence supports the source object and provides an operational shortcut for graph traversal. Cryptographic state binding and deterministic staleness should be recorded in the Evidence subjects field. When verified_by and Evidence subjects disagree, subjects is the source of truth for cryptographic binding.
verified_by.metadata.verified_at SHOULD record when the verification event occurred. It normally matches the target Evidence metadata.observed_at. When present, it MUST be an RFC 3339 timestamp normalized to UTC and ending in Z.
6.5 depends_on
Connects one object to another object required for interpretation, operation, or correctness.
Constraint --depends_on--> Constraint
Tools that traverse depends_on relationships must implement cycle detection. A conforming tool MUST yield a fatal validation error and abort graph ingestion or processing if a cycle is detected within depends_on relationships.
6.6 conflicts_with
Declares that two objects are incompatible.
Constraint --conflicts_with--> Constraint
Current unresolved conflicts should remain represented as conflicts_with relationships. Accepted risk, override, mute, and resolution decisions should be represented as Evidence that targets the relationship id, preserving historical context without relying on edge deletion.
6.7 supersedes
Declares that one object replaces another.
Constraint --supersedes--> Constraint
Tools that traverse supersedes relationships must implement cycle detection. supersedes lineage must be acyclic. A conforming tool MUST yield a fatal validation error and abort graph ingestion or processing if a cycle is detected within supersedes lineage.
6.8 waived_by
Connects a Constraint or Policy to Evidence that records an approved exception.
Constraint --waived_by--> Evidence
waived_by.metadata.waived_at SHOULD record when the waiver decision occurred. When present, it MUST be an RFC 3339 timestamp normalized to UTC and ending in Z.
7. Canonical Topology
The recommended canonical topology is:
Constraint --derived_from--> Intent
Constraint --governed_by--> Policy
Constraint --implemented_by--> Artifact
Constraint --verified_by--> Evidence
This makes Constraint the central query point.
Given a Constraint, a tool should be able to answer:
- Where did this Constraint come from?
- What governs it?
- Where is it implemented?
- How is it verified?
8. Manifest Format
An otop manifest may be represented as YAML or JSON.
A manifest contains:
- otop version.
- Graph metadata.
- Objects.
- Relationships.
- Optional extension data.
- Optional signatures.
graph.metadata.created_at SHOULD identify the creation timestamp for the manifest graph or graph partition. When present, it MUST be an RFC 3339 timestamp normalized to UTC and ending in Z. Tools SHOULD use a deterministic value for generated manifests, such as a Git commit timestamp or fixed release timestamp, so regenerated manifests remain stable for diffing and review.
8.1 Schema Binding
Manifests should declare their schema when the file format supports it.
JSON manifests should use the standard $schema key:
{
"$schema": "https://opentopology.dev/schemas/otop-core-v0.2.schema.json",
"otop_version": 0.2,
"graph": {
"metadata": {
"created_at": "2026-06-20T12:00:00Z"
}
}
}
YAML manifests should use an IDE-compatible schema directive comment:
# yaml-language-server: $schema=https://opentopology.dev/schemas/otop-core-v0.2.schema.json
otop_version: 0.2
graph:
metadata:
created_at: 2026-06-20T12:00:00Z
Schema binding allows editors, language servers, and general-purpose validators to provide validation without requiring a custom tool.
Versioned schema URLs are immutable once published. otop_version: 0.2 binds a manifest to the v0.2 schema family. Compatible corrections may be published with explicit patch URLs, such as otop-core-v0.2.1.schema.json. Moving aliases may exist for convenience, but examples should use immutable versioned URLs.
Minimal valid manifest:
# yaml-language-server: $schema=https://opentopology.dev/schemas/otop-core-v0.2.schema.json
otop_version: 0.2
graph:
id: graph.example.minimal
title: Minimal Example Topology
metadata:
created_at: 2026-06-20T12:00:00Z
objects:
- id: intent.example.minimal
kind: intent
title: Minimal intent
metadata:
created_at: 2026-06-20T12:00:00Z
relationships: []
Example:
# yaml-language-server: $schema=https://opentopology.dev/schemas/otop-core-v0.2.schema.json
otop_version: 0.2
graph:
id: graph.example.auth-service
title: Example Auth Service Topology
repository: github.com/example/auth-service
commit: 8f3c3a92b3
metadata:
created_at: 2026-06-20T12:00:00Z
objects:
- id: intent.auth.session-validation
kind: intent
intent_type: requirement
title: User session validation
lifecycle: active
metadata:
created_at: 2026-06-20T12:00:00Z
actor: user.alice
source:
kind: markdown
path: specs/auth/session-validation.md
- id: constraint.auth.session-token-entropy
kind: constraint
constraint_type: security
title: Session tokens must provide sufficient entropy
lifecycle: active
metadata:
created_at: 2026-06-20T12:00:00Z
actor: user.alice
modality: MUST
checkability: dynamic
assertion: session.token.entropy >= 256
expression_language: cel
- id: policy.security.iso27001.crypto-controls
kind: policy
policy_type: security_control
title: Cryptographic controls
lifecycle: active
metadata:
created_at: 2026-06-20T12:00:00Z
actor: user.alice
authority: external
reference: ISO27001-A.10
- id: artifact.auth.validate-session
kind: artifact
artifact_type: source_symbol
title: validateSession
lifecycle: active
metadata:
created_at: 2026-06-20T12:00:00Z
actor: example-indexer
language: typescript
locator:
path: src/auth/session.ts
symbol: validateSession
range:
start_line: 42
end_line: 87
digest: sha256:8f3c3a92b3
- id: evidence.auth.session-token-entropy.test.2026-06-20
kind: evidence
evidence_type: unit_test_result
title: Session token entropy test
result: pass
metadata:
created_at: 2026-06-20T12:01:00Z
observed_at: 2026-06-20T12:00:00Z
actor: ci.github-actions
tool:
name: vitest
version: 2.1.0
confidence: deterministic
digest: sha256:44ac91
subjects:
- id: constraint.auth.session-token-entropy
kind: constraint
digest: sha256:7c91f0
version: 3
- id: artifact.auth.validate-session
kind: artifact
digest: sha256:8f3c3a92b3
commit: 8f3c3a92b3
- id: rel.constraint.auth.session-token-entropy.implemented-by.artifact.auth.validate-session
relationship_type: implemented_by
digest: sha256:90b1e2
provenance:
actor:
id: ci.github-actions
type: automation
producer:
name: vitest
version: 2.1.0
source:
kind: ci
run_id: 123456
signature:
algorithm: ed25519
key_id: ci.github-actions.2026-06
payload_digest: sha256:44ac91
signature: base64:MEUCIQD...
relationships:
- id: rel.constraint.auth.session-token-entropy.derived-from.intent.auth.session-validation
from: constraint.auth.session-token-entropy
to: intent.auth.session-validation
type: derived_from
metadata:
confidence: high
created_at: 2026-06-20T12:00:00Z
actor: user.alice
method: human_review
- id: rel.constraint.auth.session-token-entropy.governed-by.policy.security.iso27001.crypto-controls
from: constraint.auth.session-token-entropy
to: policy.security.iso27001.crypto-controls
type: governed_by
metadata:
actor: user.alice
- id: rel.constraint.auth.session-token-entropy.implemented-by.artifact.auth.validate-session
from: constraint.auth.session-token-entropy
to: artifact.auth.validate-session
type: implemented_by
metadata:
implemented_at: 2026-06-20T12:00:00Z
confidence: medium
inferred_by:
tool: example-indexer
version: 0.4.0
method: static_analysis
note: Symbol reference inferred from call graph.
extensions:
com.example.indexer:
rule_id: callgraph.symbol-match
- id: rel.constraint.auth.session-token-entropy.verified-by.evidence.auth.session-token-entropy.test.2026-06-20
from: constraint.auth.session-token-entropy
to: evidence.auth.session-token-entropy.test.2026-06-20
type: verified_by
metadata:
verified_at: 2026-06-20T12:00:00Z
actor: ci.github-actions
9. Identity Rules
Every object in an otop graph must have a stable id.
Object IDs should be:
- Unique within a graph.
- Stable across graph updates.
- Human-readable where possible.
- Namespaced to avoid collisions.
- Independent of line numbers.
- Suitable for diffing and review.
Relationship IDs are optional. When present, a relationship ID must be unique within the graph.
Relationship IDs should be:
- Stable while the relationship's
from,to, andtypesemantics remain stable. - Human-readable where possible.
- Namespaced to avoid collisions.
- Suitable for Evidence
subjects. - Suitable for diffing and review.
Recommended ID style:
intent.auth.session-validation
constraint.auth.session-token-entropy
policy.security.iso27001.crypto-controls
artifact.auth.validate-session
evidence.auth.session-token-entropy.test.2026-06-20
rel.constraint.auth.session-token-entropy.implemented-by.artifact.auth.validate-session
10. Artifact Locators
Artifact locators describe where an Artifact can be found.
A locator may include:
- repository
- commit
- path
- symbol
- range
- digest
- language
- parser metadata
- runtime endpoint
- package identifier
- image reference
If repository is defined or can be inferred from graph metadata, path values must be interpreted as relative to the root of that repository. Tools should not interpret locator paths relative to the manifest file location or an arbitrary working directory unless an extension profile explicitly defines that behavior.
Line ranges are hints, not stable identity. AST data may be included as optional locator metadata.
Example:
locator:
path: src/auth/session.ts
symbol: validateSession
range:
start_line: 42
end_line: 87
ast:
parser: tree-sitter-typescript
node_type: function_declaration
digest: sha256:8f3c3a92b3
11. Evidence Semantics
Verification should be represented as Evidence, not only as mutable status.
A Constraint may be considered verified when sufficient valid Evidence objects are connected through verified_by relationships.
Evidence chronology is recorded in metadata.observed_at. Tools should use metadata.observed_at, not record IDs, file ordering, compilation order, or metadata.created_at, to determine when the underlying observation occurred.
Evidence may become stale if:
- The related Constraint changes.
- The related Artifact changes.
- The related Policy changes.
- The verification method changes.
- The Evidence expires.
- A dependency changes.
For deterministic staleness computation, Evidence should record subjects snapshots for the object and relationship states it verifies. A tool should compare each subject snapshot against the current graph, object, relationship, Artifact locator, commit, version, or digest state available to that tool. If a subject no longer matches the current state, the Evidence should be treated as stale for that subject.
Tools may compute verification summaries, but summaries should be derived from Evidence objects and their subjects. The underlying Evidence object should remain immutable historical data.
11.1 Graph Partitions And External References
A graph partition is a bounded set of objects and relationships that a tool treats as locally resolvable during validation. A single manifest is a graph partition unless an extension profile or federation transport defines a broader partition boundary.
References to objects or relationships inside the same graph partition MUST resolve. A missing local relationship endpoint or local Evidence subject reference MUST be a fatal validation error.
Evidence subjects MAY reference objects or relationships outside the current graph partition when the subject explicitly identifies an external reference, graph, or partition. Tools that support federated graphs MAY report such subjects as unresolved external references instead of fatal validation errors. Tools SHOULD distinguish unresolved external references from missing local references in diagnostics.
12. Conflict Semantics
otop supports explicit representation of conflicts.
Conflict types may include:
syntactic
structural
logical
policy
semantic
Tools must distinguish deterministic conflicts from inferred conflicts.
A tool must not claim deterministic semantic conflict detection unless the conflict is backed by a formal rule, declared contradiction, or approved human review.
Conflict resolution is historical graph data. Tools should not rely on deleting a conflicts_with relationship as the only representation of resolution. A conflict may be accepted, muted, overridden, or resolved by creating Evidence whose subjects include the conflicts_with relationship id. That Evidence may be connected with waived_by when it records an accepted exception, or with verified_by when it records a verified resolution.
13. Extension Model
Implementations may define custom fields, object subtypes, relationship types, and profiles.
Extensions must:
- Preserve core semantics.
- Avoid redefining core object kinds.
- Use namespaced identifiers.
- Be safely ignored by tools that do not understand them.
- Preserve unknown fields where possible.
Example:
extensions:
com.example.risk:
risk_score: 8.7
threat_model: STRIDE
14. Conformance
A tool conforms to otop-core if it can:
- Parse a valid otop manifest.
- Parse schema-bound JSON and YAML manifests.
- Validate required object fields.
- Validate object
metadata.created_aton every object. - Validate Evidence
metadata.observed_at. - Validate required relationship fields.
- Validate relationship
metadata.created_atwhen present. - Apply the relationship chronology fallback rule when relationship
metadata.created_atis omitted. - Validate relationship event timestamps when present, including
implemented_at,verified_at, andwaived_at. - Reject missing or malformed required object and Evidence chronology metadata in 0.2 graphs.
- Reject chronology timestamps that are not RFC 3339 UTC strings ending in
Z. - Resolve object IDs.
- Resolve relationship IDs when present.
- Validate core lifecycle values when
lifecycleis present. - Preserve unknown extension fields where possible.
- Preserve unknown relationship extension fields where possible.
- Export a valid otop graph.
- Reject invalid core object kinds.
- Reject relationships that reference missing objects.
- Reject Evidence subjects that reference missing local objects or missing local relationships in the same graph partition.
- Report unresolved external Evidence subject references separately when federation or partition metadata marks them as external.
- Emit a fatal validation error and abort graph ingestion or processing when a cycle is detected in
depends_onorsupersedes. - Respect immutable versioned schema URLs when it uses remote schemas for validation.
A tool that claims support for signed Evidence must also parse the standard provenance and signature fields, require payload_digest when signature is present, and report whether the signature is valid, invalid, unverifiable, or absent. If the tool does not implement a profile-defined canonicalization rule for the signed payload, it should report the signature as unverifiable rather than valid. Profiles that define canonicalization should prefer established deterministic serialization rules such as RFC 8785 JCS for JSON.
Additional profiles may define stronger requirements.
Examples include:
otop-traceotop-verifyotop-governanceotop-deltaotop-agent
15. Security Considerations
otop graphs may influence software generation, verification, compliance workflows, and agent behavior.
Implementations should consider:
- Forged Evidence.
- Stale graph replay.
- Unauthorized Policy changes.
- Malicious Constraint weakening.
- Prompt injection through text fields.
- Context poisoning.
- Waiver abuse.
- Signature confusion.
- Tool impersonation.
Implementations should support:
- Graph digests.
- Evidence digests.
- Actor identity.
- Signed Evidence.
- Signed graph states.
- Audit logs.
- Authorization controls for waivers and verification status.
16. Relationship to Implementations
otop-core is implementation-neutral.
A tool may implement otop using:
- A local file.
- A database.
- A graph engine.
- A CLI.
- A CI plugin.
- An IDE extension.
- An MCP server.
- A hosted API.
No implementation is required by otop-core.
17. References
17.1 Normative References
- RFC 2119: Key words for use in RFCs to indicate requirement levels.
- RFC 8174: Ambiguity clarification for uppercase and lowercase requirement keywords.
- RFC 3986: Uniform Resource Identifier (URI) syntax for schema URLs and locator references.
- RFC 3339: Date and time format used by chronology fields such as object
metadata.created_at, Evidencemetadata.observed_at, graphmetadata.created_at, and relationship metadata event keysimplemented_at,verified_at, andwaived_at. - RFC 4648: Base64 encoding used by signature examples.
17.2 Informative References
- RFC 8785: JSON Canonicalization Scheme (JCS), recommended for profiles that define signed JSON payloads.
- RFC 8032: Ed25519 and related Edwards-curve signature algorithms, referenced by signature examples.
- JSON Schema: External schema-validation vocabulary for otop JSON and YAML-compatible schema artifacts. The schema artifact defines the specific JSON Schema draft it uses.
18. Core Registries
| Registry | Values |
|---|---|
| Object kinds | intent, constraint, policy, artifact, evidence |
| Relationship types | derived_from, governed_by, implemented_by, verified_by, depends_on, conflicts_with, supersedes, waived_by |
| Evidence results | pass, fail, unknown, waived, not_applicable |
| Lifecycle values | draft, active, deprecated, superseded, archived |
| Chronology metadata keys | object metadata.created_at, Evidence metadata.observed_at, graph metadata.created_at, relationship metadata.created_at, relationship metadata.implemented_at, relationship metadata.verified_at, relationship metadata.waived_at |
| Conflict types | syntactic, structural, logical, policy, semantic |
19. Summary
OpenTopology defines a portable software topology graph.
Its five core object kinds are:
Intent
Constraint
Policy
Artifact
Evidence
Its canonical relationship pattern is:
Constraint --derived_from--> Intent
Constraint --governed_by--> Policy
Constraint --implemented_by--> Artifact
Constraint --verified_by--> Evidence
This allows independent tools to connect software intent, governing policy, implementation artifacts, and verification evidence in a common format.