Skip to content

Manifesto Intent & Projection Specification v1.1

Status: Proposed Scope: Normative (except where marked Informative) Authors: Manifesto Team Applies to: All Manifesto Intent Producers & Projections License: MIT Changelog: v1.1 adds Action Catalog system (§3.4, §7.4), clarifies ExpressionIR cross-reference, adds catalogHash algorithm


Table of Contents

  1. Purpose
  2. Normative Language
  3. Definitions
  4. Intent Semantics
  5. Intent Types
  6. Intent Identity
  7. Projection Contract
  8. System Direct Intent
  9. Weak Interpreter Boundary
  10. SnapshotView Contract
  11. Determinism Requirements
  12. Projection Recording
  13. Scope Proposal & Approval
  14. Integration with World Protocol & Host
  15. Bridge Compatibility (Informative)
  16. Invariants
  17. Explicit Non-Goals

1. Purpose

This document defines Intent and Projection for Manifesto.

It specifies:

  • Intent is a Command (not an event)
  • Intent identity uses dual keys: intentId (instance) and intentKey (semantic)
  • Projection is a weak interpreter (DX-friendly selection, not domain logic)
  • Projection may read SnapshotView (data + computed) read-only
  • Projection MUST be deterministic
  • Scope is proposed by Projection, approved by Authority
  • Action Catalog is a projection output for context injection (v1.1)

2. Normative Language

Key words MUST, MUST NOT, SHOULD, MAY, etc. are interpreted as described in RFC 2119.


3. Definitions

3.1 Actor

All Intents are attributable to an Actor. System is also an Actor.

typescript
type ActorKind = 'human' | 'agent' | 'system';

type ActorRef = {
  readonly actorId: string;
  readonly kind: ActorKind;
  readonly name?: string;
  readonly meta?: Record<string, unknown>;
};

3.2 SourceEvent

The raw external trigger that Projection receives.

typescript
type SourceKind = 'ui' | 'api' | 'agent' | 'system';

type SourceEvent = {
  readonly kind: SourceKind;
  readonly eventId: string;       // Stable identifier if available
  readonly payload: unknown;      // Raw input from source
  readonly occurredAt?: number;   // OPTIONAL; MUST NOT affect semantic projection
};

3.3 SnapshotView

Projection reads a read-only view of semantic state.

typescript
type SnapshotView = Readonly<{
  data: unknown;
  computed: Record<string, unknown>;
}>;

SnapshotView intentionally excludes meta, version, and timestamp.

3.4 Action Catalog (Context Injection)

An Action Catalog is a projection output used by UIs and LLM runtimes to enumerate which actions are currently relevant and/or callable.

This specification defines a standard Action Catalog shape for Bridge runtimes.

typescript
/**
 * ExpressionIR: Opaque Intermediate Representation for availability predicates.
 * 
 * When MEL is used, this is the compiler output ExprNode.
 * See manifesto-ai-compiler SPEC §7 (IR Mapping).
 * 
 * Constraints:
 * - MUST be JSON-serializable (for cross-system transport)
 * - MUST be deterministic (same inputs → same output)
 * - MUST yield boolean result
 */
type ExpressionIR = unknown;  // Opaque; structure defined by compiler/builder

/**
 * AvailabilityContext: Input for availability evaluation.
 */
type AvailabilityContext = Readonly<{
  data: unknown;
  computed: Record<string, unknown>;
  actor: ActorRef;
}>;

/**
 * AvailabilityPredicate: What ActionDescriptor.available can hold.
 * 
 * - ExpressionIR: Portable, MEL-compiled expression (preferred)
 * - fn: Non-portable extension for local runtimes only (not cross-system)
 * - null/undefined: Always available
 */
type AvailabilityPredicate =
  | ExpressionIR
  | { readonly kind: 'fn'; readonly evaluate: (ctx: AvailabilityContext) => boolean }  // Non-portable
  | null;

type ActionDescriptor = Readonly<{
  type: string;                      // Stable action identifier
  label?: string;                    // Optional UI label
  description?: string;              // Optional description
  inputSchema?: unknown;             // JSON-serializable schema for tool/UI input
  available?: AvailabilityPredicate; // Optional availability predicate (pure)
}>;

type AvailabilityStatus =
  | { readonly status: 'available' }
  | { readonly status: 'unavailable'; readonly reason?: string }
  | { readonly status: 'unknown'; readonly reason: 'missing_context' | 'indeterminate' };

type ProjectedAction = Readonly<{
  type: string;
  label?: string;
  description?: string;
  inputSchema?: unknown;
  availability: AvailabilityStatus;
}>;

type ActionCatalog = Readonly<{
  kind: 'action_catalog';
  schemaHash: string;
  catalogHash: string;          // Deterministic hash of actions + options (see §7.4.4)
  actions: readonly ProjectedAction[];
}>;

Action Catalog is NOT a security boundary. Final enforcement remains the responsibility of World Protocol (Authority) and Core runtime validation. See FDR-IP015 for rationale.

If schemaHash is needed (it is, for intentKey), it is passed separately in ProjectionRequest.


4. Intent Semantics

4.1 Intent is a Command

An Intent is a command: a request to perform a domain action.

Intent is not a fact ("what happened"). Intent is a request ("do this").

A system MAY transport Intents via event streams, but "subscription" is only routing/capability. Legitimacy is governed by World Protocol (Authority), unless the actor's binding is auto-approve.

4.2 Intent Immutability

  • IntentBody MUST be immutable once produced
  • IntentInstance MUST be immutable once issued
  • If the "same semantic intent" is needed again, it MUST be re-issued as a new IntentInstance with a new intentId

5. Intent Types

5.1 Split: Body vs Meta vs Instance

To avoid conflating semantic content with metadata, Intent is structured as:

typescript
/**
 * IntentBody: Semantic content of the command
 * This is what Projection produces.
 * intentKey is computed from this (+ schemaHash).
 */
type IntentBody = {
  readonly type: string;              // Action identifier (e.g., "todo.create")
  readonly input?: unknown;           // Action parameters
  readonly scopeProposal?: IntentScope; // Proposed write scope (optional)
};

/**
 * IntentMeta: Non-semantic metadata
 * Excluded from intentKey computation.
 */
type IntentMeta = {
  readonly origin: IntentOrigin;
};

/**
 * IntentInstance: Complete intent ready for submission
 * This is what World Protocol receives.
 */
type IntentInstance = {
  readonly body: IntentBody;
  readonly intentId: string;    // Instance identity (unique per attempt)
  readonly intentKey: string;   // Semantic identity (derived from body + schemaHash)
  readonly meta: IntentMeta;
};

5.2 Intent Origin

Origin captures where and how the Intent was produced.

typescript
type IntentOrigin = {
  readonly projectionId: string;                    // Which projection produced this
  readonly source: { kind: SourceKind; eventId: string }; // Source event reference
  readonly actor: ActorRef;                         // Who is responsible
  readonly note?: string;                           // Optional human note (not semantic)
};

Rules:

  • origin is metadata, NOT semantic content
  • origin MUST NOT affect intentKey computation
  • origin.note is for debugging only and MUST NOT affect any computation

5.3 Intent Scope

Scope defines proposed write boundaries.

typescript
type IntentScope = {
  readonly allowedPaths?: string[];  // Path patterns allowed to write (e.g., "data.profile.*")
  readonly note?: string;            // Optional human description
};

6. Intent Identity

6.1 intentId (Instance Identity)

intentId identifies a single processing attempt.

Rules:

RuleRequirement
ID-1Every IntentInstance MUST have an intentId
ID-2intentId MUST be unique per processing attempt
ID-3intentId MUST remain stable during a single Host execution loop
ID-4intentId SHOULD be UUIDv4, ULID, or equivalent high-entropy identifier

6.2 intentKey (Semantic Identity)

intentKey defines semantic equality across re-issuance.

6.2.1 Computation Algorithm (MUST)

intentKey MUST be computed as:

intentKey = SHA-256(
  schemaHash + ":" +
  body.type + ":" +
  JCS(body.input ?? null) + ":" +
  JCS(body.scopeProposal ?? null)
)

Where:

  • SHA-256 produces a lowercase hex string
  • JCS(x) is JSON Canonicalization Scheme (RFC 8785) applied to x
  • ?? is nullish coalescing (use null if undefined)

Implementation Notes:

  • Implementations MAY prefix the result (e.g., sha256:abcd...) but MUST be consistent
  • Implementations MAY use an alternative canonicalizer only if it produces byte-identical output to RFC 8785 for all JSON values

6.2.2 Explicit Exclusions (MUST NOT)

The following fields MUST NOT be included in intentKey computation:

Excluded FieldReason
intentIdInstance-specific
meta.origin.*Metadata, not semantic
Wall-clock timestampsNon-deterministic
Runtime correlation fieldsInstance-specific

Rationale: The same semantic command (e.g., "create todo with title X") may originate from different projections, actors, or sources. These are the same intent, just different attempts.

6.3 Equality Semantics

Equality TypeDefinitionUse Case
Instance equalitySame intentId"Is this the exact same attempt?"
Semantic equalitySame intentKey"Is this the same command?"

6.4 Retry and Re-issue Semantics

When retrying or re-issuing a semantically identical command:

FieldBehavior
intentIdMUST be new (different attempt)
intentKeyMUST be same (if body is identical)
bodySame content produces same key

If body changes (different input, different scope), intentKey changes.


7. Projection Contract

7.1 Projection Definition

A Projection maps (SourceEvent, SnapshotView, Actor) to an IntentBody (or none).

Projection does NOT execute, patch, or apply. It only selects an Intent type and shapes its input.

typescript
type ProjectionResult =
  | { kind: 'none'; reason?: string }
  | { kind: 'intent'; body: IntentBody };

interface Projection {
  readonly projectionId: string;

  project(req: ProjectionRequest): ProjectionResult;
}

type ProjectionRequest = {
  readonly schemaHash: string;      // For intentKey computation reference
  readonly snapshot: SnapshotView;  // Read-only: data + computed
  readonly actor: ActorRef;         // Who is acting
  readonly source: SourceEvent;     // What triggered this
};

7.2 Issuer Contract

Projection returns IntentBody only. An Issuer produces IntentInstance.

typescript
interface IntentIssuer {
  issue(req: IssueRequest): IntentInstance;
}

type IssueRequest = {
  readonly schemaHash: string;
  readonly projectionId: string;
  readonly actor: ActorRef;
  readonly source: SourceEvent;
  readonly body: IntentBody;
};

Issuer Responsibilities (MUST):

ResponsibilityDescription
Generate intentIdNew unique identifier for this attempt
Compute intentKeyUsing §6.2.1 algorithm
Attach meta.originFrom projectionId, source, actor
Ensure immutabilityReturned IntentInstance is frozen

Issuer Constraints (MUST NOT):

ConstraintDescription
Modify bodyIssuer MUST NOT change type, input, or scopeProposal
Add semantic contentIssuer MUST NOT inject business logic

7.3 Issuer Deployment (Guidance)

ContextTypical Issuer Location
UIBridge runtime
APIAPI gateway or handler
AgentAgent runtime
SystemSystem runtime or scheduler

7.4 Action Catalog Projection (Standard, Optional)

In addition to Intent-producing projections, Bridge runtimes MAY provide a deterministic Action Catalog Projection that supports state-dependent context injection for UIs and LLM toolsets.

This projection does not produce Intents and does not interact with World Protocol. It is a read-only selection & shaping operation that enumerates currently relevant actions.

7.4.1 Contract

typescript
type ActionCatalogProjectionRequest = Readonly<{
  schemaHash: string;
  snapshot: SnapshotView;                 // data + computed (read-only)
  actor: ActorRef;                        // acting actor (for meta/roles)
  actions: readonly ActionDescriptor[];    // source catalog (typically from schema)
  mode?: 'llm' | 'ui' | 'debug';           // default: 'llm'
  pruning?: Readonly<{
    policy?: 'drop_unavailable' | 'mark_only';  // default: drop_unavailable
    includeUnknown?: boolean;                   // default: true
    maxActions?: number;                        // OPTIONAL
    sort?: 'type_lex' | 'schema_order';         // default: type_lex
  }>;
}>;

/**
 * Sort order definitions:
 * - `type_lex`: Lexicographic sort by `action.type` (deterministic, interoperable)
 * - `schema_order`: Preserve the order of `req.actions` as provided.
 *   Callers MUST provide `req.actions` in a deterministic order when using `schema_order`.
 */

