Skip to content

@manifesto-ai/translator Foundational Design Rationale v1.1.1

Status: Release Version: 1.1.1 Companion To: @manifesto-ai/translator SPEC v1.1.1 License: MIT


Changelog

VersionChanges
v1.1.1Architecture Decision (FAD-001) + Critical Fixes + MEL Type Definitions
v1.1.0Added FDR-T022~T029: Manifesto Ecosystem Integration + Memory Architecture decisions
v1.0.0Initial release: FDR-T001~T021

v1.1.1 Architecture Decision Alignment

FAD-001: Translator is a Compiler Frontend with Deterministic Contracts

This version implements the foundational architecture decision that realigns Translator's identity:

ChangeFromTo
Identity"LLM-based helper"Compiler frontend with deterministic contracts
DeterminismImplicit "fully deterministic"Explicit: stages 0–2, 6 deterministic; proposer non-deterministic
WorldOptional contextPremise (cannot operate without)
MemoryOptional enhancementDefault path (absence = degradation)
Human EscalationUX featureConstitutional invariant
Type DefinitionsTypeScriptMEL (normative)

v1.1.1 MEL Type Migration

All normative domain types are now defined in MEL for consistency with Manifesto ecosystem:

RationaleDescription
Ecosystem ConsistencyTranslator operates on MEL-based World; types should be in MEL
Domain ExpressivenessMEL provides better domain modeling than TypeScript
Single Source§6 is now the single normative type definition source
Implementation AgnosticMEL types can be transpiled to any implementation language

TypeScript in SPEC is now informative (implementation examples).

v1.1.1 Final Polish (Post-GO)

ItemSectionFix
§8.8 trace presence rule§8.8Clarified when trace is present vs absent
obj.fields key uniqueness§6.2Added duplicate key validation rule

v1.1.1 Critical Issue Fixes (Round 10 — STOPPER)

BlockerIssueFix
S6MEM-006 vs §8.9 "require" mode conflictSplit MEM-006 into mode-conditional rules
S7schema.types MUST vs "if present" inconsistencyClarified schema fields REQUIRED, typeIndex derived

Details:

  • MEM-006a: mode=default → MAY skip Stage 4 (degraded)
  • MEM-006b: mode=require → MUST error (§8.9 precedence)
  • §4.6: All schema fields (types, state, computed, actions) REQUIRED (may be {})
  • §8A.2: Removed "if present", added schema requirements table
  • TypeIndex: NOT stored, MUST be derived via deriveTypeIndex(schema)

v1.1.1 Critical Issue Fixes (Round 9 — STOPPER)

BlockerIssueFix
S5§8.5 example ↔ §6.14 MemoryStageTrace field mismatchAligned both sections

Details:

  • Added degradeReason?: "SELECTOR_NOT_CONFIGURED" | "SELECTION_EMPTY" | "SELECTOR_ERROR" to §6.14 normative
  • Added errorMessage?: string to §6.14 normative
  • Fixed §8.5 contentSummary keys: schemaCountschemaSnapshotCount, glossaryCountglossaryTermCount

v1.1.1 Critical Issue Fixes (Round 8 — STOPPER)

BlockerIssueFix
S4§8.5 example ↔ MemoryStageResult mismatchRewrote memoryStage() with full type alignment

Details:

  • Added degraded: boolean (required field)
  • Changed trace from MemoryTrace to MemoryStageTrace
  • Added degradation handling (selector not configured, selector error, empty selection)
  • Added averageConfidence calculation
  • Fixed TypeExpr.literal.value from JsonValue to PrimitiveValue

v1.1.1 Critical Issue Fixes (Round 7 — STOPPER)

BlockerIssueFix
S2sys.path string vs ArraySystemPath = Array<string>
S3obj.fields Record vs key/value arrayArray<{ key: string, value: ExprNode }>

Additional:

  • Added canonicalizeExprNode() function to §13.2
  • Clarified §6.2.1 as "Translator-Level" restrictions (distinct from MEL-level)

v1.1.1 Critical Issue Fixes (Round 6 — STOPPER)

BlockerIssueFix
S1ExprNode misaligned with MEL v0.3.3Changed to 7-kind canonical IR

Details:

  • MEL v0.3.3 canonical IR: lit | var | sys | get | call | obj | arr
  • lit.value restricted to PrimitiveValue (no object/array)
  • $meta.*, $system.*, $input.* use sys node (not var)
  • obj/arr nodes for object/array literals
  • var is $item only (v0.3.3: $acc removed)
  • Added ExprNode context validation rules (§6.2.1)
  • Added MemoryStageResult type (§6.5)

v1.1.1 Critical Issue Fixes (Round 5)

BlockerIssueFix
#12addAction.params Array vs RecordChanged to Record<string, ActionParamSpec>
#13ActionBody guard-stmt bindingIntroduced GuardedBlock, ActionStmt, nested structure

Bonus:

  • Stage 4 wording: "Optional" → "Default; may degrade"
  • ProposalResult: Changed from nullable fields to discriminated union (one-of)

v1.1.1 Critical Issue Fixes (Round 4)

BlockerIssueFix
#9freeform text vs input mismatch§8B.3 examples use text
#10Human resolution missing escalation§8B.3 examples include escalation
#11deriveTypeIndex uses Array§8A.2 uses Object.entries() for Record

Bonus: Added explicit MemoryPolicy.mode: "require" failure behavior in §8.9

v1.1.1 Critical Issue Fixes (Round 3)

BlockerIssueFix
#6opt-cancel MUST vs MAY conflictUnified to MUST for all ambiguity kinds (§6.8, §11.2.1)
#7TypeExpr array vs Record mismatch§4 references §6.3 MEL; fields is Record; §13.2 updated
#8Glossary type undefinedAdded MEL data structure type Glossary = { entries: Array<GlossaryEntry> }

v1.1.1 Critical Issue Fixes (Round 2 — 5 Blockers)

This version fixes 5 critical modeling blockers that prevented spec closure:

BlockerIssueFix
#1TypeIndex/ResolvedType missing in §6Added §6.3 with normative MEL definitions
#2ExprNode too loose for call-only IRFixed §6.2 with lit/var/get/call variants
#3ResolutionPrompt field mismatchAdded optionIds to §6.8, unified text field
#4TraceConfig duplicate definitionsSingle normative MEL in §6.18
#5updateComputedExpr violates monotonicRemoved from v1 operator set (§6.7.2)

Additional Fixes:

IssueFix
MemoryStageTrace duplicateSingle canonical MEL definition (§6.14)
EscalationTrace duplicateSingle canonical MEL definition (§6.15)
Memory v1.0.0 referencesUpdated to v1.2.0 throughout
Config missing fieldsAdded MemoryPolicy type in MEL
Section numberingRenumbered §6.1-6.18 consistently
ErrorCode incompleteExtended to match §12.2 comprehensive list

v1.1.0 Decisions

FDRCategoryDecision
T022EcosystemWorld as Single Source of Truth
T023EcosystemHuman Escalation for Ambiguity
T024EcosystemActor Creates Proposal
T025EcosystemTypeIndex Derived from Schema
T026MemoryMemory Provides Content (not just refs)
T027MemoryMemory as Few-Shot Examples
T028MemoryMemory Enhances All Stages → Stage 5/6 Only
T029MemoryMemory is Optional (graceful degradation)

Table of Contents

  1. Overview
  2. Foundational Architecture Decision (FAD-001)
  3. Core Philosophy Decisions
  4. Data Model Decisions
  5. Pipeline Decisions
  6. Identity & Determinism Decisions
  7. Memory Integration Decisions
  8. Ambiguity & Resolution Decisions
  9. Configuration Decisions
  10. Summary Table
  11. Cross-Reference: Related FDRs
  12. Manifesto Ecosystem Integration Decisions
  13. Memory Architecture Decisions

Overview

This document captures the foundational design rationale for the @manifesto-ai/translator package. Each decision (FDR-T*) explains why the specification is designed the way it is, what alternatives were considered, and what consequences follow.

Translator = Manifesto World 위에서 동작하는 결정론적 Compiler Frontend

Translator is NOT an "AI helper", NOT an "LLM-based assistant", NOT a standalone tool. It is a semantic proposal engine that reads World and emits proposals.


Foundational Architecture Decision (FAD-001)

Translator is a Compiler Frontend with Deterministic Contracts

Translator = Manifesto World 위에서 동작하는 Compiler Frontend (deterministic stages 0–2, 6; untrusted/non-deterministic proposer stage 5)

This is the foundational identity of Translator. All other decisions derive from this.

Clarification on Determinism

Translator is NOT "fully deterministic" in the sense that re-running translate() produces identical output. However, contracts and core stages are deterministic:

AspectDeterministic?Notes
Semantic Identity (fragmentId)✅ YesContent-addressed
Types, Validation, IR✅ YesPure functions
Stages 0–2, 6✅ YesNo LLM
Stage 3 (Retrieval)⚠️ ShouldWith tie-breaking
Stages 4, 5❌ May notLLM-based

Key insight: Proposer (Stage 5) is explicitly untrusted. Its non-determinism is by design—Authority verifies, not Translator.

Core Properties

PropertyValue
InputNatural Language (any human language)
OutputPatchFragment[] | AmbiguityReport | TranslationError
StateNone (stateless)
TruthOnly World (Schema + Snapshot)
ResponsibilityInterpret + Propose + Trace (never Apply, never Approve)

Three Architectural Pillars

PillarDescriptionConsequence
World is PremiseTranslator cannot operate without WorldContext MUST be World-derived
Memory is DefaultMemory is structural input, not optional enhancementAbsence triggers degradation
Human Escalation is ConstitutionalAmbiguity = Human's constitutional rightAgent auto-resolve forbidden

Forbidden Patterns

PatternWhy Forbidden
"Standalone Translator"World is premise, not option
"AI helper" / "LLM assistant" framingTranslator is compiler frontend
Agent auto-resolving ambiguityHuman escalation is constitutional
Memory as "optional enhancement"Memory is default path
Direct context constructionMust derive from World

Why This Decision Matters

This decision ensures:

  • Translator is a reproducible semantic compiler (for deterministic stages)
  • Proposer non-determinism is explicitly bounded (untrusted, Authority verifies)
  • Manifesto becomes OS layer, not "LLM framework"
  • "Why not LangChain/LangGraph?" becomes clear
  • Human-in-the-loop is structure, not philosophy

This decision is final and non-negotiable.


Core Philosophy Decisions

FDR-T001: Translator is Frontend Only (No MEL Generation)

Decision

Translator outputs PatchFragment (structured semantic ops), NOT MEL text.

Context

Two possible designs:

OptionOutputDownstream
A: Code GeneratorMEL source textParser needed to consume
B: Frontend OnlyStructured IR (PatchFragment)Direct consumption

Rationale

Frontend-only design enables:

  1. No round-trip parsing: Downstream (Authority/Host) consumes fragments directly
  2. Validation before serialization: Structural validation happens on typed data
  3. Deterministic rendering: MEL text is a pure projection from IR (if needed)
  4. AI-friendly: LLMs work better with structured constraints than free-form text

Code generation would require:

  • MEL parser in every consumer
  • Handling of syntax errors from LLM
  • Loss of semantic structure

Alternatives Rejected

AlternativeWhy Rejected
Generate MEL textRound-trip parsing, syntax error risk
Generate bothComplexity, sync burden
Let LLM choose formatNon-deterministic, validation nightmare

Consequences

  • Translator MUST NOT emit MEL text (INV-005)
  • Deterministic Renderer is separate (optional, may be bundled)
  • PatchFragment becomes the canonical unit of semantic change

FDR-T002: Incremental-First Design

Decision

Every input is treated as an incremental fragment. "Initial generation" is just the first fragment set.

Context

Two mental models for domain authoring:

ModelApproach
Document-FirstGenerate complete domain from epic spec
Incremental-FirstBuild domain through successive fragments

Rationale

Incremental-first is more robust because:

  1. Smaller LLM context: Each fragment is bounded
  2. Progressive validation: Errors caught early
  3. Natural collaboration: Human + AI iterate together
  4. Resumable: Ambiguity pauses, resolution continues
  5. Auditable: Each fragment has trace

