OAKEN CORE
Generated

Software map

The components of Oaken Core, the layers they sit in, what calls what, and which pieces exist yet.

1

Status

25 components in 8 layers: 25 built, 0 partial, 0 planned.

Status Meaning
Built Implemented and checked in the repository.
Partial Exists, but only part of what is planned.
Planned Designed; no code yet.

Generated from docs/softmap.toml by docs/tools/softmap.py, which refuses to build if the data breaks the layering rules or disagrees with the repository. Edit the data in the same change that builds or alters a component.

2

Map

Click a component to draw its relationships. Each separate piece of software is its own framed stack, with its layers top to bottom. The border shows status; a red dot marks components that handle untrusted input.

Composition rootDoorsOperationsIntake pipelinePluginsRuntimeStateFoundationOaken Core (one asyncio process)Core daemonbuiltCLIbuiltLocal APIbuiltHandles untrusted inputConsolebuiltHandles untrusted inputOperation registrybuiltIntakebuiltHandles untrusted inputTriagersbuiltHandles untrusted inputModel routerbuiltHandles untrusted inputPlugin hostbuiltPlugin base classesbuiltPlugin contractsbuiltCatalog and extensionsbuiltFormattersbuiltProvidersbuiltHandles untrusted inputItems ingestorbuiltJobsbuiltQueuesbuiltSchedulerbuiltAgentsbuiltHandles untrusted inputLabelsbuiltChange logbuiltEvents and logbuiltDatabasebuiltSettingsbuiltUntrusted textbuilt
calls (selected component calls this)called bynotifies (event or callback, upward)notified by
Select a component on the map.
3

Conventions

4

Components

Oaken Core (one asyncio process)

Composition root

Core daemonBuiltsrc/oaken_core/daemon · map

Builds everything in dependency order, starts it as units, stops it in reverse, and rebuilds it on reload. The only place that knows all the parts.

Called by
none
Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
CoreclassThe composition root: settings, host and store, labels, queues, jobs, agents, scheduler, runner, services, registry, client, API and console.
External none
Notes
  • A reload rebuilds Core in the same process and keeps the API and console ports. It does not re-import Python modules: a code change needs a restart.

Doors

The oaken command. Built from the operation registry at plugin load, so a plugin's commands appear when it loads. Talks to the running core, or runs in process for the commands that need no core.

