- Wants: active wants by effective strength with origin, means, drives,
values, goal, reinforcement, suppressions and each conflict with its
resolution rule; closed wants with their resolution.
- Intentions grouped by status with blocked reasons and plans, plus the
wants that did not become intentions and why. An intention page shows
sources, subordinate intentions, formation terms, every plan revision as
a dependency graph, decisions and the correlated timeline; operators can
abandon it.
- Commitments with polarity, exception, matcher, weight and due time,
live conflicts between commitments, a creation form and close controls.
- Plans with estimate against budget; a plan page with the dependency
graph, per-step expectations, observations and linked approvals,
requests, executions and subordinate intentions, resources, completion
and abort conditions, assumptions, alternatives, revisions and
validation; operators can cancel a plan or release a blocked step.
- Agency timeline labelling each event as wanted, intended, committed,
planned, requested, approved, acted, observed or reconsidered.
- "Why did this happen?" pages built from agency.Explain, reachable from
events, executions in the approval centre, plan steps and intentions.
- A research dashboard per mind (volition and agency rates, introspection
accuracy, action claims, self-model accuracy, calibration by confidence
band, experiments on the mind) and a global research page grouping
experiments by protocol; every figure sits next to its operational
definition and the disclaimer. Experiment pages show the protocol,
reproducibility, build, per-variant research measures, divergence
extras and counterfactual findings.
- The mind tabs gain Volition; the navigation gains Research.
Observers can read wants (with effective strength), want conflicts,
commitments, intentions with their plans, subordinate intentions and
decisions, the decision ledger, plans with steps, "why" explanations for
executions, approvals, capability requests, plan steps, intentions and
events, attribution of an outcome event, the agency timeline, the
measure definitions with their disclaimer, agency metrics, metacognitive
calibration and raw research measurements.
Operators can create and close commitments, abandon an intention (its
plan is cancelled and pending requests withdrawn), cancel a plan and
release a blocked step. Every write is audited; none grants capability
authority. OpenAPI documents all 21 routes, and an end-to-end test
covers reads, writes and observer refusals.
A framework for testing functional properties of the architecture
(Part C). None of it claims consciousness; every measure has an
operational definition in research.Measures.
- Ablations (attention, memory retrieval, affect, metacognition,
commitments, volition, global workspace, curiosity, association, goals,
narrative, notifications) and workspace overrides (force a matching
candidate in or out of admission) live in a fork's cognitive
configuration. Original minds refuse them on create and update; only
snapshot restores may carry them, so they are part of the configuration
digest. Excluded candidates are recorded with fate "excluded".
- Self-model experiments override a fork's self-model (capabilities,
identity, goals, knowledge gaps) without touching policy. When an
action's effective policy disagrees with the self-model, cognition
records a self_model_mismatch and corrects the entry; experiments report
self-model accuracy and correction latency.
- Counterfactual experiments replay a mind's recorded stimuli from a
snapshot with chosen events omitted; the report lists what differed in
beliefs, wants, intentions, memories, attention and capability
decisions, in a form introspection can cite.
- Experiments record a protocol (kind, independent variable, controlled
variables, measures), per-variant volition, plan, downstream-by-category
(events reachable from each stimulus through recorded links),
introspection and self-model measures and event ranges; comparisons add
want, intention and plan-capability overlap, measure ranges, a
descriptive architecture share and a downstream delta; reproducibility
is labelled against the previous run of the same definition.
- research.Agency computes want→intention, intention→action, abandonment,
commitment fulfilment and conflict, blocked intentions, replanning,
outcome success and introspection accuracy; MetacognitiveCalibration
relates confidence and expressed uncertainty in replies to later belief
revision, with Brier scores for each half of the period.
- The sandbox test harness gains volition, planning, agency and research
but not the motivation hook, whose wall-clock decay would make replay
comparisons timing-dependent.
- agency.Explain answers "why did this happen?" for an execution,
approval, capability request, plan step, intention or event from
recorded state only: action, immediate plan step, plan, intention and
any subordinate intention, originating wants, goal, supporting beliefs
and their evidence, conflicting wants with their resolution,
commitments applied, formation and reconsideration decisions, the
expectation and its outcome, and explicit gaps where nothing is
recorded. Hidden model reasoning is never shown because it is not
stored.
- agency.Attribute classifies an outcome as caused (a recorded causal
link from one of the mind's actions), followed (the mind acted on the
same target earlier with no recorded link), independent or unknown;
temporal order alone is never taken for causation.
- New introspection intents answer from records: why an action happened,
what was believed at a past time (from append-only belief versions),
which earlier state is the mind's (lineage), what would have happened
without an event (only from completed counterfactual experiments,
otherwise "no evidence"), how the mind changed, and what it wants,
intends and has committed to.
- research.ScoreIntrospection compares a reply with the recorded facts
sentence by sentence (supported, partially supported, unsupported,
contradicted, unknown). Fluent reasons with no recorded counterpart earn
nothing, and a claim that an action was done is checked against
execution records. Every reply is scored; results are append-only
research measurements (migration 0028), and failures raise
unsupported_explanation or action_claim_without_record warnings.
Part H invariants, enforced and tested:
- Snapshots now carry wants, want conflicts, commitments, intentions,
plans, plan steps and the volition decision ledger.
- A fork no longer copies the source mind's policies unless the operator
asks for it explicitly (inherit_policies in the API, a checkbox in the
UI; audited), and the fork's history records the omission. Imports
never restore policies, as before. Replays and experiments never
inherit.
- Work inherited mid-flight by a fork or import is quiesced in the
restore transaction: open steps are blocked with their approval and
request ids cleared, open plans blocked and live intentions suspended,
each with the reason. Approvals, grants and executions stay with the
source mind.
- Dreams may leave a want to test a hypothesis they proposed; they never
request authority, and dream-origin plans never run.
- Snapshot column discovery now reads the current schema instead of
"public", which only worked in tests because the development database
happened to hold the same tables.
- Security tests: a static scan that only the capability service runs
executors and that no cognitive package can set or delete policy,
approve, deny, grant or revoke; forged wants, commitments, intentions,
model plans and model output end in refusal or a pending approval with
policy and grants unchanged; component names cannot decide requests or
approvals; no capability names an operator control; the registry cannot
grow at runtime; audit, event and decision history cannot be altered;
forks and dreams as above.
Volition and planning now run as part of cognition (PLAN §8.2 item 3):
- A volition hook derives wants after each cycle from what it perceived
and produced, satisfies answer wants when a reply is sent, raises due,
overdue, expired and conflicting commitments, and expires faded wants.
Events produced by earlier cycles are not re-derived.
- An intend process proposes deciding about the strongest undecided
wants; the candidate competes for the workspace, so attention gates
what the mind decides to pursue. The handler makes value tensions
explicit (caution against disruptive writes, privacy against reading
personal data), resolves them with recorded scores, runs deterministic
formation with commitments, policy preview, goals and values, records
the decision whatever it is, and plans a formed intention in the same
transaction. Operator requests carry their own weight in formation.
- Explicit requests in conversation ("restart <unit>", "logs for <unit>",
"fetch <url>") become wants with proposed means instead of direct
invocations; the reply says the request was recorded and that acting
depends on commitments and policy.
- The executor is woken after commits, runs in a scheduler-owned loop and
reacts to the event bus: a new commitment tightens or abandons affected
intentions (withdrawing their pending approvals), a weakened assumption
or a finished goal triggers reconsideration. A tightened plan may reuse
its strategy; a failed one may not.
- Metacognition gains volition checks: strong wants repeatedly set aside,
intentions with no recorded reason, intentions a commitment forbids,
commitments that cannot be kept, churn, repeated failed execution,
cost outweighing value, and intentions that outlived their goal.
- A plan model role and prompt let a model propose decompositions that
the planner validates. Ablations are a fork-only configuration field.
- Approvals required by an intention are described as coming from a
commitment or value constraint. The expectation after an approved
action is linked to the execution event, not the request.
- The wants.values column of the unreleased migration 0026 is renamed
value_keys: VALUES is reserved and the generic snapshot restore does
not quote identifiers.
- The hostile-output security test now uses a message that asks for no
action, because an operator's "status of <unit>" is legitimately a
read-only status check.
Bounded operations instead of a shell (ADR-0011): service.status,
service.restart and logs.query run systemctl/journalctl from a fixed
allow-list with no shell, a minimal environment, validated unit names and
the unit as the derived policy target; logs mask e-mail and IP addresses
and credential-like values by default. host.disk.usage,
host.memory.status and host.process.list read the kernel directly and
never read command lines. browser.navigate/read/links fetch through the
SSRF-safe client, run no scripts, refuse cross-host redirects, use the
host as the policy target and deliver content as low-trust observations.
Writing browser operations are designed but not registered. The test
harness takes a fake command runner so no test touches a real unit.
- Capabilities declare access (read/write, unknown fails closed as
write), side effects, idempotency, timeout, cost estimate and the trust
of their output (web content is low trust). A capability may derive its
policy target from its parameters; a disagreeing target is refused, and
approvals whose modified parameters change the target are refused.
- The registry is frozen at start-up; registration afterwards panics.
- Invocation.RequireApproval turns ALLOW into ASK for commitments; it can
only tighten, and scoped grants never satisfy it.
- Scoped grants (migration 0025): capability, target and parameter globs,
access, expiry of at most seven days and an optional operation count
consumed atomically; applied only where policy says ASK. A sweep marks
lapsed grants and refreshes the self-model, which now lists live grants.
- Capability requests carry scope, duration, operation cap, reason,
evidence, risk, mitigation, fallback, alternatives and explicit decision
history; they batch per intention, are capped per mind (operator
attention budget) and can be decided only by a named person. Component
names are refused as deciders, for approvals too, and as usernames.
- API routes, OpenAPI entries, scheduler sweeps and approval-centre
sections for requests and temporary grants.
Neither noemad nor the test harness passed ui.Actions.Policy or Decide,
so an operator's Approve, Deny and "add rule" forms dereferenced a nil
function and returned 500. Both handlers now use the shared, audited
server methods like the other study pages, and the unused callbacks are
removed. The observer-escalation test only reached the role check, which
is why this went unnoticed; the new browser test fails without the fix
(policy form → 500) and passes with it.
The cognitive registry was assembled by hand in three places. Ablation
experiments need the daemon, the test harness and replay sandboxes to
name the same processes and hooks, so they now share
cognition.NewRegistry; hooks are added only when their store exists,
which keeps the harness's previous behaviour.
Rows in append-only history are never deleted; their content can now be
made irrecoverable through one audited path. A redaction replaces the
content columns of an event, memory, message, model call, belief or
assertion with a fixed marker, keeps identifiers, links, timestamps,
scores and breakdowns, writes an append-only ledger row with a SHA-256 of
the removed content, appends a redaction event, optionally cascades to
derived rows and to the events that quote them, and scrubs stored snapshot
archives before re-signing them. noema_redact() is the only write the
append-only trigger admits, for UPDATE only, under a transaction-local flag
the application never sets; plain updates and all deletes stay refused.
Replay labels redacted stimuli instead of inventing them.
Cryptographic erasure was considered and deferred with reasons (ADR-0009);
docs/privacy.md defines retained, redacted, irrecoverable and deleted and
states what backups and earlier exports are not covered. Migration 0023.
A bounded walk (six hops, two hundred events) over the links events
actually record: causation ids, parent ids and cited-event evidence,
backwards towards causes and forwards towards consequences, with the edge
kind on every arrow. Nodes carry their cycle for grouping, labelled as
correlation rather than causation, and the artefacts (beliefs, memories,
model calls) they rest on. Cyclic references terminate. Exposed at
GET /api/v1/events/{id}/chain and /events/{id}/timeline, linked from the
event page, and documented.
Adds co_occurs_with, temporally_precedes, possibly_caused_by and
asserted_by to the relation vocabulary with Causal and Hypothetical
predicates. Entities mentioned together now co-occur rather than being
'related'; association hypotheses record possibly_caused_by and their
basis (temporal association only); caused_by is reserved for explicit
operator statements and nothing automatic writes it. Documented in
docs/graph.md and checked end to end.
A statement made to a mind is now three things kept apart: the observation
that it arrived, an append-only assertion (attributed actor, stance,
certainty, modality, negation, reported or quoted speech, hypothetical
status, interpretation confidence and notes), and, only for factual
assertions, one piece of evidence for a proposition belief attributed to
whoever actually stands behind it. Reported speech is attributed to the
person reported and weighed as second-hand; hypotheticals, questions and
imperatives create no belief; expressed doubt counts against; a possibly
sarcastic remark is recorded with low interpretation confidence rather
than guessed at. Interpretation is deterministic code; a model may enrich
the claim list but never sets stance or confidence.
Association no longer treats conversational turns as world events:
hypotheticals, questions, requests and consecutive turns by one speaker
cannot seed causal hypotheses.
Adds internal/epistemics, migration 0018, the assertions API, assertions
on belief pages and in belief detail, a shared end-to-end test harness
(tests/harness), end-to-end tests for eight speech patterns, and updates
the milestone test to the new provenance.
Forged action requests for locked, unknown and ask-only capabilities and a
hostile model emitting tool calls and policy in perception output all end
in denial or an approval request; nothing executes and policy is unchanged.
Non-JSON and wrong-shape model output falls back to the deterministic path.
Drives, goal kinds and the capability registry contain nothing about
self-preservation, replication, permissions or the mind's own lifecycle.
The SQL-injection effect test found that a NUL byte in a query string,
path or JSON body reached PostgreSQL and surfaced as a 500. Requests are
now buffered up to the existing limit and NUL in any form (raw, JSON
escaped, form encoded) is refused with a 400 before a query runs.
TestSQLInjectionHasNoEffect sends metacharacter payloads through every
search, filter and free-text route and asserts effect: users, policies,
sessions and tokens unchanged, seeded content intact, payloads stored
verbatim. TestDynamicSQLIdentifiersAreAllowListed scans for statements
assembled with Sprintf outside the reviewed allow-list.
- docs/screenshots: nineteen pages captured with headless Chromium from a
running instance; README gains a screenshot section
- tests/perf: opt-in load test (NOEMA_PERF=1) seeding 60k events, 6k
memories and 1.5k beliefs across two minds, timing sixteen hot reads
against a 400 ms ceiling and rejecting sequential-scan plans
- migration 0016: indexes the test found missing (memories by mind and
recency, beliefs by mind and confidence, events by mind and category,
belief versions by mind and time)
- docs/performance.md records the numbers and how to rerun
- TOTP second factor (RFC 6238, secret encrypted under the master key),
ten hashed single-use recovery codes, two-step login with a pending token
bound to the client address, account enrolment/disable, admin reset
- tests/security: prompt-injection corpus never acts or creates evidence-free
beliefs; roles and CSRF on form and API paths; cross-mind isolation
(demo scenario 5); stored-XSS escaping and CSP across pages; secrets never
echoed (API, pages, database, archives); hostile archive import; session
lifecycle and security headers
- OpenAPI 3.1 document generated from the route table, served at
/api/v1/openapi.json and kept complete by a test
- gosec clean (justified #nosec annotations, cookie/redirect hardening,
bounded multipart parsing, UUID packing without narrowing conversions);
govulncheck clean with toolchain pinned to go1.26.8
- THREAT_MODEL verification pointers, SECURITY.md testing section, README,
CHANGELOG 0.1.0, docs/RELEASE_NOTES.md, PLAN status
- snapshots: checksummed JSON archive of every mind-scoped state table plus
identity/personality/config and the event position; stored, downloadable
- fork: restore into a new mind with all ids remapped; event references are
kept so history before the fork is shared by reference
- export/import: same archive; import is hostile-input validated (size,
allow-listed tables, row caps, column names, checksum, forced mind_id)
- compare: deterministic counts, belief diffs by proposition, personality
and config diffs, event mix
- replay: Runtime.Step for synchronous drivers; sandbox fork driven one
stimulus at a time under a forbidden capability context; recorded model
responses via a replaying router; steps labelled exact / approximate /
diverged with recorded-vs-replayed digests
- experiments: definition (overrides, stimuli, expectations, seed, duration),
background run in a disabled subject mind, stored and exportable results
- migration 0015, API, UI (Snapshots and Replay tabs, Experiments section,
compare page), noemactl snapshots/compare/replay/experiments, docs
- dreaming.Service: deterministic memory replay sample keyed by dream id,
vocabulary-based association of unlinked memory pairs (similar_to edges +
dream_association events), speculative hypotheses as hypothesis-kind beliefs
with two weak memory citations (starts ~0.30, asserted <= 0.35)
- Run marks the context forbidden for capabilities before anything else;
test proves Invoke refuses inside a dream
- per-mind settings: enabled (default off), hours window (wraps midnight),
interval, model-call / memory / hypothesis caps; global pause switch
- optional model wording via new `dream` prompt (role hypothesise)
- promotion adds operator evidence, rejection retracts the belief; both
audited and recorded as operator actions
- migration 0014, API, Dreams tab and page, noemactl dreams, docs/dreaming.md
Phase 12 (ADR-0005). Capabilities are registered in code with parameter
schemas, risk classes and default effects; sudo_shell and delete_database
are locked to DENY and cannot be relaxed. Policies are scoped globally or
per mind with capability, target glob, action kind and optional hour
window; evaluation is deterministic, most specific wins, and ties go to
the stricter effect. Invoke is the single entry point: it refuses
dreaming and replay contexts, validates parameters (unknown keys, non
http URLs and path traversal rejected), evaluates policy and session
grants, hashes the exact request and records a policy_decision event.
ALLOW executes with timeout and panic isolation and turns textual output
into a tool-trust observation; ASK creates an approval request bound to
the hash with an alert notification; DENY is counted and recorded.
Operators approve once, approve for a time-boxed session grant, deny
with a note, or modify parameters (re-validated, re-hashed, original
kept in the append-only decision log). The self-model's capability list
is recomputed from effective policy on start and on every policy change.
The act process maps fetch requests to http.fetch and the action handler
invokes through the layer; replies report capabilities and outcomes.
Policy matrix and approval centre pages, dashboard count, API, CLI
(approvals, policy, invoke) and docs/capabilities.md.
Phase 11. Entities are mind-scoped nodes with canonical matching,
aliases and deterministic kind guessing (hostnames and hyphenated ids
are systems, capitalised names people, file suffixes documents).
Relationships carry a relation from the shared vocabulary, confidence,
source, reinforcement count and the event that produced them; links tie
entities to memories, beliefs, events, goals and predictions.
The perceive and attend handlers upsert the entities a message or
observation mentions and record co-mention edges cited to the event, so
the graph grows only from what was actually seen. Operators can merge
("these are the same": edges and links move, the old name becomes an
alias, the old id still resolves), record that two entities are
different, correct kinds and add typed edges; every correction is an
operator action and a corrections row.
The explorer renders a bounded subgraph on a canvas with a small
force-directed layout in plain JavaScript, with kind filters, focus on
a neighbourhood and a side panel per entity. API, entity page, CLI and
docs/graph.md.
Phase 10. Metacognition is a cognitive process with deterministic
self-checks (insufficient evidence, single-source reliance, model output
without evidence, repeated failed hypotheses, stale contradictions,
calibration overconfidence); its warnings compete for attention and,
when admitted, add counter-evidence or open an investigation goal.
Reflection reviews the period since the last run (prediction errors,
rejected beliefs, corrections, status changes, completed goals,
contradictions, calibration), turns repeated failures into procedural
lessons written once, and records a reflection event; a model may only
word the prose within the mind's budget.
Consolidation clusters unconsolidated episodes by shared stemmed terms,
creates a belief whose confidence is computed from the episodes as
evidence and a semantic memory linked to each episode by derived_from,
and records jobs with inputs and outputs. Wording may come from the
consolidate prompt within a per-run model budget; the job says which.
Operators can run, pause and reject; originals are never touched.
The narrative hook keeps a five-part first-person narrative built from
state and stored with narrative_updated events. The notification hook
applies explicit thresholded rules, aggregates repeats within a cooldown
and records suppressions with reasons. A scheduled job runs
consolidation and reflection per mind, switching the runtime mode while
it works. API, Background tab, notifications page with unread badge,
overview narrative and warnings, CLI commands, docs/cognition.md.
Phase 9. Goals form a mind-scoped tree with kind, priority, progress and
blockers; their deterministic relevance to a candidate feeds the
goal_relevance attention feature and a goal monitor raises stalled goals
and observations that touch one. Drives are a closed set of eight
scalars with operator-configured ranges and personality-derived
baselines; there is no self-preservation, replication or acquisition
drive and no way to add one at runtime. Affect is ten scalars moved by an
explicit rule table over events and decaying towards baseline; both
modulate attention weights each cycle and the effective weights are
recorded with every cycle and shown beside the configured ones.
Predictions carry a window and machine-checkable criteria (event terms
occurring or staying absent, a belief reaching a confidence, or operator
judgement). A resolver job judges them deterministically, keeps an
append-only outcome history for calibration (accuracy, Brier score,
confidence buckets, overconfidence flag), emits prediction_error events
scaled by how confident the miss was, and feeds the outcome back into the
linked belief as evidence. Causal hypotheses derive predictions
automatically. Curiosity turns misses, contradictions and unexplained
observations into questions that compete for attention and become
investigation goals when admitted.
Brain gains after-cycle hooks and goal/motivation state. API, UI (goals,
prediction dashboard, cognitive state panel, effective weights) and CLI
(goal, prediction, state). Demo scenario 4 verified end to end.
Phase 8, completing milestone M1. A user message is stored and appended
as an observation event carrying trust, actor, channel and reference. The
perceive process analyses it deterministically (intent, introspection
kind, entities, claims, urgency) and, within the per-cycle model
allowance, enriches it through the perceive prompt. Its handler writes a
perception event, an episodic memory with participants, turns claims into
beliefs whose evidence is the message, and builds a response intent from
state: beliefs and memories for the topic, evidence rows for why-questions,
the uncertain band, contested beliefs and their links, recent learning,
status changes, and honest declines for subsystems that do not exist yet
or for requests with no capabilities. The respond prompt phrases the
intent when a model is assigned; otherwise the reply is a direct
rendering of the intent. response_generated cites the message, the
perception, every belief and memory used, the episode and the model call.
API: conversations, messages with optional wait, one-shot ask; chat UI
with live refresh and a per-reply intent view. Sample mind Dani as a
strictly decoded seed document with an import endpoint and noemactl mind
import. tests/m1 drives all fourteen milestone steps including restart.