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.
- 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.
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.
- 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