diff --git a/README.md b/README.md index 14a3259..d273960 100644 --- a/README.md +++ b/README.md @@ -40,10 +40,9 @@ for the LLM-free hot path. See [Interlingua Standard](./docs/interlingua-standard.md) for the shared meaning-packet contract Weksa clients should target. -See [Verse Service Demotion](./docs/verse-service-demotion.md) for the current -service-status receipt: Weksa is not a daemon or Verse service yet, but the note -names the CultCache witnesses, CultMesh provider surfaces, Eve projections, and -commands expected if it later becomes one. +See [Verse Service Contract](./docs/verse-service-contract.md) for the daemon +contract: Weksa owns typed conversational intent, pronunciation plans, utterance +handoffs, and the Eve/CultMesh surfaces that make those documents inspectable. See [Flavored English Lowering](./docs/flavored-english-lowering.md) for the first lowering target: interlingua projected through agent state into English @@ -57,9 +56,11 @@ pronunciation coverage. ## Implementation Status -No runtime language has been selected yet. The first committed artifact is the -persistent state spine: map, scratch, schemas, docs, and examples. The engine -implementation should be chosen after the pipeline and data ownership are clear. +The first committed artifact is the persistent state spine: map, scratch, +schemas, docs, examples, and a read-only provider advertisement fixture. The +daemon runtime still needs implementation, but its authority is no longer +ambiguous: writing and agent state enter Weksa as intent pressure, and typed +utterance documents leave for AquaSynth. [Eusocial Interbeing / Zyphos](./settings/eusocial-interbeing/README.md) is the current higher-priority setting target. [Rust to Dust](./settings/rust-to-dust/README.md) diff --git a/docs/architecture.md b/docs/architecture.md index 9d74b2f..f7d29d5 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,22 +1,23 @@ # Architecture -Weksa is currently a state spine and a pipeline map, not an implementation. +Weksa is the language-intent daemon surface: currently a state spine, pipeline +map, fixtures, and service contract waiting for its runtime loop. -It is also not currently an active Verse service. See -[Verse Service Demotion](./verse-service-demotion.md) for the current -service-status receipt and the future CultCache/CultMesh/Eve expectations if -Weksa grows into a daemon. +See [Verse Service Contract](./verse-service-contract.md) for the +CultCache/CultMesh/Eve authority map. ## Objective Build a procedural alien-language engine whose outputs are grounded in -worldview, semantics, grammar, phonology, morphology, and history. +worldview, semantics, grammar, phonology, morphology, and history. As a daemon, +Weksa also turns writing plus agent state into typed conversational intent, then +lowers that intent into pronunciation and utterance handoff documents. ## Current Mechanism -There is no runtime mechanism yet. The repo contains persistent state surfaces -that define the intended data flow and the ownership boundaries future code must -respect. +There is no long-running runtime loop yet. The repo contains persistent state +surfaces and a provider advertisement fixture that define the intended data flow +and the ownership boundaries future code must respect. The first shared contract is the [Interlingua Standard](./interlingua-standard.md): clients submit interlingua packets before any language project projects them @@ -31,13 +32,17 @@ through its ontology. - Phonology owns sound legality. - Diachrony owns plausible irregularity. - Renderer owns output, not interpretation. +- Weksa owns conversational intent and utterance lowering. +- AquaSynth owns learned utterance embeddings, synth controls, Faust + compilation, and audio output. ## Intended Change Future implementation should turn the pipeline in `state/map.yaml` into a small, -inspectable machine. The first executable slice should probably validate a tiny +inspectable daemon. The first executable slice should validate a tiny interlingua packet, read a tiny language project definition, render glossed -output, and produce a trace explaining which stage made each decision. +output, lower an accepted intent into a pronunciation/utterance handoff, and +produce a trace explaining which stage made each decision. Runtime should be fast and deterministic. Model-assisted English decomposition belongs in authoring tools or offline import flows, not in the required hot path. @@ -45,8 +50,8 @@ See [Runtime and Authoring Split](./runtime-authoring-split.md). ## Cut Line -Do not add a runtime language, service, database, queue, plugin system, prompt -framework, or adapter until the pipeline stage needing it is known. +Do not add a database, queue, plugin system, prompt framework, or adapter until +the pipeline stage needing it is known. Do not hard-code Rust to Dust, its aliens, or its aesthetic-honor ontology into the generic engine. diff --git a/docs/fixtures/weksa-provider-advertisement.json b/docs/fixtures/weksa-provider-advertisement.json new file mode 100644 index 0000000..26a05bc --- /dev/null +++ b/docs/fixtures/weksa-provider-advertisement.json @@ -0,0 +1,190 @@ +{ + "schema": "gamecult.eve.provider_advertisement.v1", + "providerId": "weksa.intent.service", + "title": "Weksa Intent Service", + "description": "Weksa converts writing, interlingua, and agent state into typed conversational intent, pronunciation plans, and utterance handoff documents for AquaSynth and other consumers.", + "mode": "fixture-read-only", + "serviceVerse": { + "id": "verse.weksa.service.v1", + "cultMeshKey": "weksa.service/provider-advertisement", + "authority": "Weksa daemon identity, schema catalog, and provider publication", + "owns": [ + "typed conversational intent", + "pronunciation plans", + "utterance handoff documents", + "lowering traces", + "language-project and flavor-profile state" + ], + "doesNotOwn": [ + "AquaSynth learned embeddings", + "Faust compilation", + "rendered audio", + "Persona canonical state" + ] + }, + "nestedVerses": [ + { + "id": "weksa.intent", + "kind": "intent", + "cultMeshKey": "weksa.intent/current", + "authority": "Weksa conversational intent compiler", + "schemas": [ + "weksa.conversational_intent.v0" + ] + }, + { + "id": "weksa.pronunciation", + "kind": "pronunciation", + "cultMeshKey": "weksa.pronunciation/current", + "authority": "Weksa pronunciation lowering", + "schemas": [ + "weksa.pronunciation_plan.v0" + ] + }, + { + "id": "weksa.utterance", + "kind": "utterance", + "cultMeshKey": "weksa.utterance/handoffs", + "authority": "Weksa utterance handoff export", + "schemas": [ + "weksa.utterance_handoff.v0", + "weksa.utterance_embedding_handoff.v0.1" + ] + }, + { + "id": "weksa.operator", + "kind": "operator", + "cultMeshKey": "weksa.operator/status", + "authority": "Weksa daemon runtime", + "schemas": [ + "weksa.operator_state.v0", + "gamecult.eve.surface.v1" + ] + } + ], + "schemaWitnessFamilies": [ + { + "family": "intent", + "namespace": "weksa.intent.*", + "witnesses": [ + "weksa.conversational_intent.v0" + ], + "durableShape": ".weksa/intent/{intentId}.cc" + }, + { + "family": "pronunciation", + "namespace": "weksa.pronunciation.*", + "witnesses": [ + "weksa.pronunciation_plan.v0" + ], + "durableShape": ".weksa/pronunciation/{utteranceId}.cc" + }, + { + "family": "utterance", + "namespace": "weksa.utterance.*", + "witnesses": [ + "weksa.utterance_handoff.v0", + "weksa.utterance_embedding_handoff.v0.1" + ], + "durableShape": ".weksa/handoff/{utteranceId}.cc" + }, + { + "family": "trace", + "namespace": "weksa.trace.*", + "witnesses": [ + "weksa.lowering_trace.v0" + ], + "durableShape": ".weksa/traces/{traceId}.cc" + }, + { + "family": "eve", + "namespace": "weksa.eve.*", + "witnesses": [ + "gamecult.eve.provider_advertisement.v1", + "gamecult.eve.surface.v1" + ], + "durableShape": ".weksa/eve-surfaces.cc" + } + ], + "cultMeshSurfaceKeys": [ + { + "id": "weksa.eve.intent_review.v0", + "documentSchema": "gamecult.eve.surface.v1", + "cultMeshKey": "weksa.eve.surface.intent-review", + "binds": [ + "weksa.intent.*", + "weksa.trace.*" + ], + "status": "expected-surface" + }, + { + "id": "weksa.eve.pronunciation_trace.v0", + "documentSchema": "gamecult.eve.surface.v1", + "cultMeshKey": "weksa.eve.surface.pronunciation-trace", + "binds": [ + "weksa.pronunciation.*", + "weksa.trace.*" + ], + "status": "expected-surface" + }, + { + "id": "weksa.eve.utterance_handoff.v0", + "documentSchema": "gamecult.eve.surface.v1", + "cultMeshKey": "weksa.eve.surface.utterance-handoff", + "binds": [ + "weksa.utterance.*", + "aquasynth.speech.*" + ], + "status": "expected-surface" + } + ], + "commandBoundaries": [ + { + "id": "weksa.command.intent.create", + "owner": "Weksa", + "acceptedByFixture": false, + "allowedInputs": [ + "writing", + "interlingua packet", + "Persona/agent state projection" + ], + "emits": [ + "weksa.conversational_intent.v0", + "weksa.lowering_trace.v0" + ] + }, + { + "id": "weksa.command.utterance.lower", + "owner": "Weksa", + "acceptedByFixture": false, + "allowedInputs": [ + "accepted conversational intent", + "language project", + "speaker state" + ], + "emits": [ + "weksa.pronunciation_plan.v0", + "weksa.utterance_handoff.v0" + ] + }, + { + "id": "weksa.command.handoff.export", + "owner": "Weksa", + "acceptedByFixture": false, + "emits": [ + "weksa.utterance_embedding_handoff.v0.1" + ], + "forbiddenTargets": [ + "Faust compilation", + "audio rendering", + "AquaSynth synth driver truth" + ] + } + ], + "loweringRules": [ + "Weksa owns conversational intent and utterance lowering.", + "AquaSynth owns learned embeddings, synth controls, Faust compilation, and audio output.", + "Eve surfaces submit commands and inspect witnesses; they do not own intent truth.", + "Fixture exports are discovery metadata until the daemon loop commits typed witnesses." + ] +} diff --git a/docs/roadmap.md b/docs/roadmap.md index 1a737be..e5369a8 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -22,6 +22,10 @@ IPA. - Add one toy utterance embedding handoff fixture, then replace hand-authored values with the AquaSynth-owned learned encoder. +- Add a daemon loop that commits conversational intent, pronunciation plans, and + utterance handoffs as typed CultCache witnesses. +- Publish the provider advertisement and first Eve operator/intent-review + surfaces through CultMesh for Odin discovery. - Preserve the first lowering proof as fixture data under `examples/english-lowering/`. - Preserve the Airawa first-contact slice as a hand-authored language-project @@ -31,9 +35,8 @@ - Render glossed output through grammar, morphology, phonology, and diachrony. - Emit a trace explaining which stage made each decision. - Keep runtime LLM-free; model use belongs in authoring and critique. -- Do not add Verse service migration, provider advertisements, or Eve lowering - until Weksa has an actual daemon/compiler-service owner. Preserve the future - expectations in [Verse Service Demotion](./verse-service-demotion.md). +- Keep CLI tools, fixtures, daemon jobs, and Eve commands on the same commit and + derivation paths so Weksa does not grow split-brained intent truth. ## Later diff --git a/docs/verse-service-contract.md b/docs/verse-service-contract.md new file mode 100644 index 0000000..28e0b86 --- /dev/null +++ b/docs/verse-service-contract.md @@ -0,0 +1,90 @@ +# Weksa Verse Service Contract + +Weksa is the language-intent daemon. It turns writing, dialogue pressure, and +agent state into typed conversational intent, then lowers that intent into +utterance documents for speech, text, and synthesis consumers. + +## Authority + +Owner: Weksa. + +Inputs: + +- writing or dialogue drafts +- `weksa.interlingua_packet.v0` meaning packets +- `gamecult.persona_state.v0` or compatible agent-state projections +- language-project state, pronunciation rules, and flavor profiles +- optional speaker, scene, and discourse constraints + +Outputs: + +- `weksa.conversational_intent.v0` +- `weksa.pronunciation_plan.v0` +- `weksa.utterance_handoff.v0` +- `weksa.utterance_embedding_handoff.v0.1` +- Eve/CultUI surfaces for intent review, pronunciation inspection, and handoff + traces + +Weksa owns conversational intent and utterance lowering. AquaSynth owns learned +phonetic realization, packed utterance embeddings, synth-driver controls, Faust +compilation, live instrument handles, and rendered audio. + +## CultCache Witnesses + +- `.weksa/provider-advertisement.cc`: read-only provider advertisement witness. +- `.weksa/intent/{intentId}.cc`: conversational intent documents. +- `.weksa/pronunciation/{utteranceId}.cc`: pronunciation plans and phonetic + event sequences. +- `.weksa/handoff/{utteranceId}.cc`: utterance handoffs and embedding handoff + requests for AquaSynth. +- `.weksa/traces/{traceId}.cc`: lowering traces naming the stage that made each + decision. +- `.weksa/projects/{projectId}.cc`: language-project and flavor-profile state. + +Early exporters may publish fixtures before a daemon loop exists, but the +witness names are not decorative. These are the state surfaces the daemon must +commit when the runtime lands. + +## CultMesh Verses + +- `weksa.service`: service identity, schema catalog, version, and health. +- `weksa.intent`: conversational intent documents and review queues. +- `weksa.language_project`: language-project state, flavor profiles, and + pronunciation rules. +- `weksa.pronunciation`: phonetic plans, IPA spans, prosody, and trace + evidence. +- `weksa.utterance`: utterance handoff documents, packed embedding requests, + and AquaSynth binding receipts. +- `weksa.operator`: daemon status, queue pressure, schema drift, and witness + freshness. + +## Eve Surfaces + +- `weksa.eve.intent_review.v0`: inspect typed conversational intent before it + becomes an utterance. +- `weksa.eve.pronunciation_trace.v0`: inspect pronunciation and IPA/prosody + lowering. +- `weksa.eve.utterance_handoff.v0`: inspect handoff packets, embedding request + status, and AquaSynth receipt links. +- `weksa.eve.operator.v0`: compact daemon state, queues, schema versions, and + witness freshness. + +## Commands + +- `intent.create`: convert writing or interlingua into typed conversational + intent. +- `intent.review`: accept, reject, or revise intent through the same commit + path used by automated jobs. +- `utterance.lower`: lower accepted intent and agent state into pronunciation + and utterance handoff documents. +- `handoff.export`: emit typed `.cc` witnesses for AquaSynth consumption. +- `provider.advertise`: publish `gamecult.eve.provider_advertisement.v1`. + +## Forbidden Writers + +- Text renderers do not own meaning. +- AquaSynth does not own conversational intent. +- Eve lowerings do not own Weksa state. +- Fixture emitters cannot become an alternate runtime truth. +- Agent transcript memory cannot silently override typed Persona or intent + documents. diff --git a/docs/verse-service-demotion.md b/docs/verse-service-demotion.md deleted file mode 100644 index 9125e1b..0000000 --- a/docs/verse-service-demotion.md +++ /dev/null @@ -1,66 +0,0 @@ -# Verse Service Demotion - -Weksa is not currently an active Verse service. - -## Verification - -The current repo body is a state spine, documentation set, examples, and one -fixture emitter: - -- `state/map.yaml` owns the slow project map. -- `schemas/` owns human-facing contract receipts. -- `examples/` owns fixture evidence. -- `tools/emit_tiny_panphon_handoffs.py` emits bounded AquaSynth handoff - fixtures. - -There is no daemon, server loop, package entry point, service supervisor, -CultMesh provider, CultNet transport, Eve projection runtime, or executable -compiler service. The architecture docs explicitly keep runtime language, -service scaffolding, storage, queues, and plugin systems out of scope until a -pipeline stage earns them. - -## Demotion - -No Verse service migration is due while Weksa remains a tool/library-shaped -workspace. Do not add a provider advertisement fixture, export command, or -service contract merely to satisfy the shape of future infrastructure. That -would make a dashboard for a machine that does not exist yet, which is how the -altar gets sticky. - -The current executable surface remains a bounded fixture tool, not a daemon: - -```powershell -python tools/emit_tiny_panphon_handoffs.py -``` - -## Future Service Expectations - -If Weksa becomes a language/compiler service, the first service pass should -publish a small Verse contract that names only real owned surfaces: - -- CultCache witnesses: - - project/compiler state `.cc` - - language-project state `.cc` - - interlingua packet witness `.cc` - - lowering/render trace witness `.cc` - - pronunciation or utterance-handoff witness `.cc` when that pipeline is - active -- CultMesh provider surfaces: - - service identity and version - - accepted schema versions - - available language projects - - compile/render job status - - recent witness exports -- Eve surfaces: - - compact TUI status for agent inspection - - GUI composition for language projects, schemas, traces, and witness review -- Commands: - - validate interlingua packet - - compile/load language project - - render packet through a selected language project - - export typed witness - - advertise provider contract - -Those commands must delegate to the same commit or derivation paths used by any -CLI or library API. Manual actions, programmatic jobs, fixture exports, and -future Eve controls must not become separate truths. diff --git a/tools/export-provider-advertisement.mjs b/tools/export-provider-advertisement.mjs new file mode 100644 index 0000000..e0fa56c --- /dev/null +++ b/tools/export-provider-advertisement.mjs @@ -0,0 +1,165 @@ +#!/usr/bin/env node +import { mkdir, writeFile } from "node:fs/promises"; +import path from "node:path"; + +const document = { + schema: "gamecult.eve.provider_advertisement.v1", + providerId: "weksa.intent.service", + title: "Weksa Intent Service", + description: + "Weksa converts writing, interlingua, and agent state into typed conversational intent, pronunciation plans, and utterance handoff documents for AquaSynth and other consumers.", + mode: "fixture-read-only", + serviceVerse: { + id: "verse.weksa.service.v1", + cultMeshKey: "weksa.service/provider-advertisement", + authority: "Weksa daemon identity, schema catalog, and provider publication", + owns: [ + "typed conversational intent", + "pronunciation plans", + "utterance handoff documents", + "lowering traces", + "language-project and flavor-profile state", + ], + doesNotOwn: [ + "AquaSynth learned embeddings", + "Faust compilation", + "rendered audio", + "Persona canonical state", + ], + }, + nestedVerses: [ + { + id: "weksa.intent", + kind: "intent", + cultMeshKey: "weksa.intent/current", + authority: "Weksa conversational intent compiler", + schemas: ["weksa.conversational_intent.v0"], + }, + { + id: "weksa.pronunciation", + kind: "pronunciation", + cultMeshKey: "weksa.pronunciation/current", + authority: "Weksa pronunciation lowering", + schemas: ["weksa.pronunciation_plan.v0"], + }, + { + id: "weksa.utterance", + kind: "utterance", + cultMeshKey: "weksa.utterance/handoffs", + authority: "Weksa utterance handoff export", + schemas: ["weksa.utterance_handoff.v0", "weksa.utterance_embedding_handoff.v0.1"], + }, + { + id: "weksa.operator", + kind: "operator", + cultMeshKey: "weksa.operator/status", + authority: "Weksa daemon runtime", + schemas: ["weksa.operator_state.v0", "gamecult.eve.surface.v1"], + }, + ], + schemaWitnessFamilies: [ + { + family: "intent", + namespace: "weksa.intent.*", + witnesses: ["weksa.conversational_intent.v0"], + durableShape: ".weksa/intent/{intentId}.cc", + }, + { + family: "pronunciation", + namespace: "weksa.pronunciation.*", + witnesses: ["weksa.pronunciation_plan.v0"], + durableShape: ".weksa/pronunciation/{utteranceId}.cc", + }, + { + family: "utterance", + namespace: "weksa.utterance.*", + witnesses: ["weksa.utterance_handoff.v0", "weksa.utterance_embedding_handoff.v0.1"], + durableShape: ".weksa/handoff/{utteranceId}.cc", + }, + { + family: "trace", + namespace: "weksa.trace.*", + witnesses: ["weksa.lowering_trace.v0"], + durableShape: ".weksa/traces/{traceId}.cc", + }, + { + family: "eve", + namespace: "weksa.eve.*", + witnesses: ["gamecult.eve.provider_advertisement.v1", "gamecult.eve.surface.v1"], + durableShape: ".weksa/eve-surfaces.cc", + }, + ], + cultMeshSurfaceKeys: [ + { + id: "weksa.eve.intent_review.v0", + documentSchema: "gamecult.eve.surface.v1", + cultMeshKey: "weksa.eve.surface.intent-review", + binds: ["weksa.intent.*", "weksa.trace.*"], + status: "expected-surface", + }, + { + id: "weksa.eve.pronunciation_trace.v0", + documentSchema: "gamecult.eve.surface.v1", + cultMeshKey: "weksa.eve.surface.pronunciation-trace", + binds: ["weksa.pronunciation.*", "weksa.trace.*"], + status: "expected-surface", + }, + { + id: "weksa.eve.utterance_handoff.v0", + documentSchema: "gamecult.eve.surface.v1", + cultMeshKey: "weksa.eve.surface.utterance-handoff", + binds: ["weksa.utterance.*", "aquasynth.speech.*"], + status: "expected-surface", + }, + ], + commandBoundaries: [ + { + id: "weksa.command.intent.create", + owner: "Weksa", + acceptedByFixture: false, + allowedInputs: ["writing", "interlingua packet", "Persona/agent state projection"], + emits: ["weksa.conversational_intent.v0", "weksa.lowering_trace.v0"], + }, + { + id: "weksa.command.utterance.lower", + owner: "Weksa", + acceptedByFixture: false, + allowedInputs: ["accepted conversational intent", "language project", "speaker state"], + emits: ["weksa.pronunciation_plan.v0", "weksa.utterance_handoff.v0"], + }, + { + id: "weksa.command.handoff.export", + owner: "Weksa", + acceptedByFixture: false, + emits: ["weksa.utterance_embedding_handoff.v0.1"], + forbiddenTargets: ["Faust compilation", "audio rendering", "AquaSynth synth driver truth"], + }, + ], + loweringRules: [ + "Weksa owns conversational intent and utterance lowering.", + "AquaSynth owns learned embeddings, synth controls, Faust compilation, and audio output.", + "Eve surfaces submit commands and inspect witnesses; they do not own intent truth.", + "Fixture exports are discovery metadata until the daemon loop commits typed witnesses.", + ], +}; + +async function main() { + const args = process.argv.slice(2); + const outIndex = args.indexOf("--out"); + const outputPath = outIndex >= 0 ? args[outIndex + 1] : undefined; + const json = `${JSON.stringify(document, null, 2)}\n`; + + if (outputPath) { + const resolved = path.resolve(process.cwd(), outputPath); + await mkdir(path.dirname(resolved), { recursive: true }); + await writeFile(resolved, json, "utf8"); + return; + } + + process.stdout.write(json); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +});