Technical Specification v1.0

The Ask Protocol

The internet is already an object-oriented system. Computers are objects. They pass messages. That is what TCP/IP does. The web imposed a document-oriented abstraction on top, and we forgot what was underneath. The Ask Protocol returns to the internet's true nature and extends it: objects that identify themselves, explain their capabilities in natural language, teach each other how to collaborate, and recover from misunderstanding.

This is not a proposal. It is a running system. Objects interview each other, generate proxies, and self-heal today. Download it and watch.

1 Protocol Fundamentals

Every Abject has a built-in ask handler. Send it a natural-language question, and it answers from its own self-knowledge, via an LLM. If no LLM is available, it falls back to a plain manifest description.

The protocol is a single primitive: one method, one question, one answer.

The Primitive

ask(question: string) -> string

The caller sends a natural-language question. The target consults an LLM using its own manifest (name, description, interfaces, capabilities) and optionally its source code as context. The LLM's answer is returned to the caller.

This is the entire protocol. Its power comes from what you build on top of it.

Because every object in the system implements ask, any object can query any other object about its behavior. No shared documentation, no schema registry, no out-of-band coordination. The knowledge lives where the behavior lives: in the object itself.

2 Message Format and Flow

Message Envelope

All communication in the system uses a uniform message envelope. The Ask Protocol is not special; it uses the same AbjectMessage structure as every other interaction.

AbjectMessage {
  header: {
    messageId:      string    // unique identifier
    correlationId:  string?   // links replies to requests
    sequenceNumber: number    // per-sender ordering
    timestamp:      number    // milliseconds since epoch
    type:           "request" | "reply" | "event" | "error"
  }
  routing: {
    from:   AbjectId         // sender's runtime identity
    to:     AbjectId         // recipient's runtime identity
    method: string?          // handler name ("ask")
  }
  payload: T                 // method-specific data
  protocol: {
    version:       string    // protocol version
    negotiationId: string?   // agreement context
  }
}

For the Ask Protocol, the request payload is { question: string } and the reply payload is a plain string containing the object's answer.

Flow

Caller Target LLM ask({ question }) self-knowledge LLM response answer (string) 1. Send question 2. Assemble context 3. Generate answer Fallback: if no LLM is available, the target returns its manifest description as a plain-text answer.
  1. The caller sends an ask request to the target with a natural-language question.
  2. The target discovers the LLM service and assembles context from its own self-knowledge.
  3. The LLM answers the question using that context.
  4. The target returns the answer to the caller.
  5. If no LLM is available, the target falls back to a plain manifest description.

The target acts as its own authority. It does not defer to an external schema or documentation service. The answer comes from the object that owns the behavior.

3 Self-Describing Objects

Every Abject carries a structured manifest that declares its identity, capabilities, and interface. The Ask Protocol builds on this foundation.

The Manifest

AbjectManifest {
  name:                 string
  description:          string
  version:              string
  interface: {
    id:          InterfaceId
    name:        string
    description: string
    methods: [{
      name:        string
      description: string
      params:      [{ name, type, description }]
      returns:     { type, description }
    }]
    events:  [{ name, description, payload }]
  }
  requiredCapabilities: CapabilityRequest[]
  providedCapabilities: CapabilityId[]?
  tags:                 string[]
}

The manifest is a structured declaration: what the object is, what methods it exposes, what events it emits, what capabilities it needs and provides. The function formatManifestAsDescription() converts this structure into natural-language English, which becomes the LLM's system context when answering questions.

Why Objects Can Answer

ask is not a description field. It is a live handler: code that runs when the object is questioned. That is what makes it more than static self-documentation, and it is why an outside LLM reading a fixed blob cannot do the same job.

Encapsulation, not a data dump

Like any object, an Abject exposes an interface and hides its internals. It answers as itself. It does not hand out a static snapshot of everything inside.

The answer depends on who asks

The ask handler receives the caller. A scheduler and a human can get different answers to the same question. A fixed description cannot condition on context.

Answering is behavior, not a read

The handler is code: it can consult live state, negotiate, refuse, or even ask the caller back. Two objects interview each other. A description is one-way.

Always live

The answer is computed now, from the object's current manifest and source, not authored once and left to drift. As the object changes, its answers change.

The Introspect Interface

Every Abject automatically implements the abjects:introspect interface with two methods:

  • describe returns the manifest and a formatted English description.
  • ask accepts a natural-language question and returns an LLM-powered answer using the object's self-knowledge as context.

These methods are not opt-in. Every object in the system has them. This means any object can query any other object about its behavior, without prior arrangement.

Key insight: A static description written by an outside LLM is a photograph of one object's surface at one moment. ask is the object's living, two-way, caller-aware behavior, which no photograph can replicate.

4 Use Cases

The Ask Protocol is a primitive. These are the patterns built on top of it.

ObjectCreator: Code Generation

When a user describes a new object in natural language, the ObjectCreator selects dependencies, then generates targeted questions for each one. It sends these questions via the Ask Protocol and uses the answers as context when generating the new object's code.

Objects teach the next generation how to compose with them.

ProxyGenerator: Protocol Translation

When two objects need to communicate but have incompatible interfaces, the ProxyGenerator asks both sides: "How should a proxy use your methods?" It includes both answers in the LLM prompt when generating a translator proxy between them.

The proxy is not a static shim. It is a real Abject, generated from the self-descriptions of the objects it bridges.

Self-Healing: Error Recovery

When communication between two objects degrades, the system asks both objects for fresh usage guides via the Ask Protocol, collects recent errors, and regenerates the proxy with that context. The replacement accounts for exactly the errors that killed its predecessor.

Each regeneration is informed by the failures that preceded it. The system learns from its wounds.