interface ActionCatalogProjector {
  projectActionCatalog(req: ActionCatalogProjectionRequest): ActionCatalog;
}

7.4.2 Availability Evaluation

  • If ActionDescriptor.available is absent or null, the action is treated as available.
  • If available is present, implementations MUST evaluate it deterministically from:
    • snapshot.data
    • snapshot.computed
    • actor context (at minimum actorId, kind, and actor.meta)

Purity requirement: availability evaluation MUST NOT depend on:

  • time, randomness, network, external IO
  • $system.*, $input.*, or effects (as defined by MEL availability purity constraints)

If evaluation cannot be completed due to missing context (e.g., required actor meta is absent), the action MUST be marked { status: 'unknown', reason: 'missing_context' } rather than forced to false.

If evaluation cannot be completed due to expression complexity (e.g., requires runtime-only data), the action MUST be marked { status: 'unknown', reason: 'indeterminate' }.

Implementations SHOULD use IR/AST dependency inspection (or builder-provided deps) to detect missing context and avoid false-negative pruning.

7.4.3 Pruning Policy

Default behavior (when pruning is omitted):

  • policy = drop_unavailable
  • includeUnknown = true
  • sort = type_lex

Rules:

  • drop_unavailable: remove actions where availability.status === 'unavailable'
  • mark_only: keep all actions, but set availability accordingly (debug tooling)

If maxActions is set, implementations MUST apply it deterministically (e.g., after sorting, take the first N).

7.4.4 Determinism and catalogHash

Action Catalog Projection MUST be deterministic.

appliedPruningOptions is the effective pruning configuration after applying defaults:

typescript
const appliedPruningOptions = {
  policy: req.pruning?.policy ?? 'drop_unavailable',
  includeUnknown: req.pruning?.includeUnknown ?? true,
  sort: req.pruning?.sort ?? 'type_lex',
  maxActions: req.pruning?.maxActions ?? null
};

catalogHash MUST be computed as:

catalogHash = SHA-256(
  schemaHash + ":" +
  JCS(actions.map(a => ({
    type: a.type,
    status: a.availability.status,
    reason: a.availability.status === 'unknown' ? a.availability.reason : null
  }))) + ":" +
  JCS(appliedPruningOptions)
)

Where:

  • SHA-256 produces a lowercase hex string
  • JCS(x) is JSON Canonicalization Scheme (RFC 8785) applied to x
  • actions is the final list after pruning (not the input list)

Note on mode: The mode parameter ('llm' | 'ui' | 'debug') affects which fields are included in the output (e.g., description for LLM, label for UI), but is NOT included in catalogHash. If implementations need mode-specific caching, they SHOULD use a composite key: (catalogHash, mode).

Non-deterministic fields (timestamps, counters) MUST NOT contribute to catalogHash.

Critical: World Protocol MUST receive IntentInstance, not IntentBody.

7.4.5 Unknown Status and Runtime Behavior

If an action with status: 'unknown' is subsequently invoked via Intent:

  • Core runtime MUST evaluate the action availability predicate before executing the flow
  • Authority MAY evaluate availability while judging a Proposal, but it is not required by this spec
  • Authority and Host MUST NOT treat projection-time unknown as unavailable
  • Unknown status is a projection-time optimization hint, not a final determination

This ensures that honest uncertainty at projection time does not incorrectly block valid actions. The enforcement responsibility lies with Core runtime, not Authority.


8. System Direct Intent

System Actors MAY produce IntentBody directly without using a formal Projection.

8.1 When Direct Intent is Allowed

System direct intent is appropriate for:

  • Scheduled jobs (cron, timers)
  • Migration scripts
  • Internal automation
  • Event-driven system reactions

8.2 Direct Intent Rules (MUST)

RuleRequirement
SD-1origin.projectionId MUST indicate direct production (e.g., system:direct, system:scheduler)
SD-2origin.source.kind MUST be 'system'
SD-3Determinism requirements still apply to the producing logic
SD-4All Intent invariants (INV-I*) apply
SD-5Projection invariants (INV-P*) do NOT apply (no Projection involved)

8.3 Direct Intent Example

typescript
// System scheduler producing an intent directly
const body: IntentBody = {
  type: 'maintenance.cleanup',
  input: { olderThanDays: 30 },
};

const instance = issuer.issue({
  schemaHash: currentSchemaHash,
  projectionId: 'system:scheduler',  // Marker for direct production
  actor: { actorId: 'scheduler', kind: 'system' },
  source: { kind: 'system', eventId: 'cron-daily-001', payload: {} },
  body,
});

9. Weak Interpreter Boundary

Projection is explicitly a weak interpreter.

Projection MAY select among known actions. Projection MUST NOT invent meaning or implement domain logic.

9.1 Allowed Operations (MAY)

Projection MAY:

OperationExample
Select body.type based on UI identifiersbuttonId === 'btnSubmit'type: 'form.submit'
Gate emission on computed availabilityif (!computed.canSubmit) → none
Extract input from source payloadbody.input = { title: payload.title }
Perform lossless transport normalizationEnsure JSON-compatible primitives
Propose scopebody.scopeProposal = { allowedPaths: ['data.todos.*'] }

9.2 Forbidden Operations (MUST NOT)

Projection MUST NOT:

OperationWhy Forbidden
Apply domain thresholdsif (amount > 1000) belongs in Computed
Make policy decisions"needs approval" belongs in Flow/Authority
Choose "best action"Agent planning is not Projection
Mutate snapshotsProjection is read-only
Create or apply patchesProjection produces Intent, not patches
Execute effectsEffects are Host responsibility
Bypass World ProtocolAll Intents go through Authority

If a condition could change the domain outcome, it belongs in Computed/Flow, not Projection.

ScenarioBelongs InReason
"Is submit button enabled?"Computed → Projection readsAvailability is domain logic
"If amount > 1000, need approval"Computed/FlowThreshold is domain logic
"Map button click to intent type"ProjectionPure UI mapping
"Validate input format"Schema/ComputedValidation is domain logic

9.4 Examples

✅ Allowed (Weak Interpretation):

typescript
// UI mapping
if (source.payload.buttonId === 'btnSubmit') {
  return { kind: 'intent', body: { type: 'form.submit', input: source.payload.data } };
}

// Gating on computed availability
if (snapshot.computed['form.canSubmit'] === false) {
  return { kind: 'none', reason: 'Submit not available' };
}

❌ Forbidden (Strong Interpretation):

typescript
// Domain threshold in projection - WRONG
if (source.payload.amount > 1000) {
  return { kind: 'intent', body: { type: 'payment.requestApproval', ... } };
} else {
  return { kind: 'intent', body: { type: 'payment.process', ... } };
}
// This threshold belongs in Computed; Projection should read computed.requiresApproval

10. SnapshotView Contract

10.1 Read Access (MAY)

Projection MAY read:

FieldAccess
snapshot.data✅ Read-only
snapshot.computed✅ Read-only

10.2 Excluded Fields

SnapshotView intentionally excludes:

FieldReason
meta.versionWould break determinism across versions
meta.timestampNon-deterministic
meta.schemaHashPassed separately in ProjectionRequest
system.*Internal state, not for Projection
inputTransient effect input

10.3 UI State Guidance

If a UI needs loading/error states:

NeedSolution
Loading indicatorExpress via computed value derived from state
Error displayExpress via explicit field in data (schema-defined)
AvailabilityRead from computed

Do NOT rely on implicit meta fields.


11. Determinism Requirements

11.1 Projection Determinism (MUST)

Projection MUST be deterministic with respect to IntentBody.

Given identical inputs:

InputMust Be Same
schemaHash
snapshot.data
snapshot.computed
actor
source.kind
source.eventId
source.payload

Projection MUST output identical:

OutputMust Be Same
ProjectionResult.kind
IntentBody.type✅ (if intent)
IntentBody.input✅ (if intent)
IntentBody.scopeProposal✅ (if intent)

11.2 Issuer Determinism (MUST)

Issuer MUST be deterministic for:

OutputDeterministic?
intentKey✅ MUST (fixed algorithm)
meta.origin✅ MUST (based on inputs)
intentId❌ Intentionally unique

11.3 Non-Deterministic Inputs (MUST NOT)

Projection MUST NOT depend on:

InputWhy Forbidden
Wall-clock timeNon-deterministic
Random numbersNon-deterministic
Network stateExternal dependency
Global mutable stateSide-effect
source.occurredAtTimestamp