Document-first problems:

  • Massive context window needed
  • All-or-nothing failure mode
  • Hard to attribute errors
  • No natural pause points

Alternatives Rejected

AlternativeWhy Rejected
Document-first with chunkingChunks lose cross-reference context
Hybrid (detect epic vs incremental)Complexity, mode confusion

Consequences

  • PatchProgram exists for multi-fragment coordination
  • No "generate entire domain" API in v1
  • Each fragment has independent identity

FDR-T003: Untrusted Proposer Principle

Decision

Any model output is a proposal only. Translator never applies, approves, or executes.

Context

LLMs are powerful but unreliable. Two trust models:

ModelLLM Role
Trusted AgentLLM output is applied directly
Untrusted ProposerLLM proposes, Authority verifies

Rationale

Untrusted Proposer aligns with Manifesto philosophy:

  1. Separation of concerns: Proposer ≠ Approver ≠ Executor
  2. Auditability: Every proposal has trace
  3. Governance: Authority applies policy
  4. Safety: Bad proposals are rejected, not executed

Trusted Agent problems:

  • No governance checkpoint
  • LLM errors become system errors
  • No audit trail for rejections

Alternatives Rejected

AlternativeWhy Rejected
Trust high-confidence outputsConfidence is not reliability
Trust after N successful runsGaming, distribution shift

Consequences

  • Translator returns proposals, never side-effects
  • Authority is separate layer (World Protocol)
  • Confidence is signal, not authorization

FDR-T004: Ambiguity Return (Never Resolve)

Decision

Translator MUST NOT resolve ambiguity. It MUST return a structured AmbiguityReport.

Context

When input is ambiguous, two options:

OptionBehavior
A: Best-effortPick most likely interpretation
B: Return ambiguityAsk Actor to decide

Rationale

Returning ambiguity respects Actor autonomy:

  1. No silent assumptions: Actor knows there was uncertainty
  2. Explicit decision: Choice is recorded in trace
  3. Better UX: Actor can rephrase or clarify
  4. Governance-friendly: Decision attribution is clear

Best-effort problems:

  • Silent wrong interpretations
  • No accountability for choice
  • Hard to debug "why did it do X?"

Alternatives Rejected

AlternativeWhy Rejected
Best-effort with confidenceActor may not see low confidence
Ask for clarification inlineBreaks stateless API
Return both interpretations as fragmentsWhich one applies?

Consequences

  • AmbiguityReport is first-class result type
  • resolve() API exists for continuation
  • Trace records resolution decision

Data Model Decisions

FDR-T005: ExprNode for Expressions, JsonValue for Literals

Decision

  • Computed expressions (constraints, computed, availability): ExprNode (MEL call-only)
  • Default values: JsonValue (static literal)

Context

All values could use ExprNode, or all could use JsonValue, or split by purpose.

Optionconstraint.rulesetDefaultValue.value
All ExprNodeExprNodeExprNode
All JsonValueJsonValueJsonValue
Split by purposeExprNodeJsonValue

Rationale

Split by purpose is semantically correct:

  1. Constraints need evaluation: They reference $state.*, comparisons, etc.
  2. Defaults are static: They are literal values, no runtime resolution
  3. Determinism: Defaults MUST be deterministic; ExprNode allows non-determinism
  4. MEL alignment: MEL state initializers are literals, not expressions

All-ExprNode problems:

  • Temptation to use $system.now() in defaults (non-deterministic)
  • Overcomplication for simple literals
  • Validation burden

All-JsonValue problems:

  • Can't express constraint logic
  • Would need separate constraint type anyway

Alternatives Rejected

AlternativeWhy Rejected
All ExprNodeAllows non-deterministic defaults
Subset ExprNode for defaultsStill too permissive
String DSL for constraintsParsing burden, less type-safe

Consequences

  • setDefaultValue.value is JsonValue
  • addConstraint.rule is ExprNode
  • Clear validation: defaults can't reference state

FDR-T006: PatchFragment as Minimal Semantic Unit

Decision

PatchFragment represents a single semantic operation with identity, confidence, and evidence.

Context

What granularity for change proposals?

GranularityUnit
Fine (field-level)One field change per fragment
Medium (op-level)One logical operation per fragment
Coarse (batch-level)Multiple operations per fragment

Rationale

Op-level granularity balances:

  1. Atomicity: One operation = one decision
  2. Composability: Combine fragments into programs
  3. Auditability: Each op has its own trace
  4. Deduplication: Content-addressed ID enables dedupe

Fine-grained problems:

  • Too many fragments for simple changes
  • Cross-field operations split unnaturally

Coarse-grained problems:

  • Partial rejection is complex
  • Identity is unclear

Alternatives Rejected

AlternativeWhy Rejected
Field-level fragmentsOver-fragmentation
Batch fragmentsUnclear identity, partial reject
Nested fragmentsComplexity, ordering issues

Consequences

  • One PatchOp per PatchFragment
  • fragmentId is content-addressed (op only)
  • PatchProgram coordinates multiple fragments

FDR-T007: v1 Operator Set is Monotonic (No Destructive Ops)

Decision

v1 operators are additive/monotonic: addType, addField, setFieldType, setDefaultValue, addConstraint. No removeType, removeField, renameField, removeConstraint.

Context

Full schema evolution vs safe subset for v1.

ApproachOperators
Full evolutionadd, remove, rename, migrate
Monotonic onlyadd, set (no remove/rename)

Rationale

Monotonic is safer for v1:

  1. No orphan references: Removing types can orphan fields
  2. No data loss: Removing fields loses data
  3. No migration complexity: Rename needs data migration
  4. Simpler validation: Only check "does target exist?"

Destructive ops require:

  • Orphan detection
  • Migration planning
  • Data preservation strategy
  • Governance approval workflows

Alternatives Rejected

AlternativeWhy Rejected
Full operator setToo risky for v1
Soft-delete onlyStill needs orphan handling
Rename as add+copy+deprecatePossible in v2

Consequences

  • v1 is safe for iterative building
  • Destructive ops deferred to v2
  • "removeField" expressed as deprecation pattern

