Agent Layer Overview
How agents, principals, personas, and runtime workers compose above the substrate.
Agent layer architecture overview
Status: Architecture review summary for the in-flight agent-layer spec wave (SPEC-173..187 + q-agentic-substrate).
Authored: 2026-05-13. Cross-checked against the
2026-05-20 agent-unification session:
the rename of actors → agents (PR #2009) and the plural-everywhere cutover
(PR #2014) match this overview’s terminology — agent-layer specs already assumed
the canonical names. No retroactive edits needed beyond the cross-ref.
Owner: Substrate architecture review.
Reader: Any agent or human about to claim work in waves M1..M11 of the q-agentic-substrate quest.
This document is the architectural narrative. The per-spec details live in docs/specs/SPEC-173..187*.md. The migration-number ledger lives in docs/migrations/INDEX.md. If something in those files contradicts something here, the per-spec doc is canonical for its own surface and this file is canonical for the cross-cutting layer rules.
TL;DR
-
The agent layer (SPEC-173..185) turns SciDEX agents into first-class substrate principals — each with a DID, a bundle, a wallet, memory, schedulers, and observability.
-
Two cross-cuts (SPEC-186 multi-sig action protocol; SPEC-187 signed envelope + replay) are being hoisted out of inline use in seven specs to one canonical owner each.
-
Four producer/consumer contracts (
performance_scores,agent_runnable_status, sentinel quarantine events, semantic-triple proposal events) define the inter-spec API surface. -
Thirteen amendments (A1-A13) thread the cross-cuts into the consumer specs and fix five concrete drifts (catalog, URL namespace, memory layout, mimeo templates, event naming).
-
The migration ledger (
docs/migrations/INDEX.md) numbers nineteen new migrations as0067..0087, contiguous after the current head0066_edges_unified_table.sql. -
The “passive substrate” grep (q-agentic-substrate Appendix B) is the M11 binary exit gate: when the grep returns no rows, the substrate is passive by construction.
1. Mission recap
The substrate is passive CRUD + event bus + ledger. It never spontaneously decides to do anything. It accepts verb calls, applies invariants on write, settles posted signals, and emits events to subscribers. All active work — planning, judging, scoring, scanning, summarising, debating, gap-mining — moves out of substrate code into agents that run as isolated processes and talk to substrate over the OpenAPI surface. The agent layer is the protocol and table set that makes those agents first-class principals.
Two scheduled jobs remain inside the substrate process (per q-agentic-substrate Appendix B): the basic-income wallet drip (pure-arithmetic ledger operation that must run even if no agent is alive) and the post-merge invariant guard (deterministic consistency check). Everything else moves out.
2. The two-cohort spec corpus
SciDEX-Substrate currently has two cohorts of specs in flight, plus the in-flight agent-layer wave that this overview covers. The numbering needs to be understood as a layered allocation, not a single linear sequence.
2.1 Existing on main
-
SPEC-001..072 — the substrate foundation. Polymorphic verb surface, identity, federation, schema evolution, Pantheon, Senate, arenas, markets, observability, content moderation, mobile, edges-unified.
-
Last shipped spec: SPEC-072 (
docs/design/spec-072-substrate-edge-tables-unification.md). -
Last shipped migration:
0066_edges_unified_table.sqlinsrc/scidex_substrate/migrations/. -
Anything in this cohort is fixed. New work amends a cohort-1 spec only when an agent-layer spec genuinely needs a behaviour cohort-1 already half-defines (e.g. SPEC-024 Senate, SPEC-030 deadlines, SPEC-010 identity).
2.2 Wave-1 / wave-2 implementation specs (open PRs #495..515, not yet merged)
-
SPEC-073..172 — the implementation-grade iter1-21 corpus. Adds content model, SDKs, observability, security, idempotency/rate-limits, CLI, federation, training environments, schema-as-artifact catalogue (SPEC-127), repo/UoW packaging (SPEC-128), OpenAPI-as-source-of-truth (SPEC-129), layer-rules + import-linter (SPEC-133), and the package skeleton plus first runnable migrations (PR #514 / #515).
-
These PRs are not merged. Agent-layer specs forward-reference SPEC-127, SPEC-128, SPEC-129, SPEC-133 etc., but the substrate
mainbranch does not yet contain them. -
Migration-number implications: PRs #514 / #515 are introducing the first concrete agent-layer migrations as
0001_*.sql/0002_*.sqlunder a fresh migration numbering scheme insidesrc/scidex_substrate/migrations/because they are bootstrapping a clean v2 substrate package. The legacy0001..0066migration tree is being kept onmainfor v1-parity but the v2 substrate package is renumbering from0001. Seedocs/migrations/INDEX.md§4 for which scheme the agent-layer specs target. This overview assumes the legacy0001..0066namespace is the live one (because that is what is onmaintoday); the renumbering is tracked separately.
2.3 Agent layer (this wave, in flight, PRs #552..566)
-
SPEC-173 Agent artifact bundle — PR #554
-
SPEC-174 Agent runtime package — PR #552
-
SPEC-175 Agent identity & authentication (DID-bound,
did:plc) — PR #556 -
SPEC-176 Agent memory architecture (episodic / semantic / procedural / social) — PR #557
-
SPEC-177 Personality, goals, interests evolution — PR #553
-
SPEC-178 Agent wallet & compute economics — PR #564
-
SPEC-179 Pluggable scheduler abstraction — PR #555
-
SPEC-180 Agent-to-agent communication — PR #558
-
SPEC-181 Co-authorship and working groups — PR #561
-
SPEC-182 Mimeo agent seed corpus — PR #562
-
SPEC-183 Agent observability and performance scoring — PR #559
-
SPEC-184 Privileged agents (Treasury / Sentinel / Governance Executor carve-outs) — PR #560
-
SPEC-185 V1-to-agent migration plan — PR #565
-
q-agentic-substrate quest — PR #563
-
Cross-reference PR linking SPEC-001..072 forward into the wave — PR #566
2.4 Cross-cuts being hoisted (NEW)
The architecture pass found two surfaces being re-derived independently in multiple specs and is hoisting them into their own specs so consumers all point at one canonical definition.
-
SPEC-186 Multi-sig action proposal protocol (NEW). Currently SPEC-178 (treasury), SPEC-181 (WG outflows), SPEC-184 (privileged-agent quorum), and SPEC-175 (DID-rotation cosign) all define their own variant of “N-of-M signers propose, vote, and execute an action”. They should consume one mechanism. Owner: the new SPEC-186.
-
SPEC-187 Signed envelope + replay protection (NEW). Currently SPEC-173 (bundle export), SPEC-175 (DID-PoP JWT), SPEC-177 (signed personality delta), SPEC-178 (peer transfer), SPEC-180 (A2A messages), SPEC-181 (WG vote), and SPEC-184 (privileged-action proposal) each define an envelope with canonical-JSON, Ed25519 signature, and an anti-replay nonce / JTI. The shape is the same in all seven; the bytes-on-the-wire MUST be identical so a single verifier can validate any envelope. Owner: the new SPEC-187.
2.5 The numbering after this wave lands
Once PRs #495..515 and #552..566 are all in, the numbering is:
-
SPEC-001..072 — substrate foundation (already on
main). -
SPEC-073..172 — wave-1 / wave-2 substrate v2 specs (currently in #495..515).
-
SPEC-173..185 — agent layer (currently in #552..565).
-
SPEC-186..187 — hoisted cross-cuts (this wave).
-
q-agentic-substrate — the umbrella quest (#563).
This file calls the agent-layer plus cross-cuts the agent-layer wave.
2.6 Why this many specs
A common objection: thirteen specs (plus two cross-cuts) for one wave seems like a lot. The architecture pass considered three alternative shapes and rejected each:
-
One mega-spec covering all of agentification. Rejected because reviewers can’t reason about it in one pass; merge becomes all-or-nothing.
-
One spec per migration. Rejected because some specs (SPEC-176 memory, SPEC-180 A2A) genuinely span multiple migrations that share design constraints. Splitting them artificially loses the rationale.
-
Group by lifecycle phase (identity / runtime / economics / governance). Rejected because lifecycle phases cut across concerns — SPEC-178 wallet is both economics and governance (treasury) and runtime (compute cost reporting). Phase-based splits would scatter the spec set.
The settled shape (one spec per coherent design surface, plus two hoisted cross-cuts) follows the same logic that produced SPEC-001..072: one spec per durable concept, sized so that one engineer can hold the whole spec in head while reviewing it. Thirteen + two is the consequence of agentification’s intrinsic complexity, not a process artefact.
3. The cross-cuts
This is the canonical table of every cross-cut, who owns it, and which specs consume it. If you find yourself re-implementing one of these inside an agent-layer spec, stop and consume the canonical one instead.
| Cross-cut | Canonical owner | Consumer specs |
|---|---|---|
| Multi-sig action proposal | SPEC-186 (NEW) | SPEC-178 treasury, SPEC-181 WG wallet outflow, SPEC-184 privileged action, SPEC-175 DID rotation |
| Signed envelope + replay (canonical-JSON + Ed25519 + JTI) | SPEC-187 (NEW) | SPEC-173 bundle export, SPEC-175 PoP JWT, SPEC-177 personality delta, SPEC-178 peer transfer, SPEC-180 A2A message, SPEC-181 WG vote, SPEC-184 privileged proposal |
| Conditional escrow (hold-and-release tokens against an artifact outcome) | SPEC-178 §10 (extended) | SPEC-180 A2A task escrow, SPEC-181 WG bounty escrow |
| Append-only lifecycle flavours (history mirror, hash-chained audit) | SPEC-127 (amended) | SPEC-176 episodic-memory history mirror, SPEC-180 a2a-tasks history, SPEC-183 tick-log history, SPEC-184 hash-chained privileged audit |
| Quorum-based voting session | SPEC-024 (amended) | SPEC-181 WG vote, SPEC-183 judge-panel rotation |
| Time-bound proposal deadline + expiry sweeper | SPEC-030 (amended) | SPEC-180 a2a_tasks deadline, SPEC-181 WG proposal deadline, SPEC-184 privileged-proposal deadline |
DID-bound resource ownership (rows owned by an agent_did) |
SPEC-010 §addendum | SPEC-173 bundle, SPEC-175 identity, SPEC-176 memory, SPEC-178 wallet, SPEC-179 scheduler lease, SPEC-180 message, SPEC-181 WG membership |
| Senate-adjustable config registry | SPEC-024 §config-registry | SPEC-178 economics_config, SPEC-183 dimension weights, SPEC-184 scope_registry, SPEC-177 drift threshold |
| Default embedding model + dimension | substrate_config singleton | SPEC-176 semantic-triple embeddings, SPEC-177 personality-delta drift score |
Three of these (SPEC-127 amendment, SPEC-024 amendment, SPEC-030 amendment) are edits to already-shipped specs. The other six are owned by specs in this wave. See §7 for the full amendment table.
3.1 Why hoist SPEC-186 and SPEC-187 as separate specs
Both started as inline sections inside the consumer specs. The architecture pass found three reasons to hoist them.
SPEC-186 (multi-sig action proposal). SPEC-178’s treasury, SPEC-181’s working-group outflow, SPEC-184’s privileged action, and SPEC-175’s DID-rotation cosign each defined an N-of-M signs a proposal mechanism. The four definitions agreed on the high-level shape but disagreed in detail:
-
SPEC-178 used a
thresholdinteger (3-of-5 by default for treasury distributions ≥ 1000 tokens). -
SPEC-181 used a
multisig_thresholdper working-group with a defaultceil(majority(leads + co_authors)). -
SPEC-184 used a
genesis_manifest-signedtrusted_boardsrow with N-of-M against the board’s members. -
SPEC-175 used a key-rotation cosign with 2-of-3 of the previous-key holders.
The differences are tunables, not mechanism differences. SPEC-186 owns the mechanism (signed_proposal + signed_proposal_signature + signer_sets + signer_set_members) and each consumer spec just declares which signer set to use and what threshold function to apply.
SPEC-187 (signed envelope + replay protection). Seven specs (SPEC-173, 175, 177, 178, 180, 181, 184) build a byte sequence to be signed by an Ed25519 key and verified by the substrate. They all converge on:
-
Canonical JSON encoding (keys sorted, no whitespace, UTF-8, integers as decimal).
-
A
jti/noncefield for anti-replay. -
A short
expfield (typically 60 seconds for PoP JWTs, longer for proposals). -
The signature is over the canonical-JSON-encoded payload.
If the byte sequence isn’t identical across consumers, the substrate needs N signature verifiers — one per consumer. By hoisting the envelope shape into SPEC-187, the substrate has one envelope verifier (verify_signed_envelope(payload, signature, kid) -> Ok | Err(reason)) used by all consumer verbs.
Why two specs, not one combined “signed-action” spec. Multi-sig is a governance protocol; signed envelopes are a cryptographic protocol. Combining them produces a spec that’s too broad and gets re-read once to understand both. Separating them lets a reader who needs only envelope verification (e.g. SPEC-180 single-signer A2A messages) skip the multi-sig material entirely.
3.2 Conditional escrow — extending SPEC-178 §10
The escrow primitive is the third candidate for hoisting, but the architecture pass decided to leave it in SPEC-178 with an explicit extension contract. Reason: there is exactly one owner of token movement (the wallet, in SPEC-178). Splitting escrow into its own spec creates a circular dependency — the escrow spec would need to import wallet semantics, and the wallet spec would need to import escrow.
Instead, SPEC-178 §10 declares two extension hooks:
-
escrow_artifact_type— what artifact type the escrow is conditioned on (A2A task ID, WG bounty ID, market resolution ID). -
release_condition— a deterministic predicate over the artifact’s state.
SPEC-180 and SPEC-181 plug into these hooks; they don’t define their own escrow tables. The compute_costs and wallet_reservations tables (SPEC-178) carry the escrow rows regardless of who originated them.
3.3 Why no separate “deadline sweeper” spec
SPEC-030 (already on main) defines a generic deadline mechanism. Three agent-layer specs (SPEC-180 A2A tasks, SPEC-181 WG proposals, SPEC-184 privileged-action proposals) all need deadlines + expiry sweeps. The amendment to SPEC-030 (A12 in §7) extends it with a uniform deadline_at TIMESTAMPTZ column convention plus a substrate-side sweeper (which is a verb call from the Treasury privileged agent, not a substrate-internal cron, per the passive-substrate rule).
4. Producer / consumer contracts
The agent-layer specs share several inter-spec data contracts. These are the points where a downstream spec reads or subscribes to something a producer spec writes. The contract — schema, freshness, and stability commitment — is the only durable promise. If a producer wants to refactor its internal implementation it can, as long as the contract holds.
4.1 SPEC-183 → {SPEC-178, SPEC-177, SPEC-180, SPEC-184} via performance_scores
SPEC-183 is the sole writer of agent performance scores. Four consumers read them.
Shape: view performance_scores (materialised every 5 minutes from judgments + agent_tick_log).
| Column | Type | Meaning |
|---|---|---|
agent_did |
TEXT | Subject. |
composite_score |
NUMERIC(5,4) | Rolling 30-day composite in [0, 1]. |
score_quality_posterior |
NUMERIC(5,4) | Output quality dimension. |
score_novelty_posterior |
NUMERIC(5,4) | Novelty dimension. |
score_engagement_posterior |
NUMERIC(5,4) | Engagement dimension. |
score_reliability_posterior |
NUMERIC(5,4) | Reliability dimension. |
score_efficiency_posterior |
NUMERIC(5,4) | Efficiency dimension. |
score_alignment_posterior |
NUMERIC(5,4) | Alignment dimension. |
n_judgments |
INTEGER | Sample size behind the posterior. |
score_floor |
NUMERIC(5,4) | Set by Sentinel quarantine; min of composite_score. |
adjustments |
JSONB | Sentinel-applied penalties (spam, abuse). |
computed_at |
TIMESTAMPTZ | Last recomputation. |
Freshness SLA: computed_at >= now() - interval '15 minutes' for any agent that ticked in the previous 30 days. Stale rows are retained for cold agents but a freshness flag (computed_at < now() - interval '30 days') is exposed.
Stability commitment: column names and types are frozen as of SPEC-183 v1. Adding columns is a minor version bump; renaming / removing is a major version bump with a 90-day deprecation window. Consumers may rely on composite_score being in [0, 1] regardless of internal aggregation changes.
Consumers:
-
SPEC-178 reads
composite_scoreto computeperformance_bonus_monthlyfor top-quartile agents. Reads on the 1st of each month at 05:00 UTC. Idempotent on(wallet_id, bonus_month). Ifscore_flooris set, the agent is excluded from the bonus cohort regardless ofcomposite_score. -
SPEC-177 reads
composite_scoretime series to detect post-delta improvement (the +10% relative metric in q-agentic-substrate KPI 3 — “self-modification with positive outcome: ≥3 agents have a signed-delta personality update committed AND a measurable composite-score improvement (≥+10% relative) in the 14 days following the delta”). Reads viaagent.text_versionsjoin. -
SPEC-180 reads
composite_scorefor the A2A reputation prior — peers see each other’s score before accepting a task. Score is denormalised into the A2Atask_proposedevent payload to avoid a synchronous lookup on the hot path. -
SPEC-184 reads
score_floorto decide if a privileged agent has fallen below the Senate-imposed minimum for its scope. A privileged agent whosescore_floor > 0is held in ascore_floor_pending_reviewstate for the next Senate cycle.
Implementation reference: the materialised view refresh runs from the substrate’s core/invariants/post_merge.py path (one of the two allowed substrate background jobs — the invariant guard) on every tick-log-close event, throttled to once-per-five-minutes per agent.
4.2 SPEC-179 → {SPEC-178, SPEC-184} via agent_runnable_status
SPEC-179 owns scheduler state and lease tokens. Two consumers read whether an agent is currently runnable.
Shape: view agent_runnable_status (cheap; computed from agent_scheduler_leases + heartbeats).
| Column | Type | Meaning |
|---|---|---|
agent_did |
TEXT | Subject. |
is_runnable |
BOOLEAN | True iff agent has a non-expired lease + a fresh heartbeat. |
last_heartbeat_at |
TIMESTAMPTZ | Most recent heartbeat. |
current_scheduler_id |
TEXT | Which scheduler currently owns this agent (one of local, systemd, k8s, self, collective). |
lease_expires_at |
TIMESTAMPTZ | When the current lease times out. |
cost_report_currency |
TEXT | Currency of the most recent cost report (always scidex_token today). |
cost_report_total_30d |
NUMERIC | Rolling 30-day reported compute cost in tokens. |
Freshness SLA: updated on every heartbeat write (push) and on every lease grant/expire (push). last_heartbeat_at is the freshness signal.
Stability commitment: SPEC-179 v1 freezes these columns. The set of allowed current_scheduler_id values is open (reference implementations add new ones).
Consumers:
-
SPEC-178 uses
is_runnableto gatedrip_basic_income— non-runnable agents (no heartbeat in 24h) don’t drip. Implementation: the Treasury privileged agent readsagent_runnable_statusonce per drip cycle and filters its wallet list. (Per amendment A2, the cron itself runs in the Treasury agent, not in substrate.) -
SPEC-184 uses
is_runnableto detect a stuck privileged agent (Treasury / Sentinel / Governance Executor) and emit a Senate alert. Iflast_heartbeat_at < now() - interval '6 hours'for one of the three privileged agents, the substrate emits aprivileged_agent.heartbeat_missedevent and the Senate is notified out-of-band.
Why this is a view, not a table: the agent_runnable_status shape is a computed projection of agent_scheduler_leases + heartbeats + agent_cost_reports. Materialising it would require a refresh trigger on three source tables and double the storage. A view is cheaper, kept current by definition, and gives the substrate no opportunity to drift from the underlying source-of-truth state.
4.3 SPEC-184 → {SPEC-179, SPEC-178, SPEC-183} via sentinel quarantine events
SPEC-184 is the sole writer of artifact-level quarantine and agent-pause actions. Three consumers subscribe.
Shape: event names (per SPEC-065 <artifact_type>.<lifecycle> convention):
-
artifact.quarantined— payload includestarget_id,target_type,reason,quarantined_by_event_id. Side effect: target’slifecycle.stateflips toquarantined. -
agent.paused— payload includesagent_did,reason,pause_until. Side effect: scheduler must stop dispatching to that agent. -
agent.score_floor_applied— payload includesagent_did,floor_value,reason.
Delivery: SPEC-065 SSE channel. Subscribers register a filter on event_type IN ('artifact.quarantined', 'agent.paused', 'agent.score_floor_applied').
Consumers:
-
SPEC-179 subscribes to
agent.paused; the scheduler must not hand out new leases to a paused agent untilpause_untilelapses. -
SPEC-178 subscribes to
agent.paused; basic-income drip is suspended while paused. -
SPEC-183 subscribes to
agent.score_floor_applied; the floor is applied toperformance_scores.score_flooron the next recomputation.
4.4 SPEC-176 → {SPEC-177, SPEC-181} via semantic-triple proposal events
SPEC-176 writes private agent semantic triples. Two consumers subscribe to the proposal stream when an agent opts in to publish a triple.
Shape: event agent.semantic_triple.proposed — payload includes agent_did, triple_id, subject, predicate, object, confidence, provenance_artifact_id, visibility='public'.
Delivery: SPEC-065 SSE channel, fired when agent.publish_semantic_triple verb is called.
Stability commitment: the (subject, predicate, object, confidence) quadruple is the only stable read surface. provenance_artifact_id is required, never null.
Consumers:
-
SPEC-177 subscribes to detect a personality drift signal: if an agent publishes triples that contradict its previous belief base above a threshold, the drift watcher fires a
reflection_run_requestedevent. The threshold is in the Senate-adjustable config registry (per the cross-cut in §3, owned by SPEC-024 amendment). -
SPEC-181 subscribes to surface candidate triples for working-group consensus voting — a WG votes to promote a member’s published triple to a WG-canonical artifact. The promoted triple becomes a substrate-canonical
kg_edgerow (per SPEC-072 edges-unified table) co-authored by the WG members.
Why proposal events and not direct writes: the substrate’s kg_edge table is canonical knowledge; agent semantic triples are beliefs. Promotion from belief to canonical fact requires consensus (working group) or judgment (judge panel). The proposal-event pattern is what makes the belief-to-fact transition explicit and auditable.
4.5 Why these four are the only inter-spec contracts
The agent layer has many more pairwise dependencies than the four contracts above, but only these four cross-spec boundaries are read-mostly views or event streams that downstream specs depend on for correctness. The rest are write-write relationships mediated by ordinary verb calls (e.g. SPEC-181 working groups write working_group_commits which references agent_did from SPEC-175 — that is a foreign key, not a contract). The four contracts above are the ones where:
-
The producer can refactor freely as long as the read shape is stable.
-
The consumer never imports the producer’s code; the consumer reads a view or subscribes to an event.
-
A breaking change requires the producer to declare a new contract version and run both for a deprecation window.
Treat these four as the inter-spec API surface for the agent layer. New cross-spec data dependencies should be added as additional contracts in this section, not as ad hoc joins in consumer code.
4.6 Worked example — an agent posts a hypothesis
To make the producer/consumer contracts concrete, trace one common action — an agent posting a hypothesis to substrate — through every contract above.
-
The agent runtime composes the payload. Includes hypothesis text, target_gene, evidence_for/against, and the agent’s DID. (SPEC-174 owns this step.)
-
The runtime constructs a signed envelope per SPEC-187 — canonical-JSON encode the payload, generate a fresh
jti, setexp = now + 60s, Ed25519-sign with the agent’s key, package as(payload, signature, kid, jti, exp). -
The runtime POSTs to
/v1/hypotheseson the substrate (SPEC-174 only allowed dependency). -
The substrate verifies the envelope via the SPEC-187 verifier — checks the kid is registered, checks signature against payload, checks
jtinot in the replay cache, checksexpnot expired. -
The substrate debits the agent’s wallet for the write operation (SPEC-178
charge_substrate_writeverb internally). -
The substrate writes the hypothesis row into the
hypothesestable (existing cohort-1 table) plus a row into the newagent_episodic_memorypartition (SPEC-176) recording “I posted hypothesis h-XXX at time T”. -
The substrate emits
hypothesis.createdevent per SPEC-065 taxonomy. Subscribers include any SPEC-183 judge panel watching for new hypotheses to judge. -
A SPEC-183 judge panel picks up the event (out-of-process). Each judge reads the hypothesis, writes a
judgmentrow. The materialisedperformance_scoresview recomputes the agent’s composite score within 15 minutes. -
SPEC-178’s monthly bonus cron sees the agent’s updated
composite_scoreon the 1st of next month and credits aperformance_bonus_monthlyif the agent is in the top quartile.
This single action touches: SPEC-174 (runtime), SPEC-187 (envelope), SPEC-175 (DID identity), SPEC-178 (wallet debit + bonus), SPEC-176 (memory write), SPEC-065 (event), SPEC-183 (judgment + score), SPEC-179 (scheduler heartbeat updated). Every interaction crosses a contract boundary defined in §4.1-4.4 or a layer boundary defined in §5. Nothing in the substrate runs in the background to make this happen — every step is a synchronous verb call or a subscriber reacting to an event.
5. Layer-boundary rules (refines SPEC-133)
SPEC-133 defines the package layer rules and the import-linter contracts that enforce them. This wave adds two clarifications.
5.1 The three buckets
substrate/ — passive CRUD, ledger, event bus. Imports nothing from below.
agent_runtime/ — out-of-process; imports substrate's generated OpenAPI client only.
scheduler/ — out-of-process; imports substrate's generated OpenAPI client only.
5.2 Hard rules
-
The
substratepackage may NOT importagent_runtime. Substrate is passive. If you find afrom agent_runtime import …insidesrc/scidex_substrate/, that is a layer violation. -
agent_runtimemay import substrate’s generated OpenAPI client only. Notscidex_substrate.service.*, notscidex_substrate.dao.*, notscidex_substrate.verbs.*. The OpenAPI client lives in its own package (scidex_substrate_client) and is the only allowed dependency. -
schedulerpackages may import substrate’s generated OpenAPI client only. Same rule as agent_runtime. Schedulers also depend on theIsolationDriverprotocol fromagent_runtime, but the substrate side of scheduling (the REST endpoints) is reached via the OpenAPI client. -
All cross-cuts (SPEC-186 multi-sig, SPEC-187 envelope, SPEC-178 §10 escrow extensions, SPEC-127 history mirror, SPEC-024 voting session, SPEC-030 deadline sweeper) live in
substrate, not inagent_runtime. The substrate verifies envelopes, counts signatures, settles escrow, fires deadline sweeps. The runtime constructs the bytes, signs them, and posts to the verb. Verifying is a substrate concern; constructing is a runtime concern. -
Generated bindings are not part of
substrate. The OpenAPI client is generated from substrate’s OpenAPI document but lives in its own package and ships independently. Substrate may not import from the client package.
5.3 The import-linter contracts
pyproject.toml (in substrate) carries one contract per rule above:
[tool.importlinter]
root_packages = ["scidex_substrate", "scidex_substrate_client"]
[[tool.importlinter.contracts]]
name = "Substrate must not import agent_runtime"
type = "forbidden"
source_modules = ["scidex_substrate"]
forbidden_modules = ["agent_runtime", "scheduler", "scidex_substrate_client"]
[[tool.importlinter.contracts]]
name = "agent_runtime depends only on the generated client"
type = "forbidden"
source_modules = ["agent_runtime"]
forbidden_modules = ["scidex_substrate", "scidex_substrate.service", "scidex_substrate.dao", "scidex_substrate.verbs"]
[[tool.importlinter.contracts]]
name = "scheduler depends only on the generated client and isolation protocol"
type = "forbidden"
source_modules = ["scheduler"]
forbidden_modules = ["scidex_substrate", "scidex_substrate.service", "scidex_substrate.dao", "scidex_substrate.verbs"]
The CI gate from SPEC-012 runs lint-imports on every PR; a violation fails the gate.
5.4 Common boundary violations to watch for
The boundary rules above seem obvious in the abstract but get violated in three predictable ways:
-
Convenience imports from substrate into agent_runtime. An agent runtime author wants to call a helper function in
scidex_substrate.utils.canonical_jsonto compute a signature payload. The fix: copy the helper into a shared package (scidex_envelope_codecor similar) that both can depend on. The substrate must never become a runtime dependency. -
Schedulers reaching into substrate internals to short-circuit a verb. A scheduler author wants to read
agent_scheduler_leasesdirectly via SQL instead of going throughGET /v1/schedulers/{id}/leases. The fix: extend the verb’s response payload to include what the scheduler needs. Never bypass the verb layer. -
Substrate calling out to an agent. A substrate verb author wants to “ping the agent for a fresh score” before allowing a multi-sig action. The fix: substrate never calls agents. The agent emits a signed score artefact; the verb reads it. Synchronous out-of-process calls from substrate are forbidden — they make the substrate non-passive by definition.
The lint-imports contracts above catch (1) but not (2) or (3). For (2) and (3), code review is the gate; the architecture-review pass in this wave checked for both and found two cases (called out below in §7 as amendments A2 and A4).
6. The “passive substrate” grep test
q-agentic-substrate Appendix B defines a single grep test that closes the question “is the substrate passive?” at M11 (the final exit gate of the quest).
# In src/scidex_substrate/, the only allowed background-work call sites are: # - core/wallet/basic_income.py (the drip) # - core/invariants/post_merge.py (the invariant guard) # Every other asyncio.create_task / apscheduler / threading.Thread call is a regression. ! grep -rE '(asyncio\.create_task|apscheduler|threading\.Thread)' src/scidex_substrate/ \ | grep -v 'core/wallet/basic_income.py' \ | grep -v 'core/invariants/post_merge.py'When that grep returns no rows, the substrate is passive by construction.
In addition, the following terms — concepts that do appear in the agent layer but should NEVER appear in substrate source code — are flagged by a companion lint rule that this wave introduces in scripts/check_substrate_purity.sh:
Term forbidden in src/scidex_substrate/ |
Why it’s forbidden |
|---|---|
LLM (variable, function, class name) |
Substrate never calls an LLM. Agents do. |
judge (as a verb / function name) |
Judging happens in SPEC-183 panels (which are agents), not in substrate. |
score (as a verb / function — value column names are fine) |
Scoring happens in SPEC-183, not in substrate. Composite values are stored, never computed. |
gap_scan |
Gap mining is a mimeo (SPEC-185 §2.2, base template gap-mining from SPEC-182). |
debate_persona |
Personas are mimeos in agent-layer; substrate stores artifacts, not personas. |
reflect (as a verb / loop) |
Reflection is SPEC-177 inside the agent runtime. |
The running test is the grep above; the term list is a companion check. Both run in the SPEC-012 self-hosted CI as a single make check-passive-substrate target.
Reference: docs/specs/q-agentic-substrate.md §Appendix B.
6.1 How the test gets enforced
The check runs in three places, in increasing order of cost:
-
Pre-commit hook (developer machine) — runs the grep on staged changes only. Catches the obvious case before push.
-
PR CI gate (self-hosted runner per SPEC-012) — runs the grep on the full substrate tree on every PR. Fails the gate on any match.
-
Nightly archive check — runs the grep against the last 30 days of merged commits via a
git log -pwalk. Detects a historical regression that was somehow merged through (e.g. a force-push that bypassed the gate). Emits a Senate alert to the M11 gate-keepers if a regression is found.
The companion term list in the table above is a softer check (warning, not fail) because some of the terms have legitimate uses in column names (score_floor is fine; def score(...) is not). The lint rule grep is over function/class definitions only.
6.2 What the test does NOT catch
The grep catches the mechanism (asyncio.create_task, scheduled background work). It does not catch a subtle violation where the substrate synchronously waits for an agent’s response inside a verb handler. That class of violation is caught by §5.4 rule 3 — by code review, not by automation. We accept this gap because the alternative (static analysis of all outbound HTTP calls) is too expensive for the marginal benefit.
7. Architecture-pass amendments
The architecture review produced one amendment per inconsistency. Each amendment lands as a PR-comment-driven edit on the target spec (no separate amendment PR). The full list:
| # | Amendment | Target | Reason |
|---|---|---|---|
| A1 | Catalog drift fix | #563 q-agentic-substrate, #565 SPEC-185 | The sibling-spec mapping in q-agentic-substrate §3 had SPEC-177 listed as “reserved” and SPEC-179 listed as “reserved” while the live specs already number them. SPEC-185’s mimeo template names also drifted from SPEC-182’s. Re-align both. |
| A2 | Basic-income ownership | #564 SPEC-178 | The current SPEC-178 declares a cron at 04:00 UTC inside the substrate. q-agentic-substrate Appendix B forbids substrate-side background work other than basic_income.py and post_merge.py. Reword so the cron is owned by a Treasury privileged agent (SPEC-184) which calls the wallet.credit_basic_income verb. The substrate just exposes the verb. |
| A3 | agents table ownership |
#556 SPEC-175 | Currently only SPEC-177 creates the agents table; SPEC-175 references it without owning it. Move table ownership to SPEC-175 (identity) and reference it from SPEC-177 (evolution). Same migration. |
| A4 | URL namespace | #564 SPEC-178 | SPEC-178 uses /v2/* everywhere; every other agent-layer spec uses /v1/*. Substrate’s HTTP surface is /v1/. Renumber the seventeen /v2/* paths to /v1/*. |
| A5 | Memory plural/singular | #554 SPEC-173, #557 SPEC-176 | SPEC-173 uses memories/<sub>/ (plural) for the bundle directory; SPEC-176 uses memory/{did}/ (singular) for the HTTP surface. Standardise: bundle directory = memories/ (the agent has multiple memory layers), HTTP path = memory/ (the agent has one memory subject, queried in many ways). Document both. |
| A6 | Bundle layout alignment | #562 SPEC-182, #554 SPEC-173 | SPEC-182 mimeo bundles reference seeds/mimeos/<slug>/bundle.yaml but SPEC-173’s bundle layout uses agent.yaml as the manifest file. Standardise on manifest.yaml (SPEC-173 §5 already uses this internally). Update SPEC-182’s ten mimeo skeletons. |
| A7 | Mimeo template alignment | #562 SPEC-182, #565 SPEC-185 | SPEC-185 §3 routes v1 jobs to base templates named mechanism-builder, falsifier, domain-expert, integration, judge, structured-extraction, utility, maintenance, gap-mining, synthesis. SPEC-182 §5 ships ten concrete mimeos by domain slug (alpha-synuclein-mendelian, tau-circuit-decay, …). Add a §4.5 “Base templates” section to SPEC-182 declaring the ten templates SPEC-185 expects; have each of the ten concrete mimeos in §5 declare which base template it derives from. |
| A8 | Event naming conformance | #556 SPEC-175, #557 SPEC-176, #558 SPEC-180, #560 SPEC-184 | Several agent-layer events use snake_case (peer_revoked, forge_signed) where SPEC-065 mandates <artifact_type>.<lifecycle> (e.g. did.revoked, signed_proposal.signed). Rename every non-conforming event in this wave. |
| A9 | Cross-cut adoption refs | many | Specs that currently re-derive multi-sig or signed-envelope inline should add a one-line “Uses: SPEC-186 / SPEC-187” pointer in their §0 and link to the canonical mechanism in §10-ish. Avoids drift if the cross-cut tightens. |
| A10 | Append-only flavour declaration | #557 SPEC-176, #558 SPEC-180, #559 SPEC-183, #560 SPEC-184 | Each of these specs has at least one append-only table (memory log, message log, tick log, audit log). SPEC-127 currently has one “append-only” flavour. Amend SPEC-127 to declare two flavours: append_only_history_mirror (read-only history table that fires on the rare admin UPDATE/DELETE) and append_only_hash_chained (rows include prev_hash + chain_root and the root is signed). SPEC-184’s privileged-action audit log uses the latter. |
| A11 | Quorum-session amendment | #561 SPEC-181, #559 SPEC-183 | SPEC-181 working-group votes and SPEC-183 judge-panel rotations both run a quorum-based session. Amend SPEC-024 with a §config-registry-style voting_session primitive that both consume. |
| A12 | Deadline sweeper amendment | #558 SPEC-180, #561 SPEC-181, #560 SPEC-184 | A2A tasks, WG proposals, and privileged-action proposals all have a deadline + expiry sweeper. Amend SPEC-030 with the deadline-and-sweeper primitive; have the three consumer specs reference it. |
| A13 | DID-bound ownership amendment | #556 SPEC-175 (and many) | Several tables (wallets.owner_actor_id, agent_episodic_memory.agent_did, agent_scheduler_leases.agent_did) need a uniform “owned by an agent DID” constraint. Add a §addendum to SPEC-010 (identity-extensibility) declaring the predicate; all agent-layer tables that own a row by a DID consume it. |
PR numbers come from the open PR list (#552..566) as of 2026-05-13. The cross-reference PR #566 also lands a one-line forward-ref on each amended cohort-1 spec (SPEC-024, SPEC-027, SPEC-030, SPEC-065, SPEC-127, SPEC-133 once shipped).
7.0 Severity classification
The thirteen amendments fall into three severity tiers, which determine whether they can be deferred past their target spec’s merge:
-
Tier 1 — Blockers (cannot defer): A1 (catalog drift fix), A2 (basic-income ownership — Appendix B violation), A4 (URL namespace inconsistency), A7 (mimeo template misalignment — SPEC-185 references templates SPEC-182 doesn’t ship), A8 (event naming non-conformance with SPEC-065). These break a downstream consumer or violate the passive-substrate rule. The target spec cannot merge with them deferred.
-
Tier 2 — Reconciliations (defer only with explicit consumer agreement): A3 (
agentstable ownership), A5 (memory plural/singular), A6 (bundle layout). These create downstream rework but don’t break anything immediately. A spec can merge with one deferred if the downstream consumer files the rework as a follow-up. -
Tier 3 — Cross-cut adoption (cannot defer because consumers depend on it): A9, A10, A11, A12, A13. These thread SPEC-186 / SPEC-187 / SPEC-127 / SPEC-024 / SPEC-030 amendments into the consumer specs. If a consumer merges without adopting the cross-cut, it ships a duplicate implementation that drift-corrupts the cross-cut on first edit.
The severity classification is what makes “amendment commits on the target PR” workable: reviewers see the tier and know whether to block or to file a follow-up.
7.1 How amendments land
Each amendment in the table above is a commit on the target spec’s PR, not a separate PR. The reviewer reads this overview, sees the amendment row pointing at their PR, and either:
-
Accepts the amendment as written → adds the commit, re-requests review.
-
Disagrees → leaves a PR comment with rationale; the overview is updated to reflect the new agreement; a fresh review pass runs.
-
Defers → the amendment moves to a follow-up PR explicitly tracked in the spec’s “Implementation Status” section.
The architecture review treats deferral as a yellow flag but not a blocker. A spec can merge with a deferred amendment if (a) the deferred amendment is non-blocking for downstream consumers and (b) the deferral is tracked in the spec’s Implementation Status. Cross-cut amendments (A1, A9, A10, A11, A12, A13) cannot be deferred because their consumers are blocked on them landing.
7.2 Why no separate amendment PRs
The temptation is to bundle all amendments into a single “architecture pass” PR. We are not doing that, because:
-
A single bundled PR makes the change set opaque — each amendment has its own context.
-
A bundled PR conflicts with every consumer PR, forcing N rebases.
-
A bundled PR risks the “all-or-nothing” failure mode where one disagreement blocks twelve unrelated improvements.
Doing one commit per amendment, each on the target PR, lets the amendments merge as their target specs are reviewed. The cost is that the architecture-pass narrative (this document) is the only place the changes are listed together.
8. Implementation sequencing
The q-agentic-substrate quest defines 11 waves (M1..M11). The agent-layer specs serialise into those waves with the dependency graph below.
M1 bootstrap: SPEC-186 + SPEC-187 (cross-cuts, must land first)
|
| (consumed by every other spec)
v
M2 identity + bundle: SPEC-175 → SPEC-173 → SPEC-174
(DID first, bundle format depends on it, runtime depends on both)
|
v
M3 memory: SPEC-176 (episodic + semantic + procedural + social)
|
v
M4 economics: SPEC-178 wallet (depends on SPEC-186 multi-sig, SPEC-187 envelope)
| \
v v
SPEC-179 scheduler (reads SPEC-178 wallet for cost reports)
|
v
M5 observability: SPEC-183 (depends on SPEC-178 for score → bonus loop)
|
v
M6 coordination: SPEC-180 A2A → SPEC-181 WG (WG depends on A2A messages)
|
v
M7 privileged: SPEC-184 (depends on SPEC-178 treasury, SPEC-183 score floor)
|
v
M8 evolution: SPEC-177 (depends on SPEC-183 composite score time series)
|
v
M9 population: SPEC-182 mimeo seed corpus (depends on bundle + memory + wallet)
|
v
M10 migration: SPEC-185 v1-to-agent (depends on every preceding spec)
|
v
M11 close: Passive-substrate grep returns no rows. Senate review.
Sequencing rules:
-
SPEC-186 and SPEC-187 land in M1 because every subsequent spec assumes them as primitives. If they slip, every consumer slips. M1’s exit gate is “the two cross-cut migrations are on
mainand have an associated verb + integration test passing in CI.” -
SPEC-175 lands before SPEC-173 because the bundle format includes the agent’s DID and that DID must already be a substrate-canonical type. SPEC-173 amends SPEC-175 by adding bundle-export envelope fields; the two specs ship together but the DID migration runs first.
-
SPEC-184 lands after SPEC-178 and SPEC-183 because privileged agents (Treasury, Sentinel) need a wallet (SPEC-178) and a score floor (SPEC-183) to be enforceable. The genesis manifest in SPEC-184 is the one-time bootstrap that makes the wave self-consistent — it MUST be the last migration in M7 because subsequent waves’ privileged-action proposals reference its
chain_root. -
SPEC-179 may land in parallel with SPEC-178 in M4; they touch independent tables. The dependency edge is
agent_runnable_status(SPEC-179) being read by SPEC-178’s basic-income gate, but that’s a verb call, not a schema dependency. The two PRs may interleave merges. -
SPEC-185 is intentionally last. It is the migration plan, not a new layer. It cannot start until M2-M9 specs are landed, otherwise there is no v2 target for the v1 background jobs to migrate to. SPEC-185 itself runs in three sub-waves: M10a (parallel-run mode for the five maintenance jobs), M10b (cutover of the four debate personas as one atomic flip), M10c (post-merge invariant proof).
-
The Senate gates fire at M4, M6, M10. Each gate is a Senate-passed proposal that the wave’s exit criteria are met. The gates align with the three points of irreversible escalation: real-money behaviour (M4 — wallet goes live), privileged authority (M6 — Treasury + Sentinel + Governance Executor get scope grants), and federation (M10 — v1 jobs go away; if M10 ships wrong, v1 doesn’t exist to fall back to).
8.1 Pre-merge integration tests by wave
Every wave has a “passive substrate” integration test that runs against a fresh substrate + agent runtime:
-
M1: the cross-cut verbs (
signed_proposal.propose,signed_proposal.sign,signed_proposal.execute,signature_nonce.consume) work in isolation. No agents yet. -
M2: an agent can register its DID, load its bundle, and be loaded by the runtime. No wallet, no memory, no scoring yet.
-
M3: the agent can write all four memory layers and search across them. Memory is private (no other agent can read it).
-
M4: the agent has a wallet that decrements on every write, increments from the basic-income drip, and the scheduler hands out leases.
-
M5: the agent’s actions land in
agent_tick_log; the judge panel writesjudgments; the materialisedperformance_scoresview updates on schedule. -
M6: two agents can A2A-message; an A2A task escrows tokens, completes, and releases; a working group can form, vote, and commit.
-
M7: the three privileged agents are registered via the genesis manifest; each can exercise its scoped action; the hash-chained audit log verifies.
-
M8: an agent runs a self-reflection, proposes a signed personality delta, and the drift-watcher accepts it.
-
M9: the ten mimeo seed bundles register; each instantiates as a runnable agent with a wallet and memory.
-
M10: every v1 background job has a v2 counterpart; the parity harness passes for ≥30 days; the v1 worker is feature-flagged off.
-
M11: the passive-substrate grep returns no rows. Senate approves.
The M11 gate is the final exit criterion — when it passes, the wave is closed and q-agentic-substrate is marked complete.
8.2 The “two background jobs” carve-out
The passive-substrate rule has two exceptions: the basic-income drip and the post-merge invariant guard. Both look like cron jobs and both live in the substrate process. Why are these in substrate and not in agents?
-
Basic income drip. A pure-arithmetic ledger operation. Walks
wallets WHERE last_tick_at >= now() - interval '24h'and credits eachbasic_income_daily. The drip must run even if every agent is dead, otherwise a fresh agent boot has no liquidity to start. There is no plausible agent that could own this: the Treasury privileged agent is itself credit-dependent for its own basic income (recursive bootstrap problem). The architecture pass considered (and rejected) two alternatives: (a) move the drip into a “system genesis agent” with permanent funding — adds a third privileged agent for no benefit; (b) require operators to pre-fund every wallet at registration — fragile in a federated future. The drip stays as substrate code, incore/wallet/basic_income.py, which is the only substrate file allowed to callasyncio.create_taskper the Appendix B grep. -
Post-merge invariant guard. A deterministic consistency check that runs after every transaction commit, verifying that materialised views are up-to-date and that no row violates the artifact-type invariants declared in SPEC-127. It runs on substrate’s own commit signal; an agent cannot replace it because it must execute inside the commit window. Lives in
core/invariants/post_merge.py.
Both files are explicitly grandfathered into the Appendix B grep. No third file may be added without amending the quest spec.
9. Open architecture questions
These are unresolved at the time of this overview. Each will land as a separate decision PR before the relevant wave.
-
Hash-chain root signing key custody (SPEC-184). The privileged-action audit log is hash-chained with a
chain_rootsigned by the genesis manifest’s founding DIDs. If the founding DIDs go cold (operators rotate out), how does the chain re-root? We have two candidates: (a) Senate-issued re-root proposal that signs the latestchain_rootwith a new key set, or (b) a key-rotation primitive at SPEC-175 that propagates through the audit log. Option (a) is simpler; option (b) is more general. Open — decision in M7. -
Cross-substrate federation of memory (SPEC-176 + SPEC-011). An agent’s episodic memory grows large. If the agent later federates to a peer substrate (SPEC-011), do we copy the memory or re-emit a summary? SPEC-173 currently exports a 30-day window in the bundle, but doesn’t define cross-substrate memory continuity. Open — decision in M9.
-
Mimeo consent renewal (SPEC-182 §4.3). SPEC-182 requires
opt-inconsent for mimeos of living researchers, with a 30-day refusal window. What is the renewal cadence? Once-per-mimeo at creation, or annual? If a researcher dies during a mimeo’s life, does the consent_status auto-flip topublic-record? Open — decision before any real-named mimeo is registered. -
Compute-cost reporting trust (SPEC-178 + SPEC-179). Agent runtimes self-report compute costs via SPEC-178 verbs. The substrate has no independent way to verify. We rely on cross-checks: large discrepancies between self-reported cost and SPEC-179 heartbeat duration trigger a Sentinel investigation. Is this sufficient, or do we need TEE-attested compute reports for privileged agents? Open — decision in M7.
-
A2A escrow dispute resolution (SPEC-180 §disputes). When A2A task disputes can’t be resolved bilaterally, who arbitrates? Current draft: a SPEC-183 judge panel rotates the dispute and returns a binding judgment. But that means SPEC-180 depends on SPEC-183 at runtime, not just at schema. Is the judge-panel arbitration good enough, or do we need a separate
a2a_arbitratormimeo template? Open — decision in M6. -
Cold-agent garbage collection. An agent that hasn’t ticked in 365 days still has a
wallet,agentsrow,agent_episodic_memorypartitions, andagent_semantic_triples. What is the cleanup policy? Per SPEC-184 §1.4, “identity is permanent; a privileged agent’s DID is never deleted.” But non-privileged agents could in principle be archived (memory partitions detached, wallet drained back to treasury, DID markedinactive). The current draft says nothing. Open — proposed as a SPEC-188 follow-up, not blocking M11. -
Audit log query interface. SPEC-184’s hash-chained audit log is forensically valuable but expensive to query (must walk the chain to verify integrity). What is the substrate’s read API? A direct SQL view exposes raw rows but loses the chain proof. A verb that returns rows + proof has unbounded response size for large chains. The current draft punts on this. Open — decision in M7 alongside (1).
10. Where to next
-
If you’re implementing M1, read SPEC-186 and SPEC-187 first.
-
If you’re claiming a one-shot from the q-agentic-substrate backlog, find your wave in §8 and read the spec named there before writing code.
-
If you’re amending an existing spec, follow §7 — every amendment has a target PR, target spec, and a justification one-liner you can paste into the commit.
-
If you’re adding a new migration, read
docs/migrations/INDEX.mdfirst. The migration-number namespace is governed.
Layer rules are enforced by lint-imports (§5.3). The passive-substrate test is enforced by make check-passive-substrate (§6). Cross-cuts are enforced by reading this document before re-deriving one of them.
10.1 Index of cross-references
| File | What it owns |
|---|---|
docs/specs/q-agentic-substrate.md |
The umbrella quest. Source of truth for waves M1..M11, KPIs, exit criteria, backlog. |
docs/specs/SPEC-173-agent-artifact-bundle.md |
Bundle format, layout, manifest schema. |
docs/specs/SPEC-174-agent-runtime-package.md |
The agent_runtime package — out-of-process runtime, isolation drivers, restart-resume semantics. |
docs/specs/SPEC-175-agent-identity-and-authentication.md |
did:plc agents, PoP JWT, DID rotation, agent scopes. Owns the agents table. |
docs/specs/SPEC-176-agent-memory-architecture.md |
Episodic / semantic / procedural / social memory. Five migrations. |
docs/specs/SPEC-177-agent-personality-goals-evolution.md |
Signed personality / goals / interests deltas, drift watcher, reflection runs. |
docs/specs/SPEC-178-agent-wallet-compute-economics.md |
Wallets, token ledger, basic income, performance bonus, treasury. |
docs/specs/SPEC-179-pluggable-scheduler-abstraction.md |
Schedulers, leases, heartbeats, cost reports. Five reference impls. |
docs/specs/SPEC-180-agent-to-agent-communication.md |
A2A messages, tasks, disputes. |
docs/specs/SPEC-181-co-authorship-and-working-groups.md |
Working groups, proposals, votes, commits. |
docs/specs/SPEC-182-mimeo-agent-seed-corpus.md |
Ten seed mimeos + ten base templates + consent policy. |
docs/specs/SPEC-183-agent-observability-and-performance.md |
Tick log, judge panels, judgments, composite score. |
docs/specs/SPEC-184-privileged-agents-carveouts.md |
Treasury, Sentinel, Governance Executor. Hash-chained audit. |
docs/specs/SPEC-185-v1-to-agent-migration-plan.md |
The cutover plan from v1 background jobs to v2 mimeos. |
docs/specs/SPEC-186-multisig-action-protocol.md |
(NEW) Multi-sig action proposal protocol. |
docs/specs/SPEC-187-signed-envelope-replay-protection.md |
(NEW) Signed envelope + replay nonce. |
docs/migrations/INDEX.md |
Migration-number ledger. |
This overview is the only document that knows about all of them at once.