If time-based behavior is needed, it MUST be:

  • A field in source.payload (supplied externally), or
  • A field in snapshot.data (schema-defined domain state)

12. Projection Recording

Projection outputs SHOULD be recorded for debugging, replay, and audit.

12.1 Recording Guidance

Result TypeRecording
intentSHOULD record
none with reasonSHOULD record (debuggability)
none without reasonMAY omit (noise reduction)

12.2 ProjectionRecord Structure

typescript
type ProjectionRecord = {
  readonly recordId: string;        // Unique record identifier
  readonly createdAt: number;       // Timestamp (non-deterministic OK)
  readonly projectionId: string;    // Which projection
  readonly actor: ActorRef;         // Who acted
  readonly source: SourceEvent;     // What triggered
  readonly snapshotVersion?: number; // Optional: snapshot reference
  readonly result: ProjectionResult; // What was produced
  readonly intentId?: string;       // If issued
  readonly intentKey?: string;      // If issued
};

12.3 Storage Location (MAY)

ProjectionRecords MAY be stored:

  • In World Protocol storage (recommended for audit)
  • In a dedicated logging system
  • In snapshot.system.* namespace (if schema supports it)

Recording MUST NOT mutate semantic state.


13. Scope Proposal & Approval

13.1 Scope Flow Overview

Projection → scopeProposal (optional)

IntentInstance.body.scopeProposal

World Protocol Proposal

Authority → approvedScope

DecisionRecord.approvedScope

Host execution (may enforce or ignore per trust model)

13.2 Scope Proposal (Projection)

  • Projection MAY set body.scopeProposal
  • Scope proposal is a suggestion, not a guarantee
  • Projection SHOULD propose the narrowest scope needed

13.3 Scope Approval (Authority)

Authority decides the approved scope:

DecisionapprovedScope Value
Approve as proposedCopy of scopeProposal
Approve with modificationModified scope
Approve without scopenull (no restriction)
RejectN/A (proposal rejected)

13.4 World Protocol Integration

Scope is carried through the Proposal lifecycle:

typescript
// Proposal carries intent (which contains scopeProposal in body)
type Proposal = {
  readonly intent: IntentInstance;  // body.scopeProposal is here
  approvedScope?: IntentScope | null; // Set by Authority
  // ... other fields per World Protocol Spec
};

// DecisionRecord includes approved scope
type DecisionRecord = {
  readonly approvedScope?: IntentScope | null; // MUST be set if approved
  // ... other fields per World Protocol Spec
};

Note: scopeProposal is NOT duplicated in Proposal; it is read from intent.body.scopeProposal.

13.5 Scope Enforcement (v1.0)

ModelBehavior
Trusted HostHost MAY ignore approvedScope
Enforcing HostHost MUST validate patches against approvedScope

v1.0 does not mandate enforcement. Regardless of enforcement:

  • Approval flow MUST be followed
  • approvedScope MUST be recorded in DecisionRecord

14. Integration with World Protocol & Host

14.1 End-to-End Pipeline

┌─────────────┐
│ SourceEvent │
└──────┬──────┘


┌─────────────┐     ┌─────────────┐
│ Projection  │────►│ IntentBody  │
└─────────────┘     └──────┬──────┘


                    ┌─────────────┐
                    │   Issuer    │
                    └──────┬──────┘


                    ┌──────────────┐
                    │IntentInstance│
                    │ (id + key +  │
                    │  body + meta)│
                    └──────┬───────┘


                    ┌──────────────┐
                    │World Protocol│
                    │  (Proposal)  │
                    └──────┬───────┘


                    ┌──────────────┐
                    │  Authority   │
                    │  (Decision)  │
                    └──────┬───────┘
                           │ approved

                    ┌──────────────┐
                    │    Host      │
                    │ (Execution)  │
                    └──────┬───────┘


                    ┌──────────────┐
                    │  New World   │
                    └──────────────┘

14.2 Layer Responsibilities

LayerInputOutputResponsibility
ProjectionSourceEvent + SnapshotViewIntentBodySelect and shape
IssuerIntentBodyIntentInstanceAdd identity
World ProtocolIntentInstanceProposalWrap for governance
AuthorityProposalDecisionRecordJudge legitimacy
HostApproved ProposalSnapshotExecute
World ProtocolSnapshotWorldRecord history