Chat: Human Interaction

Users ask Abjects about themselves directly. The object answers from its own manifest and source. Any object in the system is queryable by a human in natural language.

There is no separate user manual. The object is the manual.

Task Routing: Approach-Based Dispatch

When a task appears in TupleSpace, the system asks every registered abject: "How would you accomplish this?" Each abject self-assesses using its own manifest and capabilities via the Ask Protocol. Abjects respond with a concrete approach or PASS. An evaluator selects the best candidate.

The Ask Protocol is the dispatch mechanism. Abjects are not assigned work; they volunteer by explaining their fitness.

Knowledge Integration: Cross-Abject Memory

Abjects store learned facts, insights, and references in the KnowledgeBase. Other abjects search and retrieve relevant knowledge via full-text search. Knowledge syncs across peers via SharedState CRDT.

What one abject learns on one machine, every abject on every peer can recall.

5 Comparison with Existing Approaches

Web Protocols

REST, GraphQL, and gRPC are the dominant protocols for service communication on the web. All three require a human in the loop to read documentation, write integration code, and update it when things change.

REST
GraphQL
gRPC
Ask Protocol
Self-Description
OpenAPI specs. Static. External to the service.
Schema introspection. Structural, not behavioral.
Proto reflection. Method listing, not explanation.
The object answers from its own self-knowledge. Dynamic.
Runtime Adaptation
None. Versioned endpoints.
None. Schema evolution.
None. Proto versioning.
Proxy regeneration with error context.
Natural Language
No.
No.
No.
Yes. Objects answer in English.
Composition
Human reads docs, writes client.
Human writes queries against schema.
Human writes client from proto.
Objects interview each other.
Error Recovery
Retry. Circuit breaker.
Partial results.
Retry policy.
Regenerate translator with error history.

LLM and Agent Protocols

A new generation of protocols has emerged around LLM integration and agent interoperability. MCP, A2A, and OpenAI's function calling each address a piece of the puzzle. The Ask Protocol occupies a different position: it is not a tool-calling convention or an agent orchestration layer, but a self-description primitive embedded in the objects themselves.

In TCP, DNS, MCP, and A2A, capability negotiation serves a higher layer that carries the real payload. The Ask Protocol has no higher layer to serve. In a peer mesh there is no top: the negotiation is the work, objects teaching each other, generating proxies, and recovering from misunderstanding. The payload is mutual understanding itself.

The key distinction: MCP, A2A, and function calling are plumbing. They define how to call tools, route messages, and negotiate capabilities. The Ask Protocol is not plumbing. It is a cognitive primitive: an object explaining itself in its own words, using its own source as evidence. The plumbing tells you how to call something. Ask tells you what it is and why you would call it.

The table below is for orientation, not parity. Ask sits at a different layer than these, so read it as "where each one lives," not a feature scorecard.

MCP
A2A
OpenAI Function Calling
Ask Protocol
Purpose
Connect LLM apps to external tools and data sources.
Agent-to-agent task delegation and coordination.
Let models invoke developer-defined functions.
Let objects explain themselves and teach each other.
Self-Description
Servers declare tools, resources, prompts at connect time. Static JSON schemas.
Agent Cards: signed JSON with identity, skills, security schemes.
Developer provides JSON schemas with descriptions per function.
The object answers from its own self-knowledge. As the object changes, the answers change.
Who Describes?
The server developer writes tool descriptions.
The agent developer writes the Agent Card.
The app developer defines function schemas.
The object describes itself. No developer in the loop at query time.
Object-to-Object
No. Tools serve the LLM, not each other.
Yes. Agents delegate tasks to other agents.
No. Functions serve the model.
Yes. Any object can ask any other object. No central coordinator.

These approaches are complementary, not competing. MCP could transport an ask call; A2A could route it between peers. But neither provides the self-description primitive itself: the Ask Protocol is the content, the others are the envelope. Its value is also a whole-system property. It pays off when every participant is an object that can be asked and ask back, not when bolted onto a single server. That bidirectional, system-wide self-knowledge is what a freeform description field cannot give you.

6 The Internet Was Always Object-Oriented

The internet is computers passing messages. TCP/IP, DNS, BGP: these are protocols between machines that identify themselves, negotiate capabilities, and exchange structured data. The internet is already object-oriented.

Ask does not replace TCP or DNS. It moves no bytes. It restores their peer, self-identifying nature at the layer of meaning: not "how do I reach you," but "what are you, and why would I call you."

The web is an application on top of the internet. HTTP imposed a document metaphor: URLs as resource locators, verbs as CRUD operations. GraphQL imposed a query metaphor. gRPC imposed a procedure metaphor. All three obscure the underlying reality: that the network is made of objects communicating.

The Ask Protocol does not add object-orientation to the internet. It reveals it. It gives networked objects what they have been missing: the ability to describe themselves, teach strangers how to use them, and adapt when communication breaks down.

Identity

Every object has a PeerId (the SHA-256 hash of its signing key) and a TypeId (a scoped, durable name). Identity is cryptographic, not assigned by a registry.

Behavior

Every object has handlers: named methods that process messages. Behavior is declared in the manifest and implemented in code. It can be inspected, queried, and modified at runtime.

Self-Knowledge

Every object carries its own manifest and can answer questions about itself via the Ask Protocol. There is no external documentation to consult.

Negotiation

When two objects with incompatible interfaces meet, the system generates a translator proxy using both objects' self-descriptions. Strangers can collaborate without prior agreement.

Combined with peer-to-peer transport (WebRTC with identity-based addressing), objects across machines discover each other, ask what the other does, and compose dynamically.

No central schema registry. No shared proto files. No API documentation site.

The schema is the object, and the object can explain itself.