Skip to content

Repository files navigation

ISM

Interoperable State of Mind — a portable format for carrying stance between AI systems, plus a deterministic procedure for what happens when two of them meet.

The problem

The current protocol stack moves capability. MCP and comparable interfaces let a model reach tools, files, databases, and services, and that is solved well enough.

Nothing in that stack moves stance — the assumptions, values, and definitions a system is expected to reason from. Today it lives in a system prompt, in fine-tuning weights, or in a policy PDF no runtime ever reads, and so two agents can share every tool, agree on every stated rule, and still mean different things by "ownership" or "consent" with nothing in the wire format surfacing the disagreement.

What a Frame is

A Frame is a signed, versioned JSON document declaring a stance. It is the atomic unit of ISM. It carries axioms (what is held, and how firmly), priorities (weights used to break ties), and a vocabulary block (the terms the Frame redefines, and what reading it is rejecting).

{
  "ism_version": "0.1",
  "id": "ism:capism/attribution/1",
  "name": "CAPISM Attribution Frame",
  "version": "1.0.0",
  "authority": { "name": "CAPISM", "uri": "https://mrcap1.com" },
  "priorities": [
    { "id": "lineage", "label": "Traceable lineage", "weight": 0.6 },
    { "id": "reach", "label": "Distribution reach", "weight": 0.4 }
  ],
  "axioms": [
    {
      "id": "credit_survives_derivation",
      "statement": "Attribution to the originating artist is preserved in every derivative output.",
      "strength": "binding",
      "serves": "lineage",
      "terms": ["derivative"]
    }
  ],
  "vocabulary": [
    {
      "term": "derivative",
      "definition": "Any output whose creation depended on the source work, including outputs produced by a model trained on it.",
      "contrasts_with": "Derivative as limited to works that are recognizably similar to the source."
    }
  ]
}

The vocabulary block is where most real conflicts live. Two systems rarely disagree about a stated value; they disagree about what a word in it means.

ISM rides on MCP rather than replacing it. It defines no transport — it is a payload and a resolution algorithm, and will move over anything that can carry a JSON document.

The surface rule

A Bridge takes two or more Frames and produces a Resolution. Where the Frames are compatible, it merges them. Where one axiom clearly outweighs another, it ranks them and records what yielded and why.

Where they genuinely conflict, it does neither. It returns both positions, intact and attributed, and marks the Resolution unresolved. A Consumer receiving a blocking Resolution must not proceed as though a stance had been established; it should escalate to a human, or halt.

This is deliberate and it is the point. Every other system in this space, when values collide, quietly picks one and hides the seam. Silently resolving a conflict produces a system that looks aligned and is not, and the failure surfaces later as an output someone has to explain. ISM would rather stop.

The same commitment governs ignorance, not just disagreement: if two axioms depend on a shared vocabulary term and neither Frame declares how they relate, the Bridge surfaces the pair rather than assuming it is fine.

Bridging two Frames

examples/ holds a worked CAPISM stance and a distributor's stance that declares a conflict against it. capism-attribution.json extends capism-the-art-of-ism.json, and the Bridge does not fetch, so the ancestor is supplied too.

import { readFileSync } from 'node:fs';
import { bridge } from './src/index.js';

const load = (name) => JSON.parse(readFileSync(`examples/${name}.json`, 'utf8'));

const resolution = bridge([
  load('capism-the-art-of-ism'),
  load('capism-attribution'),
  load('syndicate-distribution'),
]);

syndicate-distribution.json declares the collision in its own document rather than leaving a classifier to guess at it:

{
  "id": "reach_over_credit",
  "statement": "A distribution channel is used whenever it increases audience, including channels that discard attribution metadata.",
  "strength": "binding",
  "conflicts_with": [
    { "frame_id": "ism:capism/attribution/1", "axiom_id": "credit_survives_derivation" }
  ]
}

Both sides are binding, so neither can be outranked and the Resolution blocks:

resolution.blocking                        // true
resolution.resolved_composite.axioms.length // 9
resolution.yielded                         // []
resolution.surfaced                        // one entry:
{
  "kind": "axiom_conflict",
  "classification": "contradictory",
  "both_binding": true,
  "sides": [
    { "frame_id": "ism:capism/attribution/1", "axiom_id": "credit_survives_derivation" },
    { "frame_id": "ism:syndicate/distribution/1", "axiom_id": "reach_over_credit" }
  ],
  "reason": "both sides are binding; a binding axiom is never outranked"
}

Note what did not happen. Neither axiom was dropped: all nine assertions are in the Composite, each under its own asserted_by, including both sides of the conflict. The Composite records what was asserted; surfaced[] records what was not settled. A Consumer reads blocking and stops — it does not discover the disagreement by noticing an axiom is missing.

The conformance corpus