14.3 Host Execution and intentId Stability

During a single Host execution loop for an approved Proposal:

  • Host MUST use the same IntentInstance throughout
  • Host MAY call Core compute() multiple times (for effects)
  • The intentId remains stable across all compute calls in that loop
  • No new Intent is created during execution

This is the meaning of "intentId stability during execution": it is continuation of the same attempt, not re-issuance.

14.4 World Protocol Type Alignment

World Protocol MUST use IntentInstance as defined in this spec:

typescript
// World Protocol Proposal (per World Protocol Spec)
type Proposal = {
  readonly proposalId: ProposalId;
  readonly actor: ActorRef;
  readonly intent: IntentInstance;  // THIS SPEC'S TYPE
  readonly baseWorld: WorldId;
  readonly trace?: ProposalTrace;
  readonly submittedAt: number;
  
  status: ProposalStatus;
  approvedScope?: IntentScope | null;  // Set by Authority
  // ... other fields
};

15. Bridge Compatibility (Informative)

This section is informative (non-normative guidance).

15.1 Two-Way Binding Model

Bridge packages preserve familiar FE DX:

DirectionMechanism
Domain → UIsubscribe(snapshot)
UI → Domaindispatch(intent)
typescript
interface Bridge {
  // Read current state
  subscribe(callback: (snapshot: SnapshotView) => void): Unsubscribe;
  get(path: string): unknown;
  
  // Dispatch intent (bridge acts as issuer internally)
  dispatch(body: IntentBody): Promise<void>;

  // Optional: state-dependent tool / command catalog
  // (See §7.4 Action Catalog Projection)
  projectActionCatalog?(req: ActionCatalogProjectionRequest): ActionCatalog;
  
  // Convenience: sugar for common patterns
  set(path: string, value: unknown): Promise<void>;
  // Equivalent to: dispatch({ type: 'field.set', input: { path, value } })
}

15.3 Dispatch Flow

  1. Application calls bridge.dispatch(body)
  2. Bridge internally issues IntentInstance (adds intentId, intentKey, origin)
  3. Bridge submits IntentInstance to World Protocol
  4. World Protocol handles approval and execution

15.4 Intent Type Convention

The specific Intent types (field.set, form.submit, etc.) are schema-defined, not protocol-defined.

15.5 Action Catalog Fallback (Optional Method)

If projectActionCatalog is not implemented:

  • LLM runtimes SHOULD fall back to schema-defined static action list
  • LLM runtimes MUST NOT fail; instead, treat all actions as available
  • UI runtimes MAY omit availability-based rendering
typescript
// Recommended LLM runtime fallback pattern
const catalog = bridge.projectActionCatalog?.(req) 
  ?? staticCatalogFromSchema(schema, { allAvailable: true });

This enables progressive enhancement: simple implementations can omit Action Catalog initially, and LLM runtimes will still function (with reduced optimization).


16. Invariants

16.1 Intent Invariants (MUST ALWAYS HOLD)

IDInvariant
INV-I1Every IntentInstance has immutable body, intentId, intentKey, and meta
INV-I2intentKey MUST be computed using §6.2.1 algorithm
INV-I3meta.origin MUST NOT affect intentKey
INV-I4Retry creates new intentId but preserves intentKey if body is identical
INV-I5intentId remains stable throughout a single Host execution loop

16.2 Projection Invariants (MUST ALWAYS HOLD)

IDInvariant
INV-P1Projection never patches, applies, or executes effects
INV-P2Projection is deterministic for IntentBody
INV-P3Projection reads SnapshotView (data + computed) read-only
INV-P4Projection is weak interpreter only (selection, not domain logic)
INV-P5Projection MUST NOT depend on non-deterministic inputs
INV-P6Any auxiliary projection (e.g., Action Catalog Projection) MUST be deterministic and MUST NOT invent actions

16.3 Issuer Invariants (MUST ALWAYS HOLD)

IDInvariant
INV-IS1Issuer generates unique intentId per issuance
INV-IS2Issuer computes intentKey using §6.2.1 algorithm
INV-IS3Issuer MUST NOT modify body content
INV-IS4Issued IntentInstance is immutable