Pipeline Decisions

FDR-T008: Six-Stage Pipeline with Clear Determinism Boundaries

Decision

Pipeline has 6 stages with explicit determinism requirements:

  • Stages 0-2: MUST deterministic
  • Stage 3: SHOULD deterministic (cache)
  • Stages 4-5: MAY non-deterministic
  • Stage 6: MUST deterministic

Context

How to structure the translation pipeline?

DesignStagesDeterminism
Monolithic1Unclear
Two-phase2 (parse, generate)Unclear
Multi-stage6Explicit per stage

Rationale

Multi-stage with explicit determinism enables:

  1. Caching: Deterministic stages can cache
  2. Debugging: Trace shows exactly where non-determinism entered
  3. Testing: Deterministic stages are unit-testable
  4. Optimization: Each stage can be optimized independently

Monolithic problems:

  • Can't cache intermediate results
  • Hard to attribute non-determinism
  • All-or-nothing testing

Alternatives Rejected

AlternativeWhy Rejected
MonolithicNo caching, poor debugging
Two-phaseToo coarse
Dynamic stagesUnpredictable trace structure

Consequences

  • TranslationTrace has stage-specific traces
  • Fast-path can short-circuit to Stage 6
  • Each stage has its own trace type

FDR-T009: Fast Path with Candidates (Not Just Match/No-Match)

Decision

FastPathResult includes candidates[] array, not just boolean match.

typescript
type FastPathResult = {
  matched: boolean;
  best: FastPathCandidate | null;
  candidates: FastPathCandidate[];
};

Context

Fast-path matching can have multiple outcomes:

OutcomeOld ModelNew Model
No matchmatched=falsecandidates=[]
One matchmatched=truematched=true, candidates=[best]
Multiple low-confidence???matched=false, candidates=[...]

Rationale

Candidates array enables proper fastPathOnly handling:

  1. Distinguish "no patterns" from "uncertain patterns"
  2. fastPathOnly + candidates → intent ambiguity
  3. fastPathOnly + no candidates → FAST_PATH_MISS error

Boolean-only problems:

  • Can't distinguish failure modes
  • fastPathOnly always errors on non-match

Alternatives Rejected

AlternativeWhy Rejected
Boolean matched onlyCan't distinguish failure modes
Separate error typesComplex, still loses candidates
Always proceed to proposerDefeats purpose of fast-path only mode

Consequences

  • FastPathCandidate is structured type
  • fastPathOnly mode has clear semantics
  • Intent ambiguity can include pattern candidates

FDR-T010: Fragment Ordering is Applicator Responsibility

Decision

Translator declares fragment order as semantically insignificant. Applicator (Host/Authority) performs topological ordering.

Context

Who decides fragment application order?

OptionResponsibility
Translator ordersTranslator emits in dependency order
Applicator ordersTranslator emits unordered, applicator sorts

Rationale

Applicator ordering is cleaner because:

  1. Translator is frontend: Ordering is execution concern
  2. Deduplication: Order-independent IDs enable dedupe
  3. Merge: Multiple proposals can be merged then ordered
  4. Single responsibility: Applicator already knows schema

Translator ordering problems:

  • Duplicates ordering logic
  • Merge becomes complex
  • Different orderings for same semantic content

Alternatives Rejected

AlternativeWhy Rejected
Translator topological sortDuplicates applicator logic
Explicit order fieldExtra complexity, sync burden
Reject unordered batchesToo strict

Consequences

  • TranslationResult.fragments order is irrelevant
  • PatchProgram.dependencies is optional DAG
  • Applicator MUST implement topo-sort

Identity & Determinism Decisions

FDR-T011: Content-Addressed fragmentId (No Ordinal)

Decision

fragmentId = sha256(intentId + ':' + canonicalize(op))

No ordinal or sequence number in ID.

Context

How to generate fragment identity?

ApproachFormula
SequentialintentId + ordinal
Content-addressedintentId + hash(op)
HybridintentId + ordinal + hash(op)

Rationale

Content-addressed IDs enable:

  1. Deduplication: Same op = same ID, automatic dedupe
  2. Order independence: Proposer output order doesn't matter
  3. Cache stability: Same op cached regardless of batch
  4. Diff stability: Same semantic content = same ID

Ordinal problems:

  • Different order = different IDs for same ops
  • Proposer output order affects identity
  • Cache misses on reordering

Alternatives Rejected

AlternativeWhy Rejected
Sequential IDsOrder-dependent, cache-unfriendly
UUIDNo deduplication
Hybrid with ordinalOrdinal makes ID order-dependent

Consequences

  • Same op in different batches has same fragmentId
  • Deduplication is simple set membership
  • Proposer can output in any order

FDR-T012: RFC 8785 (JCS) for Canonical JSON

Decision

All JSON serialization for hashing MUST follow RFC 8785 (JSON Canonicalization Scheme).

Context

JSON serialization is not deterministic by default:

  • Object key order varies
  • Number formatting varies
  • Whitespace varies

Rationale

RFC 8785 is the standard solution:

  1. Well-specified: No ambiguity in implementation
  2. Library support: Implementations exist
  3. Interoperable: Cross-language consistency
  4. Complete: Handles edge cases (numbers, escaping)

Ad-hoc canonicalization problems:

  • Edge cases (NaN, Infinity, Unicode)
  • Implementation drift
  • No external validation

Alternatives Rejected

AlternativeWhy Rejected
Custom sort + stringifyEdge cases, no standard
Stable stringify librariesNot standardized
Binary format (CBOR)Overkill, less tooling

Consequences

  • Implementations SHOULD use RFC 8785 library
  • NaN/Infinity are reject (not valid JSON)
  • Cross-implementation hashes match

FDR-T013: Semantic Collection Ordering Before Hashing

Decision

Semantically unordered collections (union.members, object.fields) MUST be sorted before canonicalization.

Context

Some MEL constructs have collections where order doesn't affect semantics:

  • union { "a" | "b" } = union { "b" | "a" }
  • object { x: number, y: string } = object { y: string, x: number }

Rationale

