started
Dispatch began. The runtime has accepted the envelope and initiated the provider call.
Harnessed AI Polyglot Protocol Interface. The universal protocol for AI integration. Any model. Any transport. One contract.
AI is a syscall.
HAPPI defines a single stdio contract. Send one NDJSON envelope. Receive a stream of NDJSON events. The contract is the spec. The CLI is canonical.
{
"v": "happi/1.0",
"id": "req-1",
"cmd": "anthropic.messages.create",
"args": ["Explain transformers in one sentence."]
}
{"v":"happi/1.2","id":"req-1","type":"started","ts":0}
{"v":"happi/1.2","id":"req-1","type":"delta","ts":5,"text":"Transformers"}
{"v":"happi/1.2","id":"req-1","type":"delta","ts":12,"text":" use self-attention"}
{"v":"happi/1.2","id":"req-1","type":"delta","ts":18,"text":" to weight relationships."}
{"v":"happi/1.2","id":"req-1","type":"completed","ts":200,"usage":{"input_tokens":8,"output_tokens":12}}
vhappi/1.0, happi/1.1, or happi/1.2. v1.2 runtimes accept all three; older envelopes dispatch unchanged. Emitted events carry the runtime's version (happi/1.2). Enables evolution without breakage.idcmdprovider.method. Namespacing is hierarchical, extensible, and self-documenting.
Exit codes: 0 on success. Non-zero on error. Standard POSIX discipline.
Seven streaming event types are sufficient to express every provider semantic: text generation, tool calls, multi-turn agents, recursive dispatch, and error handling. v1.1 adds an eighth — idr — an audit-only terminator that carries a tamper-evident receipt over the envelope and event stream. It is opt-in via flags.audit=true and emitted at most once after completed/error.
startedDispatch began. The runtime has accepted the envelope and initiated the provider call.
deltaStreamed content chunk. Partial tokens flow as the model generates. Zero-buffer end-to-end.
tool_callRuntime is invoking a tool. Declarative: name, arguments, invocation ID. Host-agnostic.
tool_resultTool returned. Payload is opaque JSON. The runtime feeds it back into the provider loop.
sub_requestA child HAPPI envelope was dispatched. Recursion is first-class. The same runtime handles it.
completedSuccess. Final event. Carries usage statistics: input tokens, output tokens, latency.
errorFailure. Terminal. Carries a code and human-readable message. Exit code follows.
idr v1.1Audit terminator. Opt-in via flags.audit=true. Carries a sha256 over the envelope and the full event stream. Replayable, locally verifiable, tamper-evident.
IDR is HAPPI/1.1's audit primitive. Set flags.audit=true on the input envelope, and the runtime emits one extra event after completed or error: an idr event carrying a sha256 hash over the envelope plus the full NDJSON event stream. Replayable. Locally verifiable. Tamper-evident. Stdlib-only.
An Intent Decision Record is an audit receipt for a single HAPPI dispatch. It binds the input envelope to the output event stream with a deterministic hash. Anyone who has the same (envelope, ndjson_events) pair can recompute the hash and confirm the run was not tampered with — or replay it through any conforming runtime to confirm the same hash again.
The IDR is emitted as a standalone idr event after completed or error — it is the new optional 8th event type and acts as a terminator that carries no streaming content of its own.
echo '{"v":"happi/1.1","id":"audit-1","cmd":"echo","args":["hi"],"flags":{"audit":true}}' \
| bash happi.md run
The runtime accepts happi/1.0, happi/1.1, and happi/1.2 envelopes. Older envelopes dispatch unchanged. v1.1 unlocked flags.audit and the v1.1 cmd set; v1.2 adds the signed memory-chain.
sha256idr event itself.cidmodel_versions{"anthropic":"claude-opus-4-7"}).block_anchoridr.emit
Already have a recorded (envelope, ndjson_events) pair? The stdlib runtime exposes idr.emit — pass them as arguments and it emits a single idr event with the deterministic sha256. Used for replay, conformance, or RWA on-chain anchoring.
sha256 is stdlib in every language.cid and block_anchor fields plug into content-addressable storage and on-chain notarisation without changing the protocol.
The IDR design is wrong if (a) audit-enabled runs produce a non-deterministic sha256 for the same envelope and event sequence, (b) the idr event arrives before completed/error (it must be the terminator), or (c) a single dispatch emits both an idr event and an inline idr_ref field on the completed/error event.
The stdlib runtime adds four cmds in v1.1:
idr.emitargs = [envelope_json, ndjson_events], computes the sha256 and emits a single idr event. Used to produce IDRs after-the-fact from recorded streams.pr.referenceflags.pr (int), flags.repo (str). Used in fractal seeds.hypothesis.registerargs[0] id; flags.{claim,metric,prediction,deadline}.quine.spawnflags.parent_issue (int), flags.repo (str). DRY-RUN unless flags.live=true.
All four cmds are stdlib-only — no extra dependencies (quine.spawn LIVE mode additionally requires the gh CLI; DRY-RUN does not).
The IDR proves what happened in one decision. The memory-chain proves the context the agent was carrying across many turns — an append-only chain of signed context events, each linking the one before it. HAPPI/1.2 makes that chain the stable capture surface. Opt in with one cmd; what you get back is a tamper-evident record of the agent's evolving knowledge that anyone can replay and verify.
They are structural twins — both are opt-in terminator events emitted once after completed or error, and neither carries streaming content — but they answer different questions:
idr)context)context event names its predecessor, so a session's knowledge is an append-only chain of content-addressed deltas — readable, replayable, and impossible to silently shorten.
A single run can carry both: an idr (via flags.audit=true) and a context (via cmd:"context.append") are independent terminators, each emitted at most once.
context event isA context event is one signed link in the memory-chain. It does not record the text of a conversation — it records the identity of a belief: a content address (a hash) of the decision body, plus a pointer back to the previous link. Follow the pointers and you can rebuild exactly what the agent knew at any point, and prove the chain has no gaps. It reuses the same machinery as the IDR — the difference is the backward link that threads the chain.
echo '{"v":"happi/1.2","id":"ctx-1","cmd":"context.append",
"args":["{\"learned\":\"the demo serves from www, not apex\"}"],
"flags":{"kind":"context-delta","predecessor_context":"ctx-0"}}' \
| bash happi.md run
The runtime accepts happi/1.0, happi/1.1, and happi/1.2 envelopes — older envelopes dispatch unchanged. v1.2 adds no new event types or cmds over v1.1; it ratifies the context event and the context.append cmd as the stable, signed memory-chain surface. Chain metadata travels in flags (predecessor_context, snapshot_ref, kind, model_versions); the default kind is context-delta.
context_ref carriessha256id, ts, and audit fields, exactly as git's tree-hash excludes the commit date. Two records with the same meaning but different timestamps share one sha256 — that shared address is what makes deduplication and chaining possible. (This is a different hash from the IDR's: the IDR hashes the envelope + event stream; the context event hashes only the belief.)predecessor_contextid of the previous context node — the backward link that threads the chain. null at the first link (genesis).kindcontext-delta (a new thing learned), context-snapshot (a folded summary so readers need not walk to genesis), or context-supersede (a forward-only correction — history is never rewritten).snapshot_refsha256 of the snapshot this delta builds on; null if none. Lets a reader fold only the tail since the last snapshot instead of the whole chain.model_versionsThe chain has two independent integrity layers, and they prove different things:
sha256 is in every language's standard library, so anyone can recompute a link's address from its body and confirm the contents — no special tool, no central service.context-supersede event: the correction wins when the chain is read, while the original stays in the chain, still signed — like a git revert, never a force-push.context event is opt-in and additive; a consumer that does not recognise it forwards it inertly, never rejecting it.
The memory-chain design is wrong if (a) two bodies identical but for their id/ts/audit fields produce different context_ref.sha256 values (the content address is broken), (b) a context event ever arrives before completed/error (it must be a terminator), or (c) a runtime's context_ref.sha256 is not byte-identical to the reference content-address for the same body (cross-runtime divergence).
A HAPPI document is simultaneously valid Markdown, bash, YAML, and LLM prompt. No separate authoritative schema exists. The polyglot form is the spec.
#!/usr/bin/env bash
: <<'HAPPI_DOC'
---
v: happi/1.0
id: demo-1
cmd: anthropic.messages.create
---
# Demo Plan
Ask Claude to explain HAPPI in one paragraph.
## prompt
Explain HAPPI/1.0 in one paragraph for a senior engineer.
HAPPI_DOC
# Bash sees a heredoc. Markdown sees headings. YAML sees frontmatter.
# The LLM sees a prompt. One file. Every parser is happy.
hal --happi-api < "$0"
hal on the last line refers to HAL — Harness Abstraction Layer — ENTER Konsult's internal HAPPI runtime, currently in development and evaluation. Substitute any HAPPI-compliant runtime.
The HAPPI spec document is not just documentation. It is the program. The same file is simultaneously readable by five different parsers — each sees exactly what it needs, nothing more.
Sees the prose, headings, and tables. The bash heredoc is invisible noise. Renders beautifully.
bash happi-spec.md — the heredoc wraps the Markdown into a discarded string. The bootstrap code at the bottom runs.
Extracts the YAML fenced block labelled yaml-openapi. A full 3.1 schema lives inside the Markdown prose.
The llm-system-prompt block gives an AI model the rules for emitting HAPPI events. The spec teaches itself.
The embedded work queue is a list of HAPPI envelopes. happi extract envelopes spec.md | hal --happi-api runs the entire build plan.
The Liskov Substitution Principle — the L in SOLID — states that any implementation of a supertype must be replaceable by any subtype without breaking correctness. HAPPI applies this to protocols. Swap Anthropic for Gemini. Swap stdio for HTTP. Swap Python for Go. The envelope contract does not change. Any conforming runtime is a valid substitution. LSP at protocol scale.
Barbara Liskov introduced this principle in 1987, the same decade Smalltalk was proving that messages — not objects — were the real unit of computation. HAPPI is that bet replayed for AI: the message is universal; the model is an implementation detail. SOLID Snake would approve. One contract. Any codec.
happi extract markdown plans/happi-spec.md # prose only
happi extract openapi plans/happi-spec.md # OpenAPI 3.1 schema
happi extract llm-prompt plans/happi-spec.md # system prompt for LLMs
happi extract envelopes plans/happi-spec.md # runnable work queue
happi extract bash plans/happi-spec.md # bootstrap script
HAPPI is defined by what would disprove it. Every axiom names the observation that would force a revision of the spec.
Every transport (HTTP, WebSocket, socket, queue) is a shim to the same stdio contract. The CLI is the reference implementation.
All provider semantics map onto started, delta, tool_call, tool_result, sub_request, completed, and error.
Child envelopes are indistinguishable from top-level ones. There is no privileged inner interface. Composition is free.
No separate authoritative schema exists. The spec document is executable, parsable, and renderable in its native form.
Every vendor shipped an incompatible stack. Connecting networks meant rewriting the application. Interop was a business decision.
Every AI provider ships an incompatible SDK. Integrating models means rewriting the runtime. Interop is a business decision.
One envelope. Any model. Any transport. The application stops caring where the intelligence comes from. AI becomes infrastructure.
A protocol wins when the boundary it draws is more useful than the systems on either side. HAPPI draws the boundary between your code and any AI. That boundary, stabilised, compounds.
Anthropic, OpenAI, and Gemini each use a different streaming wire format. HAPPI normalises all three into the same seven-event vocabulary — confirmed by a golden-fixture replay harness. Switch providers by changing one field.
event: content_block_delta
data: {"type":"content_block_delta",
"delta":{"type":"text_delta",
"text":"Hello"}}
event: content_block_delta
data: {...,"text":", "}
event: content_block_delta
data: {...,"text":"HAPPI!"}
event: message_delta
data: {"usage":{"input_tokens":3,
"output_tokens":4}}
event: message_stop
data: {"type":"message_stop"}
data: {"choices":[{"delta":
{"content":"Hello"},
"finish_reason":null}]}
data: {"choices":[{"delta":
{"content":", "}}]}
data: {"choices":[{"delta":
{"content":"HAPPI!"}},
"finish_reason":"stop"],
"usage":{"prompt_tokens":3,
"completion_tokens":4}}
data: [DONE]
data: {"candidates":[
{"content":{"parts":[
{"text":"Hello"}]}}]}
data: {"candidates":[
{"content":{"parts":[
{"text":", "}]}}]}
data: {"candidates":[
{"content":{"parts":[
{"text":"HAPPI!"}]},
"finishReason":"STOP"}],
"usageMetadata":{
"promptTokenCount":3,
"candidatesTokenCount":4}}
All three produce the same HAPPI event stream
{"v":"happi/1.2","id":"req-1","type":"started","ts":0}
{"v":"happi/1.2","id":"req-1","type":"delta","ts":8,"text":"Hello"}
{"v":"happi/1.2","id":"req-1","type":"delta","ts":14,"text":", "}
{"v":"happi/1.2","id":"req-1","type":"delta","ts":22,"text":"HAPPI!"}
{"v":"happi/1.2","id":"req-1","type":"completed","ts":180,"usage":{"in_tokens":3,"out_tokens":4}}
Switch from Anthropic to Gemini: change cmd: "anthropic.messages.create"
to cmd: "gemini.generate". Zero application code changes.
stdioHTTP / SSE/dispatch. Response is application/x-ndjson stream.Unix socketWebSocketMCPEvery AI framework solves the same problem differently and incompatibly. HAPPI solves it once — at the wire protocol layer — so any language, any model, and any agent topology participates without rewriting.
# Anthropic Python SDK
from anthropic import Anthropic
stream = Anthropic().messages.stream(
model="claude-opus-4-7",
messages=[{"role": "user", "content": "Summarise"}]
)
# OpenAI Python SDK — different object model
from openai import OpenAI
stream = OpenAI().chat.completions.create(
model="gpt-4o", stream=True,
messages=[{"role": "user", "content": "Summarise"}]
)
# Gemini Python SDK — different auth, different interface
import google.generativeai as genai
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
stream = genai.GenerativeModel("gemini-2.0-flash") \
.generate_content("Summarise", stream=True)
# Three SDKs. Three auth schemes. Three streaming formats.
# Three error types. Three upgrade cycles.
import json, subprocess
envelope = {
"v": "happi/1.0", "id": "summarise-1",
"cmd": "anthropic.messages.create", # change to switch provider
"args": ["Summarise"]
}
proc = subprocess.run(
["hal", "--happi-api"],
input=json.dumps(envelope), text=True, capture_output=True
)
for line in proc.stdout.splitlines():
ev = json.loads(line)
if ev["type"] == "delta":
print(ev["text"], end="", flush=True)
# One envelope shape. One event stream shape. Every provider.
# Change "cmd" to switch provider. Nothing else changes.
| Dimension | LangChain / LangGraph | AutoGen / CrewAI | PydanticAI | HAPPI/1.0 |
|---|---|---|---|---|
| Nature | Python framework | Python framework | Python framework | Open wire protocol |
| Language support | Python only | Python only | Python only | Any language via stdin/stdout |
| Provider portability | Via adapters, abstraction leaks | Partial, config-driven | Type-safe adapters, per-provider | Any provider via one cmd field |
| Agent composition | Graph nodes & edges | Role-based chat agents | Typed agent classes | sub_request — nested envelopes, recursive |
| Streaming contract | Provider-specific chunk types | Provider-specific chunk types | Typed stream objects | 7 canonical event types, always |
| Transport support | HTTP / in-process | HTTP / in-process | HTTP / in-process | stdio, HTTP, socket, MCP, queue |
| Spec stability | Code is the spec — drifts with releases | Code is the spec — drifts with releases | Code is the spec — drifts with releases | Frozen at 1.0 — documentation drift structurally impossible |
| Zero-dep first call | pip install (many transitive deps) | pip install (many transitive deps) | pip install pydantic + provider SDK | echo '...' | hal --happi-api |
Pipe one line of JSON into a HAPPI runtime. Watch the event stream. That is the entire onboarding.
About hal: The CLI shown below is a codename for HAL — Harness Abstraction Layer — a novel AI runtime harness currently in development and internal evaluation at ENTER Konsult. It is not yet publicly available. Any HAPPI-compliant runtime will accept the same envelope format shown here.
Try it in one line:
curl -sL https://happi.md/try.sh | bash
echo '{"v":"happi/1.0","id":"hello","cmd":"anthropic.messages.create","args":["Say hi"]}' \
| hal --happi-api
{"v":"happi/1.2","id":"hello","type":"started","ts":0}
{"v":"happi/1.2","id":"hello","type":"delta","ts":12,"text":"Hi!"}
{"v":"happi/1.2","id":"hello","type":"completed","ts":180,"usage":{"input_tokens":3,"output_tokens":2}}
import json, sys
for line in sys.stdin:
envelope = json.loads(line)
req_id = envelope["id"]
emit = lambda **kw: sys.stdout.write(
json.dumps({"v": "happi/1.0", "id": req_id, **kw}) + "\n"
) or sys.stdout.flush()
emit(type="started", ts=0)
for chunk in call_provider(envelope["cmd"], envelope["args"]):
emit(type="delta", ts=chunk.ts, text=chunk.text)
emit(type="completed", ts=chunk.ts, usage=chunk.usage)
import subprocess, json
envelope = {
"v": "happi/1.0", "id": "py-1",
"cmd": "anthropic.messages.create",
"args": ["What is HAPPI?"]
}
result = subprocess.run(
["hal", "--happi-api"],
input=json.dumps(envelope), capture_output=True, text=True
)
for line in result.stdout.splitlines():
ev = json.loads(line)
if ev["type"] == "delta":
print(ev["text"], end="", flush=True)
const { execFileSync } = require('child_process')
const envelope = {
v: 'happi/1.0', id: 'node-1',
cmd: 'anthropic.messages.create',
args: ['What is HAPPI?']
}
const out = execFileSync('hal', ['--happi-api'], {
input: JSON.stringify(envelope), encoding: 'utf8'
})
out.split('\n').filter(Boolean).map(JSON.parse).forEach(ev => {
if (ev.type === 'delta') process.stdout.write(ev.text)
})
echo '{"v":"happi/1.0","id":"sh-1","cmd":"echo","args":["Hello from HAPPI"]}' \
| hal --happi-api \
| while IFS= read -r line; do
printf '%s' "$line" | jq -r 'select(.type=="delta") | .text'
done
cmd := exec.Command("hal", "--happi-api")
cmd.Stdin = strings.NewReader(
`{"v":"happi/1.0","id":"go-1",` +
`"cmd":"anthropic.messages.create","args":["What is HAPPI?"]}`,
)
out, _ := cmd.Output()
for _, line := range bytes.Split(out, []byte("\n")) {
if len(line) == 0 { continue }
var ev map[string]interface{}
json.Unmarshal(line, &ev)
if ev["type"] == "delta" { fmt.Print(ev["text"]) }
}
That is a conforming HAPPI runtime. Any client written against the contract works. Swap providers without touching the caller.
The OpenAI SDK is a client for one provider. HAPPI is a protocol for any provider. A client ties your runtime to one vendor's object model, auth flow, streaming format, and release cadence. HAPPI standardises on a stdio contract that every provider can implement. The OpenAI SDK is a shim on top of HAPPI in the same way a browser is a shim on top of HTTP — necessary at one layer, insufficient at another.
gRPC requires schema compilation, code generation, and a runtime. NDJSON requires json.dumps and a newline. The cost-benefit curve is lopsided: for streaming AI responses, NDJSON gives you 95% of the value of Protobuf at 5% of the operational cost. HAPPI prioritises the developer who wants to pipe one line of JSON into one line of bash. A binary format can be layered on top if throughput ever matters more than approachability.
A single file that is simultaneously valid bash, Markdown, YAML, and an LLM prompt. The bash shebang makes it executable. A heredoc wraps the rest so bash skips it. Inside the heredoc, YAML frontmatter declares the envelope, Markdown documents the intent, and the natural-language body is the prompt. Four parsers look at the same bytes and each sees a well-formed document in their own language. No pre-processing. No build step.
A HAPPI runtime that emits tool_result can alternatively emit sub_request — a complete nested HAPPI envelope — and wait for its event stream. The child dispatch goes through the exact same runtime as the parent. There is no privileged inner interface. This means an agent that plans, researches, drafts, and critiques is expressible as a tree of HAPPI envelopes, each leaf a plain provider call. Composition is a property of the protocol, not of any agent framework.
The reference runtime (hal) ships with Anthropic, OpenAI-compatible, and Gemini provider adapters; HTTP and socket transports; recursive compose command; and a queue driver that consumes polyglot plan files. HAPPI/1.0 is declared stable for production use within CodeTonight-operated systems. External adoption is the next phase: the spec is frozen at 1.0 so you can build against it without churn.
HAPPI/1.0 is an open specification. Implementations, transport adapters, provider shims, language bindings, and conformance test suites are all welcome. Issues and proposals are tracked on the GitHub repository. The spec itself changes conservatively: the four axioms are the North Star, and any change must survive them. Breaking changes become HAPPI/2.0, not a silent revision of 1.0.