Called by
none
Notifies (event or callback, upward)
none
Notified by
none
Inherits
ClassBasesWhat it is
ApiClientABCThe thin-client contract. An implementation decides *how* it reaches core (HTTP to the
CliErrorExceptionAny failure the CLI wants to report with a chosen exit code and a clean message (no
CoreUnavailableCliErrorCore could not be reached: no runtime file, a dead pid, or a refused connection. Exit 3 with
AgentClient_BaseThe agent job protocol, with an *agent* token. It can reach nothing but `/v1/agent/`.
HttpApiClient_Base, ApiClientTalks to the running daemon over loopback HTTP.
InProcessApiClientApiClientDrive `CoreClient` directly, as the CLI caller class.
External none
Notes
  • oaken plugins lists what could be added and reads each plugin's source without importing it.
Local APIBuilt untrusted inputsrc/oaken_core/api · map

HTTP and server-sent events on 127.0.0.1 with token auth. Routes are generated from the operation registry; a guard checks Host, Origin, content type, token, rate and size before any route runs. Also serves the MCP doors.

Called by
CLI Core daemon
Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
ApiclassThe ASGI application: generated operation routes, events, the agent job routes and the MCP mount.
SurfacedataclassA path prefix with its own token check, size and concurrency limits and caller class.
Inherits
ClassBasesWhat it is
CallRequest_Body
_BodyBaseModel
External none
Notes
  • Binds to loopback only; configuration cannot say otherwise.
ConsoleBuilt untrusted inputsrc/oaken_core/console · map

The local web console: settings and flow, never content. It draws every plugin's row, settings modal and New instance dialog from the plugin's declared UI, and calls the same operations the CLI does.

Called by
Core daemon
Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
ConsoleclassThe Starlette app and its guard: pages for the pipeline, stages, schedules, labels, plugins and capabilities.
FielddataclassOne setting as a form draws it, made from the config schema and overridden by the plugin's spec.
External none
Notes
  • Content views belong to product UIs, which run their own server against the API.

Operations

Operation registryBuiltsrc/oaken_core/operations · map

Every action core offers is one operation: typed input and output, a permission class, an MCP mode and an optional preview. The CLI, API, MCP and console are generated from it. A change is a proposal until a person confirms it.

Types
NameKindMeaning
OperationdataclassName, summary, permission, input and output models, mcp mode, preview, group.
OperationRegistryclassCore's operations plus the ones loaded plugins offer.
CoreClientclassCalls an operation as a caller: validates, gates mutations, audits.
ServicesdataclassWhat an operation may reach: the host, jobs, queues, scheduler, labels and more.
Inherits
ClassBasesWhat it is
AgentGrantInAgentRef
AgentRefBaseModel
CompleteInJobRef
FailInJobRef
JobRefBaseModel
ScheduleEditInScheduleRef
ScheduleRefBaseModel
SecretRefBaseModel
SecretSetInSecretRef
External none
Notes
  • pluginhost notifies this layer with the operations a plugin offers; the registry takes them.

Intake pipeline

IntakeBuilt untrusted inputsrc/oaken_core/intake.py · map

The front door: submit, format into parts, triage, store. Every step is a durable job. A reject keeps only a content-free log row.

Called by
Core daemon
Notifies (event or callback, upward)
none
Notified by
Jobs Providers
Types
NameKindMeaning
IntakeclassRegisters the format, triage, store and embed job kinds and runs them.
IntakeItemdataclassSubject, source, body, labels, key, the parts a formatter made, and what earlier triagers said.
Verdictdataclassaccept, reject or unsure, with a reason and labels.
Inherits
ClassBasesWhat it is
IntakePayloadBaseModel
StorePayloadIntakePayload
External none
Notes
  • Triage rule: any reject ends it; otherwise every triager answers and the last to answer decides. Each answering triager's labels are written under its own name.
TriagersBuilt untrusted inputsrc/oaken_core/triage · map

The built-in triagers: dedupe (a repeat from the same source), rules (the owner's ordered rules) and llm (a model asks about your criteria). Others, such as the signal triagers, ship in oaken-plugins.

Called by
Intake
Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
DedupeTriagerclassRank 1. Drops an item whose source and key (or body hash) it has seen.
RulesTriagerclassRank 5. The first matching rule decides.
LlmTriagertemplateOne instance per set of criteria; asks a model backend.
Inherits
ClassBasesWhat it is
DedupeTriagerBaseTriager
LlmTriagerBaseMultitenant, BaseTemplatePlugin, BaseLLMAnalyzer, BaseTriager
RulesTriagerBaseTriagerRuns before the models (rank 5): an item you have a rule for is never sent to one.
External none
Notes
  • Imports Verdict and IntakeItem from intake: shapes only, no call. Move them to the contracts to make the layering literal.
Model routerBuilt untrusted inputsrc/oaken_core/router · map

Picks a model backend and embedder for each call, caches answers by content, keeps a ledger of spend, and refuses a remote backend for a confidential item.

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
RouterclassResolves a call to a backend, applies locality and limits, caches, and records usage.
NearJunkclassA triager that embeds an item and drops near copies of known junk.
Inherits
ClassBasesWhat it is
NearJunkBaseVecAnalyzer, BaseTriager
MemoryVectorsBasePluginCosine similarity over lists. Fine for tests; a real store indexes.
StubBackendBasePluginAnswers with `reply` (a dict, or a function of the request and the model asked for). Records
StubEmbedderBasePluginA bag-of-words hash into `dimensions` buckets: texts that share words are close.
External none
Notes
  • pluginbase imports the router for the LLM types: a lower layer reaching up. Untangle by moving those types to the contracts.

Plugins

Discovers plugins (entry points, extension directories, oaken-plugins), checks each against its kind's contract, starts them store-first, makes named instances of templates, and says what each is: template, instance or plain.

Types
NameKindMeaning
PluginHostclassLoads, starts, reloads, enables and disables plugins; builds each one's row and UI spec.
PluginStatusdataclassKind, name, health, provider origin (core, plugins or local), API version and template state.
AddPlandataclassWhat plugin add will write: an instance's table and, for a template not yet loaded, the template's too.
External none
Notes
  • Offers each plugin's operations, job handlers and scheduled tasks upward; it does not reach into the registry itself.
  • Today the host imports the operations package: a lower layer reaching up.
Plugin base classesBuiltsrc/oaken_core/plugins/base.py · map

BasePlugin and the base for each kind, plus the mixins: BaseTemplatePlugin (an instance is how it runs) and BaseMultitenant (several workers may run it). Each plugin writes its api_version and requires_core.

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
BasePluginclassConfig, labels, UI spec, row, job handlers, scheduled tasks, traced calls.
BaseTemplatePluginmixincontextual settings, the template pill and the template part of the UI spec.
BaseMultitenantmixinMarks a plugin several workers may run at once.
BaseProviderclassBrings items in with submit().
BaseTriagerclassRates an item before it is stored; any reject ends it.
Inherits
ClassBasesWhat it is
BaseActionBaseAnalyzer
BaseAnalyzerBasePluginWhat triagers, enrichers and actions share. Deterministic by default; a plugin that asks a
BaseCacheBasePluginThe router's answer cache, swapped for another store. Override all five members. `key` may return
BaseEmbedderBasePluginTurns text into vectors. Analyzers reach it only through the router (`embed`).
BaseEnricherBaseAnalyzer
BaseFormatterBasePluginSplits a raw item into named parts (`oaken_core.parts.Part) before triage. formats` lists
BaseFriendlyNamesBasePluginAdd to a plugin's bases to give the console and the API (the MCP endpoint) friendly host names, such as `oaken.localhost`.
BaseIngestorBasePluginStores an item intake accepted and returns its real `SubjectId`. The product's own: core
BaseLLMAnalyzerBaseAnalyzerAdd to a kind's base for an analyzer that asks a model through the router:
BaseLLMBackendBasePluginRuns a chat model. The router calls `generate; where the model runs (locality`) is the
BaseProviderBasePluginA source: it gets items from outside (a file, a socket, a service) and puts each into intake with
BaseStoreBasePluginA store hands core a `Database`. Core and plugins write portable SQL against it.
BaseTemplatePluginBasePluginAdd to a plugin's bases when it only runs as a named instance that is given what makes it what it is: an agent's
BaseTriagerBaseAnalyzerRates an intake item before it is stored. Lowest `rank first. Any reject ends it; otherwise every triager answers and the last to answer decides. item.verdicts` holds what the ones before said.
BaseVecAnalyzerBaseAnalyzerAdd to a kind's base for an analyzer that uses the embedder and vector store, only through
BaseVectorStoreBasePluginStores vectors under a collection and a key, and finds the nearest. A collection never mixes
External none
Notes
  • Imports the router for the LLM request types; see the router.

The shapes a plugin and core exchange: context, health, operations, job handlers, scheduled tasks, and the UI spec (settings sections and field overrides, buttons, pages, the row and the template part).

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
PluginContextdataclassWhat a plugin is given: name, config, clock, log, db, labels, submit.
UiSpecdataclasssections, buttons, pages, template, row and field overrides.
UiRowdataclassStatus pills and actions (settings, reload, remove) for a plugin's row.
UiTemplatedataclassThe settings an instance must be given; one of a|b means one of them.
External none
Notes
  • PLUGIN_API_VERSION is 1. A plugin that speaks another is refused at load.
Catalog and extensionsBuiltsrc/oaken_core/plugins/catalog.py · map

What could be added: the oaken-plugins package and the extension directories, listed without importing anything. Reads each plugin's summary, api_version and requires_core from its source.

Calls
none
Called by
Plugin host
Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
EntrydataclassA plugin in oaken-plugins: kind, name, module, summary, api, requires.
External none
FormattersBuiltsrc/oaken_core/formatters · map

Split a raw item into named parts before triage. Core ships json; others (ini, rfc822) live in oaken-plugins.

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
JsonFormatterclassOne part per key of a JSON object.
Inherits
ClassBasesWhat it is
JsonFormatterBaseFormatterA JSON object becomes one part per top-level key (the value is the part's content). Anything else
External none
ProvidersBuilt untrusted inputsrc/oaken_core/providers · map

Sources that bring items into intake. Core ships socket, the machine's door: a template, one instance per Unix path or loopback port, each with its own source and format.

Called by
Plugin host
Notifies (event or callback, upward)
Intake
Notified by
none
Types
NameKindMeaning
SocketProvidertemplateWhatever is written to its socket is submitted to intake; replies OK or ERR per item.
Inherits
ClassBasesWhat it is
SocketProviderBaseTemplatePlugin, BaseProviderA door for the machine: whatever is written to its Unix socket (or loopback port) is submitted to intake. A template: make an
External none
Notes
  • A provider reaches intake only through the submit callback it is given, never by import.
Items ingestorBuiltsrc/oaken_core/items.py · map

The built-in ingestor: stores each accepted item (body and parts) as a row. It steps aside when a product installs its own, and oaken items list filters it by label, part and date.

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
ItemsIngestorclassThe fallback ingestor.
Inherits
ClassBasesWhat it is
ItemsIngestorBaseIngestor
External none
Notes
  • The ingestor kind is exclusive: one is active at a time.

Runtime

The durable job store and the runner. Jobs have a kind, a queue, a priority, retries and leases; a crash loses nothing. Handlers are registered by core and by plugins.

Types
NameKindMeaning
JobsclassThe store: enqueue, claim, complete, fail, requeue, stats.
JobRunnerclassRuns each queue's workers and calls the registered handler.
JobSpecdataclassKind, payload, subject and priority.
Inherits
ClassBasesWhat it is
PermanentJobErrorOakenErrorRaise from a handler to fail the job at once, without retries.
External none
Notes
  • Imports the queues for the default queue name: untangle by moving it to a shared constant.

Named queues, each the stage for one kind of analyzer plugin, defined in config.toml. A queue submits jobs; pausing a queue stops it handing out work.

Calls
Jobs
Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
QueuedataclassName, kind, label, workers and what is off in it.
QueuesclassThe registry of queues.
External none

Recurring jobs by interval or cron (UTC). A due schedule enqueues its job and moves its next run in one transaction, so a crash neither repeats nor loses a run. Plugins seed their own tasks once.

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
Schedulerclassadd, remove, rows, run_now and the tick loop.
External none
Notes
  • Schedules live in the database. Create, change, remove and run-now are operations and a console tab.

State

Key and value tags on a subject, in two layers (machine and human). A key must be defined before it is written, by core, a plugin or the owner.

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
LabelMakerclassThe registry of defined keys, with allowed values and who may write them.
LabelStoreclassReads and writes labels, with the human value winning.
Inherits
ClassBasesWhat it is
LabelErrorOakenError
ReservedLabelBaseLabelA key core owns. Plugins can write it and cannot define it.
External none
Events and logBuiltsrc/oaken_core/events.py · map

The event bus for job state, plugin health and live updates, and the kept log file with its readers.

Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
EventBusclassPublishes events to streams.
JobStateChangeddataclassA job moved state.
Inherits
ClassBasesWhat it is
JobStateChangedEventJobStateChanged(*, ts: datetime.datetime, event_id: str = <factory>, job_id: oaken_core.ids.JobId, kind: str, queue: str, status: str, subject: str | None = None)
LogEventEventOne log line, as `logging made it (already scrubbed). Published with publish_nowait`: only streams see it, so the
PluginEventEventBase for events a plugin defines itself: subclass it, add plain-data fields, and publish
PluginHealthChangedEventPluginHealthChanged(*, ts: datetime.datetime, event_id: str = <factory>, plugin: str, healthy: bool, detail: str = '')
QueueStateChangedEventQueueStateChanged(*, ts: datetime.datetime, event_id: str = <factory>, queue: str, paused: bool)
TraceEventEventOne line of the trace, which holds private text. It is published with `publish_nowait`, so
External none
DatabaseBuiltsrc/oaken_core/db.py · map

The portable-SQL handle every store provides: execute, fetch, transactions and one migration runner across core and plugin tables. SQLite ships as the default store plugin.

Types
NameKindMeaning
Databaseclassexecute, fetchone, fetchall, transaction, migrate.
External none
Notes
  • The store module defines the SQLite store plugin, so this package imports the plugin base classes.

Foundation

Untrusted textBuiltsrc/oaken_core/untrusted.py · map

Text from outside is data, never instructions. It reaches a model only wrapped as UntrustedText, between markers the model is told not to obey.

Calls
none
Notifies (event or callback, upward)
none
Notified by
none
Types
NameKindMeaning
UntrustedTextclassA body or source wrapped for a model.
External none
5

Class relationships

Every class that takes part in an in-core inheritance, read from the live package by docs/tools/classmap.py into docs/softmap.classes.toml. Subclasses nest under their base; the arrow names a base from outside the package.

6

Call flows

Each step is one call from one component into another, checked against the declared relationships at build time.

An item arrives

#FromToWhat happensNotes
1Providers→Intakesubmit(item) callbackThe provider is handed a callback; it never imports intake.
2Intake→Jobsenqueue the format jobDurable, so a crash loses nothing.
3Jobs→Intakerun the format job callbackA handler intake registered.
4Intake→Formatterssplit into partsDeterministic; no model.
5Intake→Triagersask each triagerAny reject ends it; the last to answer decides.
6Intake→Labelswrite each answering triager's labelsUnder that triager's own name.
7Intake→Jobsenqueue the store jobAccepted items only.
8Jobs→Intakerun the store job callbackA handler intake registered.
9Intake→Items ingestoringestThe one active ingestor.
10Intake→Change logrecord the ingestContent-free.

A scheduled task runs

#FromToWhat happensNotes
1Scheduler→Jobsenqueue the task's jobThe job carries a dedupe key naming the slot.
2Jobs→Plugin hostrun the plugin's job handler callbackRegistered at start as plugin.NAME.KIND.
3Plugin host→Providerscall the handlerFor example an exec instance running a program.
4Providers→Intakesubmit(row) callbackOne item per row it printed.

A person changes something

#FromToWhat happensNotes
1Console→Operation registrycall an operationA mutation comes back as a proposal first.
2Operation registry→Plugin hostfor example plugin_addWrites the instance, and the template if it is new.
3Operation registry→Settingsedit config.tomlWritten with a backup, then core reloads.
4Operation registry→Change logrecord who did itAudited by the registry.

A plugin loads

#FromToWhat happensNotes
1Core daemon→Plugin hoststart the hostStore first, then everything else.
2Plugin host→Catalog and extensionsfind the pluginEntry points, extension directories, oaken-plugins.
3Plugin host→Plugin base classescheck it against its kind's contractA fault switches that plugin off, not core.
4Plugin host→Labelsregister its label keysA bad definition switches it off.
5Plugin host→Schedulerseed its scheduled tasksOnly if absent: after that they are the owner's.
7

Dependency matrix

Row is the caller, column is the target. C is a direct call, B is an event or registered callback.

8

Checks

Run every time the docs are built; the build fails if any of these stops being true.

Result Check Detail
pass Components 25 components, 0 documented functions
pass Relationships 92 calls and 4 events or callbacks
pass Layering Every call goes to the same or a lower layer; every callback goes strictly upward
pass Call graph Acyclic
pass Call flows 4 flows, 23 steps, each following a declared relationship
pass Repository Built and partial components point at paths that exist; planned ones have none yet

Entry points, which nothing else calls because the user or an event drives them: Core daemon, CLI.

9

Open points

Topic Note