Sorting ensures semantic equivalence = hash equivalence:

  1. Dedup correctness: Semantically equal ops dedupe correctly
  2. Cache hits: Reordered but equal ops hit cache
  3. Diff stability: Trivial reorderings don't show as changes

Without sorting:

  • Same type, different member order = different hash
  • False cache misses
  • Noisy diffs

Alternatives Rejected

AlternativeWhy Rejected
Preserve order, accept hash varianceDefeats content-addressing
Normalize at parse time onlyMisses runtime-constructed types
Hash sets instead of arraysComplex, non-standard

Consequences

  • canonicalizeTypeExpr() sorts members/fields
  • Hash is truly content-addressed
  • Implementation must sort before hash

Memory Integration Decisions

FDR-T014: Memory as Evidence, Not Truth

Decision

Translator treats memory as evidence (candidates + selection + trace), never as truth.

Context

Memory provides context from past Worlds. How to treat it?

Trust LevelBehavior
TruthUse memory content directly
EvidenceUse memory as input, verify separately

Rationale

Evidence model aligns with Manifesto philosophy:

  1. Authority verifies: verifyProof() checks evidence
  2. Trace records: Selection is auditable
  3. Confidence signals: Low confidence triggers policy ambiguity
  4. No silent assumptions: Memory doesn't bypass governance

Truth model problems:

  • No verification checkpoint
  • Memory errors become system errors
  • No audit of memory usage

Alternatives Rejected

AlternativeWhy Rejected
Trust high-confidence memoryConfidence ≠ correctness
Skip memory, always freshLoses valuable context
Memory in proposer prompt onlyStill needs verification

Consequences

  • INV-008: Memory ≠ Truth
  • MemoryTrace attached to TranslationTrace
  • Authority calls verifyProof(), not Store

FDR-T015: Translator Returns Trace, Actor Attaches to Proposal

Decision

Translator returns MemoryTrace in TranslationTrace. Actor is responsible for attaching to Proposal.

Context

Who creates and attaches memory evidence to Proposal?

OptionCreatorAttacher
Translator creates ProposalTranslatorTranslator
Translator returns traceTranslatorActor

Rationale

Actor attachment respects boundaries:

  1. Translator is frontend: Doesn't create Proposals
  2. Actor has Proposal context: Knows how to attach
  3. Separation of concerns: Translator ≠ Proposal factory
  4. Flexibility: Actor can modify before attach

Translator-creates-Proposal problems:

  • Translator becomes too coupled to World Protocol
  • Actor loses control over Proposal construction
  • Testing requires full Proposal infrastructure

Alternatives Rejected

AlternativeWhy Rejected
Translator creates ProposalCoupling, boundary violation
Actor re-selects memoryDuplicates work, inconsistency risk
No trace, Actor fetchesLoses selection context

Consequences

  • TranslationTrace.stages.memory.trace exists
  • Actor calls MemoryTraceUtils.attachToProposal()
  • Clear responsibility chain

FDR-T016: atWorldId is Required Context

Decision

TranslationContext.atWorldId is REQUIRED, not optional.

Context

Memory selection needs a World reference point. Should it be required or optional?

OptionatWorldId
RequiredMUST provide
OptionalDefaults to "latest" or null

Rationale

Required atWorldId ensures:

  1. Explicit anchoring: No ambiguity about reference point
  2. Memory scoping: Selection is scoped to World lineage
  3. Verification context: Authority knows what was anchored
  4. Reproducibility: Same atWorldId = same memory scope

Optional problems:

  • "Latest" is non-deterministic
  • Null disables memory silently
  • Ambiguous in multi-World scenarios

Alternatives Rejected

AlternativeWhy Rejected
Default to latestNon-deterministic
Optional with nullSilent memory disable
Derive from schemaSchema doesn't have World

Consequences

  • TranslationContext.atWorldId is required field
  • Memory selection always has anchor
  • INVALID_CONTEXT if atWorldId missing

Ambiguity & Resolution Decisions

FDR-T017: Candidates >= 2 Invariant for All Ambiguity

Decision

All AmbiguityReports MUST have candidates.length >= 2.

Context

Ambiguity with one candidate is not really ambiguity.

candidates.lengthMeaning
0Error (no options)
1Not ambiguity (one option)
>= 2True ambiguity (choice needed)

Rationale

Invariant ensures meaningful choice:

  1. UX clarity: Actor always has options
  2. Cancel option: Even low-confidence has apply/cancel
  3. No degenerate cases: One option = just return it
  4. Consistent resolve(): Always choosing between options

Single candidate problems:

  • Why ask Actor if only one option?
  • resolve() is meaningless
  • UX confusion

Alternatives Rejected

AlternativeWhy Rejected
Allow 1 candidateMeaningless ambiguity
Allow 0 candidatesThat's an error
Flexible countInconsistent resolve()

Consequences

  • policy ambiguity always has apply + cancel
  • intent ambiguity includes candidates + cancel
  • resolve() always has meaningful choice

FDR-T018: opt-cancel is Universal (All Ambiguity Kinds)

Decision

opt-cancel option is valid for all ambiguity kinds, not just policy.

Context

Should cancel/no-op be available in all ambiguity types?

Ambiguity Kindopt-cancel?
policyAlways
intent?
target/value/conflict?

Rationale

Universal cancel provides safe exit:

  1. Actor autonomy: Always can say "no"
  2. Rephrase opportunity: Cancel and retry with better input
  3. Consistent UX: Same pattern across ambiguity types
  4. No forced choice: Actor isn't trapped

Kind-specific cancel problems:

  • Inconsistent UX
  • Some ambiguities have no exit
  • Complex rules for when cancel exists

Alternatives Rejected

AlternativeWhy Rejected
policy-only cancelInconsistent, traps Actor
No cancel, must chooseNo safe exit
Cancel with penaltyOvercomplicates

Consequences

  • opt-cancel allowed in any ambiguity
  • resolve() with opt-cancel = fragments: []
  • No-op result is valid from any ambiguity

FDR-T019: resolve() is Stateless

Decision

resolve() accepts (report, resolution, context). Translator is stateless.

typescript
function resolve(
  report: AmbiguityReport,
  resolution: AmbiguityResolution,
  context: TranslationContext
): Promise<TranslationResult>;

Context

How to handle ambiguity resolution?

DesignState
Stateful sessionTranslator stores pending reports
StatelessCaller provides report + resolution

Rationale

Stateless design enables:

  1. Horizontal scaling: No shared state between instances
  2. Restart resilience: No session loss on restart
  3. Explicit data flow: All inputs visible
  4. Simpler testing: No session setup

Stateful problems:

  • Session management complexity
  • Scaling requires session affinity
  • Restart loses pending reports
  • TTL/eviction policies needed

Alternatives Rejected

AlternativeWhy Rejected
Session-basedScaling, restart, complexity
reportId lookupStill needs storage
Combined translate+resolveBreaks separation

Consequences

  • Caller stores AmbiguityReport
  • resolve() is pure function (mostly)
  • Context must match original translation

Configuration Decisions

FDR-T020: Two-Threshold Confidence Policy

Decision

Confidence policy uses two thresholds: autoAcceptThreshold and rejectThreshold.

typescript
type ConfidencePolicy = {
  autoAcceptThreshold: number;  // >= this → fragment
  rejectThreshold: number;      // < this → error
  // between → policy ambiguity
};

Context

How many thresholds for confidence-based decisions?

DesignThresholds
Binary1 (accept/reject)
Ternary2 (accept/ambiguity/reject)
Multi-zone3+

Rationale

Two thresholds with ambiguity middle zone:

  1. High confidence (>= 0.95): Auto-accept, no friction
  2. Medium confidence: Actor reviews via policy ambiguity
  3. Low confidence (< 0.30): Reject, don't waste Actor time

Binary problems:

  • No middle ground for review
  • Either too strict or too lenient

Multi-zone problems:

  • Complex rules
  • Unclear UX per zone

Alternatives Rejected

AlternativeWhy Rejected
Single thresholdNo review zone
Three+ thresholdsOvercomplicated
Per-operation thresholdsConfiguration explosion

Consequences

  • Simple mental model: auto/review/reject
  • Policy ambiguity handles uncertain cases
  • Thresholds are tunable per deployment

FDR-T021: fastPathOnly Uses Same Threshold

Decision

Fast-path match threshold uses confidencePolicy.autoAcceptThreshold, not a separate config.

Context

Should fast-path have its own threshold?

DesignThreshold
SharedUse confidencePolicy.autoAcceptThreshold
SeparatefastPathMatchThreshold

Rationale

Shared threshold simplifies v1:

  1. One mental model: High confidence = accept, everywhere
  2. Less config: Fewer knobs to tune
  3. Consistency: Same meaning across stages

Separate threshold considerations:

  • Fast-path patterns might warrant different bar
  • Can add in v1.1 if needed

Alternatives Rejected

AlternativeWhy Rejected
Separate thresholdPremature config complexity
Always accept fast-pathMay accept low-confidence matches
Never use thresholds for fast-pathDefeats confidence filtering

Consequences

  • Single confidence threshold for v1
  • MAY add fastPathMatchThreshold in future
  • Simple configuration to start

Summary Table

FDRDecisionKey Principle
T001Frontend OnlyNo MEL generation, structured output
T002Incremental-FirstBuild via successive fragments
T003Untrusted ProposerProposals only, no execution
T004Ambiguity ReturnNever resolve, return to Actor
T005ExprNode/JsonValue SplitExpressions vs literals
T006PatchFragment UnitOne op per fragment
T007Monotonic v1 OpsNo destructive operators
T008Six-Stage PipelineExplicit determinism boundaries
T009FastPath CandidatesDistinguish failure modes
T010Applicator OrdersTranslator doesn't order
T011Content-Addressed IDNo ordinal in fragmentId
T012RFC 8785 (JCS)Standard canonical JSON
T013Collection OrderingSort before hash
T014Memory as EvidenceNot truth
T015Actor Attaches TraceTranslator returns, Actor attaches
T016atWorldId RequiredExplicit anchoring
T017Candidates >= 2Always meaningful choice
T018Universal opt-cancelSafe exit from any ambiguity
T019Stateless resolve()No session state
T020Two-Threshold PolicyAuto/review/reject zones
T021Shared ThresholdSimple v1 config
T022World as Source of TruthContext derived from World
T023Human EscalationAgents must not auto-resolve
T024Actor Creates ProposalFragment → Proposal by Actor
T025TypeIndex DerivedDerived from schema, not provided
T026Memory Provides ContentFetch World content, not just refs
T027Memory as Few-ShotExamples in Proposer prompt
T028Memory Stage 5/6 OnlyStage 1/2 use pre-built config
T029Memory is OptionalGraceful degradation without Memory
T030Store BoundariesMemory selects, World stores fetch
T031EscalationTrace FieldExplicit escalation in TranslationTrace
T032deriveContext() APIRecommended, not required

From MEL Compiler FDR

MEL FDRRelevance
FDR-MEL-040 (Call-only IR)Translator targets this IR
FDR-MEL-024 (Canonical form)Normalization before IR

From World Protocol FDR

World FDRRelevance
FDR-W001 (Intent-level governance)Translator produces proposals
FDR-W002 (Proposal = Actor + Intent)Actor wraps Translator output

From Memory FDR

Memory FDRRelevance
M-1 (Memory is not truth)Translator treats as evidence
M-4 (Authority does not re-select)verifyProof only

From Host Contract FDR

Host FDRRelevance
FDR-H003 (No pause/resume)Ambiguity returns, doesn't pause
FDR-H006 (Intent identity)intentId in fragmentId

From Builder FDR

Builder FDRRelevance
FDR-B007 (Zod-first typing)Schema structure
FDR-B001 (No string paths)SemanticPath type

Manifesto Ecosystem Integration Decisions

FDR-T022: World as Single Source of Truth for Context

Decision

TranslationContext MUST be derived from World. Independent construction is a spec violation.

Context

How should Translator get schema and type information?

OptionSource
A: IndependentCaller provides schema/typeIndex directly
B: World-derivedCaller provides worldId, Translator derives rest
C: HybridCaller provides worldId, context is derived

Rationale