16.4 System Direct Intent Invariants

IDInvariant
INV-SD1System direct intent MUST have origin.projectionId indicating direct production
INV-SD2System direct intent MUST have origin.source.kind === 'system'
INV-SD3All Intent invariants (INV-I*) apply to system direct intents

16.5 Action Catalog Invariants (v1.1)

IDInvariant
INV-AC1Action Catalog Projection MUST be deterministic
INV-AC2catalogHash MUST be computed using §7.4.4 algorithm
INV-AC3Action Catalog is NOT a security boundary; final enforcement is outside projection (Authority governance + Core runtime validation)
INV-AC4Availability predicates MUST be pure functions (no time, network, $system., $input., effects)
INV-AC5Unknown availability MUST NOT be treated as unavailable; Core runtime evaluates at execution

17. Explicit Non-Goals

This specification does NOT define:

Non-GoalReason
Authentication / securityOrthogonal concern
Prompt/tool pruning as a security boundaryPruning is UX/cost/hallucination mitigation; enforcement belongs to Authority/Core
Authority policy logicDefined by World Protocol
Patch semanticsDefined by Schema Spec
Effect executionDefined by Host Contract
UI framework specificsImplementation detail
Scope enforcement mechanismv1.0 defers to host trust model
Agent planning / reasoningApplication layer
MEL/ExpressionIR structureDefined by Compiler Spec

Appendix A: Quick Reference

A.1 Type Summary

typescript
// Body: Semantic content (what Projection produces)
type IntentBody = {
  readonly type: string;
  readonly input?: unknown;
  readonly scopeProposal?: IntentScope;
};

// Meta: Non-semantic metadata
type IntentMeta = {
  readonly origin: IntentOrigin;
};

// Instance: Complete intent (what World Protocol receives)
type IntentInstance = {
  readonly body: IntentBody;
  readonly intentId: string;
  readonly intentKey: string;
  readonly meta: IntentMeta;
};

// Scope
type IntentScope = {
  readonly allowedPaths?: string[];
  readonly note?: string;
};

// Origin
type IntentOrigin = {
  readonly projectionId: string;
  readonly source: { kind: SourceKind; eventId: string };
  readonly actor: ActorRef;
  readonly note?: string;
};

// Action Catalog (v1.1)
type ActionCatalog = {
  readonly kind: 'action_catalog';
  readonly schemaHash: string;
  readonly catalogHash: string;
  readonly actions: readonly ProjectedAction[];
};

A.2 intentKey Algorithm

intentKey = SHA-256(
  schemaHash + ":" +
  body.type + ":" +
  JCS(body.input ?? null) + ":" +
  JCS(body.scopeProposal ?? null)
)

A.3 catalogHash Algorithm (v1.1)

catalogHash = SHA-256(
  schemaHash + ":" +
  JCS(actions.map(a => ({
    type: a.type,
    status: a.availability.status,
    reason: a.availability.status === 'unknown' ? a.availability.reason : null
  }))) + ":" +
  JCS(appliedPruningOptions)
)

A.4 Key Invariants Summary

CategoryKey Rule
IntentImmutable, dual identity (id + key)
ProjectionDeterministic, weak interpreter, read-only
IssuerAdds identity, doesn't modify body
ScopeProposed by Projection, approved by Authority
Action CatalogDeterministic, NOT security boundary, pure predicates (no $input)

Appendix B: Cross-Reference

SpecRelationship
World Protocol SpecUses IntentInstance in Proposal
Host ContractExecutes approved Intents
Schema SpecDefines domain types and validation
Compiler SpecDefines ExpressionIR structure for availability predicates

B.2 World Protocol Alignment

This spec defines Intent types that World Protocol MUST use:

  • Proposal.intent is IntentInstance
  • scopeProposal is in intent.body.scopeProposal
  • approvedScope is set by Authority, stored in DecisionRecord

B.3 Compiler Spec Alignment (v1.1)

This spec references Compiler types:

  • ExpressionIR for availability predicates is the compiler output ExprNode
  • Purity constraints for availability evaluation follow MEL availability purity rules
  • See manifesto-ai-compiler SPEC §7 (IR Mapping) for structure details

End of Manifesto Intent & Projection Specification v1.1