Pins the two open scope decisions that the capability roadmap
(ADR-0016) tagged "Before Phase 3". Both are resolved with explicit
ADRs and PROGRESS.md is updated to reflect.
ADR-0017 - Agency: responsive-with-axiology
- Turn boundary stays responsive (no autonomous initiative, no
background agent loop, no inter-turn processes).
- IdentityManifold value axes become load-bearing for articulator
candidate selection (within a single turn). Goal-directedness
lives inside the turn, not across turns.
- Replay determinism is the load-bearing constraint that rules
out pure agentic loops.
- Rejects pure-responsive (would relegate identity to read-only)
and pure-agentic (would break trace_hash replay contract).
ADR-0018 - Tool use: typed deterministic operators
- Operators are pure functions over CORE's typed state. No
external IO at this stage (no shells, network, external models).
- Operator registry is curated, small, ADR-gated; no plug-in
surface, no dynamic loading.
- Operators participate in trace_hash so replay stays bit-stable.
- Initial operator set lands in Phase 3 v2: transitive_walk over
proposition graph + path_recall over vault. Closes Gap 1 + Gap 2
from the inference-closure / multi-step-reasoning / compositionality
/ cross-domain-transfer v1 findings.
- Rules out: generic plugin protocols, LLM-as-judge, approximate
retrieval, anything that breaks the exact-CGA / replay
contracts in CLAUDE.md.
Future extensions recorded but explicitly deferred: calculator
(Phase 4+), document retrieval over content-addressed packs,
metaphor / narrative / writing-style operators (downstream of
cross-domain-transfer literal case working).
This unblocks Phase 3 v2 engineering. Next: the transitive_walk +
path_recall bundle as a single bounded PR per ADR-0018, plus the
trace_hash extension to fold operator invocation records.
6.4 KiB
ADR-0018 — Tool Use Scope: Typed Deterministic Operators
Status: Accepted
Date: 2026-05-16
Authors: Joshua Shay
Supersedes: Open Scope Decisions row "Tool use (typed deterministic
operators)" in docs/PROGRESS.md.
Depends on: ADR-0017 (Agency Scope).
Context
ADR-0016 flagged tool use as an open scope decision required
before Phase 3. The capability roadmap (Phase 3 work items) notes
that multi-step reasoning may benefit from operator delegation
(docs/capability_roadmap.md). Phase 3 v1 evidence
(evals/inference_closure/gaps.md Gap 1 + Gap 2,
evals/multi_step_reasoning/gaps.md) confirms this: closing the
inference-depth gaps requires a transitive_walk operator over the
proposition graph and a path_recall operator over the vault.
The question is what shape such operators take in CORE. Three positions are available:
- No tools. Reasoning depth is implemented inline in the articulator and field-propagate machinery. No first-class operator surface.
- External tools. CORE invokes external services (calculator, search, code execution, shell) through a generic tool-use protocol.
- Typed deterministic operators. CORE exposes a small, curated set of pure-function operators over its own typed state (proposition graph, vault, field state). No external IO. Each operator is invoked synchronously inside a responsive turn (per ADR-0017).
Decision
CORE adopts typed deterministic operators:
-
Operators are pure functions over CORE's typed state. Each operator takes typed inputs (proposition-graph nodes, vault entries, field versors, relation predicates) and returns typed outputs. No side effects beyond the per-turn deterministic record.
-
No external IO at this stage. CORE will not invoke shells, network endpoints, file IO outside the existing pack/vault contracts, or other models. External tool integration is deferred to a later phase and would require its own ADR.
-
Operator registry is curated and small. Adding an operator is a deliberate design act with an ADR-level decision. No plug-in surface; no dynamic operator loading; no caller-supplied operators. The deterministic-replay contract requires the operator set to be a fixed, versioned part of the build.
-
Operators participate in trace_hash. When an operator is invoked during a turn, its name, inputs, and outputs are folded into
trace_hashso replay is bit-for-bit reproducible. This is the mechanical guarantee that makes operators safe to add. -
Operators are invoked by the articulator inside one turn. Per ADR-0017, no operator runs autonomously between turns. The articulator decides whether to invoke an operator based on the intent classification and proposition-graph shape produced for the current turn.
Initial operator set (Phase 3 v2)
Two operators land together as the bounded Phase 3 v2 engineering work that closes inference-closure Gap 1 + Gap 2:
-
transitive_walk(graph, head, relation, max_hops) -> list[Node]Deterministic traversal of the proposition graph fromheadfollowing only edges labeledrelation. Returns the path of visited nodes. Bounded bymax_hops(initial cap: 5; seeevals/multi_step_reasoning/contract.md). No approximate search. Empty path is a valid result. -
path_recall(vault, entity, relation_chain) -> list[VaultEntry]Returns vault entries that participate in the named relation chain starting fromentity. Uses the existing exact-CGA inner product for entity matching; no approximate / HNSW / ANN substitution permitted (per CLAUDE.md).
Both operators are pure functions with no global state. Both produce outputs that are themselves addressable in the proposition graph and vault, so their results round-trip through the existing pipeline.
What this rules out
- Generic plugin protocols (MCP-style). CORE does not become a host for external tools. The strict typing and replay-determinism contracts forbid arbitrary capability surfaces.
- LLM-as-judge / LLM-as-tool patterns. No operator may call out to a stochastic model.
- Approximate retrieval / search operators. Per CLAUDE.md ("Vault recall is exact and deterministic. Do not add cosine similarity, HNSW, ANN indexes, or approximate recall to the runtime path."), search-shaped operators must remain exact.
Consequences
- Phase 3 v2 has a well-defined shape. The two-operator bundle above is the unit of engineering work. It is small, testable, and replay-safe by design.
- Operator-aware trace hashing.
core/cognition/trace.pywill need a small extension to fold operator invocation records into the hash. This is one of the bounded design tasks inside the Phase 3 v2 work. - Articulator gains an operator-call site.
generate/realizer.pyand/orgenerate/graph_planner.pylearn to decide whether to invoke an operator based on intent + graph shape. This decision itself is deterministic — no learned policy. - No operator-registry hot path. Operator lookup is at the import-time level, not the per-turn level. The operator set is effectively part of the build.
Future extensions (recorded so they're not forgotten)
When (and if) external IO becomes scoped:
- Calculator (pure-function over typed numerics) is the cleanest first external operator candidate. Still typed, still deterministic, no network. Probably Phase 4 or later.
- Document retrieval over curated packs (not the open web) could become typed if the corpus is content-addressed and the result is bit-stable.
- Search / code execution / shell are out of scope for the foreseeable future. They break replay determinism and the trust-boundary discipline in CLAUDE.md.
Metaphor, narrative, and writing-style work (raised in 2026-05-16
session, recorded in evals/compositionality/gaps.md and
evals/cross_domain_transfer/gaps.md) live under this ADR's
operator umbrella if they ever land: a metaphor operator is a
typed deterministic function over the proposition graph plus a
selectivity filter, not an external capability.
Verification
- The two Phase 3 v2 operators land with unit tests showing replay-bit-stability.
trace_hashextension passes determinism tests intests/test_determinism_proofs.py.- All inference-closure / multi-step-reasoning / compositionality / cross-domain-transfer lanes are re-scored after the operator bundle lands.