World-derived context ensures:

  1. Consistency: Schema matches World's current state
  2. Verifiability: Authority can verify context against World
  3. Single source of truth: No divergence between World and context
  4. Audit trail: Context is traceable to specific World

Independent construction problems:

  • Schema may be stale
  • TypeIndex may not match schema
  • Authority cannot verify context origin
  • Changes may conflict with current World state

Alternatives Rejected

AlternativeWhy Rejected
Trust caller-provided contextNo verification possible
Validate independentlyExpensive, may still miss drift
Ignore World, just use schemaLoses governance integration

Consequences

  • Context includes atWorldId as primary field
  • Schema and typeIndex derived from World
  • INVALID_CONTEXT error if inconsistent

FDR-T023: Human Escalation for Ambiguity

Decision

AmbiguityReport MUST be escalated to Human. Agents MUST NOT auto-resolve.

Context

When Translator returns ambiguity, who decides?

OptionResolver
A: Human alwaysEscalate to Human via UI
B: Agent decidesLLM picks best candidate
C: Policy-basedRules decide when to escalate

Rationale

Human escalation respects Actor autonomy:

  1. Explicit decision: Human makes the choice
  2. Audit trail: resolvedBy records Human actor
  3. No silent assumptions: Agent doesn't guess intent
  4. UX clarity: Human sees all options including cancel

Agent auto-resolve problems:

  • Compounds uncertainty (LLM choosing between LLM outputs)
  • No accountability for choice
  • Human may not know choice was made
  • Violates INV-004 (Ambiguity Return principle)

Alternatives Rejected

AlternativeWhy Rejected
Agent picks highest confidenceStill uncertain, no accountability
Only escalate low confidenceConfidence ≠ correctness
Auto-resolve if unambiguousDefeats purpose of ambiguity type

Consequences

  • ESC-001: Agents MUST NOT auto-resolve
  • UI MUST show all candidates
  • Resolution includes Human actor reference

FDR-T024: Fragment → Proposal Conversion by Actor

Decision

Actor (not Translator) converts fragments to World Protocol Proposal.

Context

Who creates the Proposal for World Protocol?

OptionCreator
A: TranslatorReturns Proposal directly
B: ActorWraps fragments in Proposal

Rationale

Actor creates Proposal because:

  1. Separation of concerns: Translator is frontend, not governance layer
  2. Actor context: Actor has identity, session, preferences
  3. Flexibility: Actor can modify before submission
  4. World Protocol alignment: Proposal.actor must be the Actor

Translator-creates-Proposal problems:

  • Translator would need Actor context
  • Couples Translator to World Protocol internals
  • Less flexibility for Actor

Alternatives Rejected

AlternativeWhy Rejected
Translator creates ProposalCoupling, boundary violation
Shared creationUnclear responsibility

Consequences

  • Translator returns fragments + trace
  • Actor wraps in IntentInstance → Proposal
  • Actor submits to Authority

FDR-T025: TypeIndex Derived, Not Provided

Decision

TypeIndex MUST be derived from Schema via deriveTypeIndex(). Independent provision is error.

Context

Should typeIndex be provided or derived?

OptionSource
A: ProvidedCaller passes typeIndex
B: DerivedTranslator derives from schema
C: HybridEither, with validation

Rationale

Derivation ensures consistency:

  1. No drift: TypeIndex always matches schema
  2. Single algorithm: deriveTypeIndex() is canonical
  3. Less error-prone: Caller can't provide wrong index
  4. Verifiable: Can always re-derive and compare

Provided typeIndex problems:

  • May be stale
  • May be incorrectly computed
  • Different implementations may differ
  • Inconsistency with schema

Alternatives Rejected

AlternativeWhy Rejected
Trust callerInconsistency risk
Accept but validateStill allows inconsistency
Cache independentlyDrift risk

Consequences

  • deriveTypeIndex(schema) is normative algorithm
  • TypeIndex is NOT a context input
  • Validation rejects inconsistent context

Memory Architecture Decisions

FDR-T026: Memory Provides Translation Examples (Not Just References)

Decision

Memory selection returns SelectedMemory[] (references), but Translator MUST fetch actual content from those Worlds to build MemoryContent for the Proposer.

Context

What should Memory provide to Translator?

OptionContent
A: References onlyJust WorldIds, Translator fetches nothing
B: References + ContentTranslator fetches World content
C: Pre-processed contextMemory returns ready-to-use examples

Rationale

References + Content (Option B) balances:

  1. Memory boundary: Memory selects, doesn't process
  2. Translator control: Translator decides what to extract
  3. Flexibility: Different Translators can extract differently
  4. Auditability: Clear separation of selection vs. usage

Why not references only?

  • Proposer (LLM) needs actual examples, not WorldIds
  • Fast-path needs actual patterns
  • References alone provide no value to LLM

Why not pre-processed?

  • Memory would need to understand Translator's needs
  • Coupling between Memory and Translator
  • Less flexible for different use cases

Alternatives Rejected

AlternativeWhy Rejected
References onlyUseless for LLM prompting
Pre-processed by MemoryCoupling, less flexible
LLM fetches directlySecurity, no trace

Consequences

  • Stage 4 calls both Selector and Store
  • MemoryContent type defined in Translator
  • Proposer receives actual examples

FDR-T027: Memory Feeds Proposer via Few-Shot Examples

Decision

MemoryContent is injected into Proposer (LLM) prompt as few-shot examples.

Context

How should Memory improve translation?

OptionMechanism
A: Fine-tuningTrain LLM on past translations
B: Few-shotInclude examples in prompt
C: RAGRetrieve and augment
D: EmbeddingsSemantic similarity lookup

Rationale

Few-shot (Option B) is practical for v1:

  1. No infrastructure: No vector DB or fine-tuning needed
  2. Immediate: Works with any LLM
  3. Auditable: Examples are in trace
  4. Adjustable: Easy to tune number of examples

Why not fine-tuning?

  • Requires training infrastructure
  • Per-domain models
  • Slow feedback loop

Why not pure RAG?

  • Need structured examples, not raw text
  • Translation needs input→output pairs

Alternatives Rejected

AlternativeWhy Rejected
Fine-tuningInfrastructure, slow iteration
Pure RAGUnstructured, not translation pairs
Embeddings onlyMissing input→output structure

Consequences

  • Proposer prompt includes past translations
  • Prompt size increases with examples
  • May need truncation strategy

FDR-T028: Memory Enhances Stage 5/6 Only (Not Stage 1/2)

Decision

Memory content is used ONLY in Stage 5 (Proposer) and Stage 6 (Assembly). Stage 1/2 use pre-built, offline-compiled resources.

Context

Original v1.1.0 stated Memory enhances Stages 1, 2, 5, 6. This conflicts with Stage 1/2 determinism requirements.

StageDeterminism RequirementMemory Usage
Stage 1MUST deterministic❓ Conflict
Stage 2MUST deterministic❓ Conflict
Stage 5MAY non-deterministic✅ OK
Stage 6MUST deterministic (semantic only)✅ OK

Rationale

Stage 1/2 MUST NOT use runtime Memory because:

  1. Determinism violation: Memory selection is non-deterministic (LLM-based)
  2. Offline capability: Stage 1/2 must work without network
  3. Pipeline ordering: Memory is fetched at Stage 4, after Stage 1/2

Solution: Pre-built resources

StageUsesSource
Stage 1 (Normalization)config.glossaryPre-built offline
Stage 2 (Fast-Path)config.fastPathPatternsPre-built offline
Stage 5 (Proposer)memoryContent.translationExamplesRuntime Memory
Stage 6 (Assembly)memoryContent.resolutionHistoryRuntime Memory

Historical data still benefits Stage 1/2, but via offline compilation, not runtime fetch.

Alternatives Rejected

AlternativeWhy Rejected
Split stages (1A/1B)Complexity, spec inflation
Make Stage 1/2 non-deterministicBreaks fundamental guarantees
Skip Memory for Stage 1/2 silentlyConfusing, implicit behavior

Consequences

  • §8.4 Memory Usage table clarified
  • Stage 1/2 use config, not runtime Memory
  • No pipeline ordering conflict

FDR-T029: Memory is Optional (Graceful Degradation)

Decision

If Memory (Selector/Store) is not configured, Translator MUST still function with degraded quality.

Context

Should Memory be required or optional?

OptionBehavior
A: RequiredError if no Memory
B: OptionalGraceful degradation

Rationale

Optional with degradation is more practical:

  1. Bootstrap: New domains have no history
  2. Simplicity: Simple deployments work
  3. Testing: Easier to test without Memory
  4. Incremental: Add Memory later

Required Memory problems:

  • Cold start impossible
  • Complex test setup
  • Barrier to adoption

Alternatives Rejected

AlternativeWhy Rejected
Required MemoryCold start problem
Synthetic MemoryComplexity, fake data

Consequences

  • Stage 4 can return empty MemoryContent
  • Proposer works without examples (lower quality)
  • Fast-path starts empty, learns over time

FDR-T030: Store Boundaries (Memory Selects, World Stores Fetch)

Decision

Memory package (@manifesto-ai/memory) handles selection only. World Protocol stores handle content fetching.

Context

Memory selection returns WorldIds. Who fetches actual World content?

OptionFetcher
A: Memory storeMemory package provides content
B: World storesTranslator uses World Protocol stores

Rationale

World stores for content (Option B) maintains package boundaries:

  1. Single responsibility: Memory selects, World stores persist
  2. No duplication: World content in one place
  3. Clear dependency: Translator depends on both packages explicitly
  4. Verification: World Protocol handles integrity verification

Memory-fetches-content problems:

  • Memory would need World content access
  • Duplication of World data in Memory
  • Unclear responsibility for integrity

Alternatives Rejected

AlternativeWhy Rejected
Memory stores World contentDuplication, boundary violation
Translator fetches directlyNo explicit dependency declaration

Consequences

  • TranslatorConfig requires stores (World Protocol)
  • Memory Selector returns refs only
  • Stage 4 uses both Memory and World stores

FDR-T031: EscalationTrace in TranslationTrace

Decision

TranslationTrace has explicit escalation?: EscalationTrace field. AmbiguityResolution includes escalation metadata when resolved by Human.

Context

ESC-005 requires "All Human escalations MUST be recorded in trace". Where does it go?

OptionLocation
A: Inside ambiguityResolutionNested in existing field
B: Separate escalation fieldTop-level in TranslationTrace

Rationale

Separate field (Option B) is cleaner:

  1. Explicit: Escalation is first-class trace data
  2. Queryable: Easy to find escalations in traces
  3. Complete: Has all metadata (escalatedAt, escalatedTo, duration)
  4. Audit-friendly: Clear separation of concerns

Nested inside ambiguityResolution problems:

  • Type gets complex
  • Escalation metadata mixed with resolution choice
  • Hard to query traces for escalations

Alternatives Rejected

AlternativeWhy Rejected
Nested in ambiguityResolutionType complexity, hard to query
Array of escalationsOverkill for single Human interaction

Consequences

  • TranslationTrace.escalation is optional field
  • AmbiguityResolution.escalation provides input metadata
  • Translator populates trace from resolution

Decision

deriveContext(atWorldId, actor, stores) is a recommended (not required) API for constructing TranslationContext.

Context

How should callers construct World-derived context?

OptionApproach
A: Manual constructionCaller builds context manually
B: Required APICaller MUST use deriveContext()
C: Recommended APIderiveContext() provided, manual allowed

Rationale

Recommended API (Option C) balances safety and flexibility:

  1. Easy correct path: deriveContext() does the right thing
  2. Flexibility: Testing/edge cases can construct manually
  3. Verification: contextVerification config provides safety net
  4. Documentation: API documents the correct pattern

Required API problems:

  • Testing becomes harder
  • Some edge cases need manual construction
  • Over-constrains implementations

Alternatives Rejected

AlternativeWhy Rejected
Required deriveContext()Too restrictive
No helper, manual onlyEasy to make mistakes
Constructor patternNot functional style

Consequences

  • deriveContext() is in Public API (§9.5)
  • Manual construction still allowed
  • contextVerification provides safety net

End of Foundational Design Rationale v1.1.1