corpus/ is a set of JSON test cases for the Bridge, and it is meant to be run by implementations other than this one. Each file is one case:

{
  "name": "both binding: surfaces and blocks",
  "note": "Why this case exists and what rule it pins.",
  "frames": [ ... ISM Frames, all of them valid ... ],
  "expected": {
    "blocking": true,
    "composite_axioms": [{ "frame_id": "...", "axiom_id": "..." }],
    "composite_vocabulary": [],
    "yielded": [],
    "surfaced": [{ "kind": "axiom_conflict", "classification": "contradictory", "both_binding": true, "sides": [...] }],
    "dangling": []
  }
}

A case that must be rejected outright uses "expected": { "throws": "..." } instead.

expected asserts protocol-observable outcomes only — never a Resolution id or hash, which v0.1 does not specify and which implementations are free to derive differently. Everything it does assert is fixed by Section 4: which axioms reach the Composite and under whose name, which yielded and to what, what surfaced and why, and whether the Resolution blocks.

The 15 cases cover both binding paths, ranking above and below tie_margin, undetermined classification by term overlap, dangling conflicts_with targets, vocabulary collision and merge, extends shadowing, shared ancestry, lineage cycles, and an unresolvable parent. To check a second implementation, run its Bridge over each frames array and compare against expected. If you find a case where two readings of Section 4 disagree, that is a spec bug worth filing rather than an implementation detail.

Status

Two version numbers, and they move independently: git tags version this implementation, ism_version versions the wire format and is currently 0.1. So the v0.2.0 tag ships ism_version 0.1, and a deprecation scheduled for ism_version 0.2 is not triggered by a repository release numbered 0.2.x.

ism_version 0.1 is a draft and nothing in it is stable. Field names, wire format, and resolution semantics may change without notice before 1.0. Pin ism_version and expect breaking changes.

Working today:

  • Validator — JSON Schema plus the semantic rules a schema cannot express (priority references, id uniqueness, vocabulary collisions, lineage chronology, id/version agreement). ism validate <file> exits 0 or 1 and prints the JSON path of every failure.
  • Frame Server — ISM conformance Level 1. Serves Frames from a directory as MCP resources over stdio. Every document is validated before publication; an invalid Frame is excluded and logged rather than served.
  • Bridge — ISM conformance Level 2. All five steps of Section 4: extends expansion with cycle rejection, vocabulary reconciliation, classification from declared structure, resolution in spec order, and a Composite carrying per-axiom provenance. Deterministic byte for byte — no clock, no network, no randomness, and no natural language processing anywhere in it.
  • Conformance corpus — 15 JSON cases under corpus/, described above.

Not built:

  • Signatures. Section 3.6 specifies them and the schema carries the field, but nothing here signs or verifies anything. Every Frame is treated as unverified, including one that arrives with a signature block, and there is no RFC 8785 canonicalization. Section 7 leans on signing for its whole trust argument, so this is the largest gap between the spec and this implementation.
  • ism_bridge as an MCP tool. Section 5.1 describes it, and the Bridge it would expose now exists, but the Frame Server does not register it and still advertises Level 1 only.
npm install && npm test
npx tsx bin/ism.ts validate examples/capism-attribution.json
npx tsx bin/ism.ts serve examples

Read SPEC.md first — it is the source of truth, and Section 8 lists what is still broken in it.

Site

https://bjoyce1.github.io/ism-protocol — the specification, the corpus, and a narrated walkthrough of a Bridge run you can drive yourself.

It is generated from this repository's own sources, so it cannot drift from them:

npm run site

That reads SPEC.md, corpus/, schema/ and CONTRIBUTING.md and writes docs/, which GitHub Pages serves. Edit site/ and rebuild; never edit docs/ by hand.

Contributing

See CONTRIBUTING.md. Spec changes go through an issue before a pull request, and any change to Bridge behaviour needs a corpus case.

The single most useful thing anyone can do right now is implement the spec independently and report where it was ambiguous. A protocol with one implementation cannot tell the difference between what it specified and what that implementation happens to do — and §8 is candid that the remaining hard problem is one no amount of testing this codebase will find. If you read a section two ways and had to pick one, that is a bug in SPEC.md even if your code works.

License

Two licenses, split by what the file is.

  • Code — everything under src/, bin/, and tests/ — is Apache License 2.0. See LICENSE.
  • The specification, schemas, and conformance corpusSPEC.md, everything under schema/, the worked Frames under examples/, and the cases under corpus/ — are CC BY 4.0. See LICENSE-SPEC. The corpus is licensed this way on purpose: it is a normative artifact meant to be copied and run by other implementations, not test code for this one.

Copyright 2026 Cornelius A. Pratt.

About

An open protocol for carrying stance between AI systems. Rides on MCP.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages