Documentation
Yoke Function Call Reference
The Yoke function-call surface is the agent-facing mutation surface for the Yoke control plane. Agents call typed function ids through one envelope shape; the dispatcher routes to a handler, verifies the calling session's claim, writes through the canonical domain owner, and emits structured events. Shell-quoted JSON payloads are not the operator path: the python3 -m yoke_core.cli.db_router ... and python3 -m yoke_core.api.service_client ... CLI commands remain as retained operator/debug adapters that build a typed FunctionCallRequest internally and dispatch through the same registry.
This file is the per-family function reference. Render the operator-readable Atlas (one row per yoke subcommand with function id + help status, plus the tool-shaped CLI, permanent, and pending rosters and live promise-vs-live contradictions) locally with python3 -m yoke_core.tools.atlas_render_docs render. Cross-link back from db-reference.md for the entry-point CLI, the domain catalog, and the structured-field discipline.
Envelope
Every function call accepts and returns the same envelope shape, defined in yoke_contracts.api.function_call:
// Request
{
"function": "<family>.<subfamily>.<operation>", // registered function id
"version": 1, // optional; defaults to current
"request_id": "<uuid>", // dedup key; reusing returns the original response
"actor": { // who is calling
"session_id": "<harness_sessions.session_id>",
"actor_id": "<harness_sessions.actor_id>"
},
"target": { // typed target ref; shape depends on function
"kind": "item | epic_task | section | claim | process | none",
"public_ref": "PREFIX-N", // client-supplied PREFIX-N (or bare sequence)
"item_id": 1234, // resolved internal items.id (machine)
"epic_id": 833,
"task_num": 5,
"section_name": "Progress Log",
"process_key": "...",
"conflict_group": "..."
},
"payload": { /* function-specific typed body */ },
"preconditions": { /* optional invariant assertions, e.g. allow_empty + reason */ },
"options": { /* sync_github_body, ... */ }
}
// Response
{
"function": "...",
"version": 1,
"request_id": "...",
"success": true,
"result": { /* function-specific typed result */ },
"warnings": [{"code": "...", "step": "..."}],
"errors": [{"code": "...", "message": "..."}],
"event_ids": ["..."]
}
public_ref vs internal item_id
item_id is the internal items.id integer. public_ref is the public PREFIX-N handle. A person never reads a bare internal id — not alone, and not paired with the public handle. Machine payloads (--json, HTTP result) keep integer item_id; the dispatcher does not add a sibling ref. Human CLI output is translated at the print layer (yoke_cli.transport.public_ref_display) on a display copy: item_id / current_item_id / recent_item_id / epic_id become public_ref / current_public_ref / recent_public_ref / epic_public_ref. Lookup over HTTPS uses items.public_ref.lookup. Request targets carry target.public_ref; there is no alias for a retired target key. Handlers that already know the public handle put it on result.public_ref. DB rows, events, telemetry, and tests keep bare integer item_id.
The dispatcher always emits YokeFunctionCalled. Repeated calls with the same (function, request_id) emit DispatcherIdempotencyReplay and return the cached response verbatim. The dedup store is the function_call_ledger table (exact request_id match, written alongside the emission; rows expire after the replay TTL via the events retention prune) — events stay telemetry; the ledger owns the replay decision. Partial-state failures (the primary write succeeded but a downstream sync degraded) return HTTP 207 with success=true, warnings=[...], and a DispatcherDownstreamDegraded row in events. See the yoke source-repo doc docs/event-catalog.md for the envelope schemas.
Actor identity binding (transport-symmetric)
actor.session_id may be omitted: ambient identity resolves automatically — YOKE_SESSION_ID first, then the session variables of the harness family this process actually runs under (the nearest harness ancestor in the process tree, so a harness started inside another harness's shell never answers with the outer one's inherited variable), then that family's hook-written process-anchor registry (yoke_core.domain.session_ambient_identity). An explicit payload session always binds and is the flagged operator-debug override: when it diverges from the resolved ambient, dispatcher events carry session_override: true plus the divergent ambient_session_id in context. actor_id is never trusted from the payload — it resolves server-side from harness_sessions keyed on the bound session (a contradicting supplied value rejects with actor_id_mismatch), and over https the bearer-token actor overwrites it at the boundary.
A mutating call whose registry entry requires a session rejects with actor_session_missing when none resolves — an infrastructure-bug signal (hook registration / anchor resolution failed), not a state agents should work around. A plain terminal is the exception the message names for itself: with no harness anywhere in the process tree the refusal drops the infrastructure framing and names the supported path instead — run the command from a harness session, which is what can hold the work claim it needs. Explicitly session-optional functions never reach that refusal. They are the ones a person runs before any session exists (the onboarding wizard's Apply stages and the plain-terminal CLI recipes, enumerated in yoke_core.domain.terminal_reachable_functions and checked against the registry), and one contract attributes them all: the identity binder keeps the bearer-token actor over HTTPS and binds the universe's operating human for a local call, so a session-less write has an author without each handler resolving one. Calls whose bound session has no harness_sessions row execute where downstream gates allow but are marked provenance_unverified: true in event context on both transports — unregistered-session writes are recorded, never silently trusted.
A session's own actor follows the person who started it: a launched session binds the launching actor transitively rather than the identity of the machine it runs on. session_control. calls that act on another session (message.send, session.wake, session.terminate, keepalive.hold/release, launch.) are role-checked against the TARGET's project by yoke_core.domain.session_action_authority — project membership to message, wake, hold alive, or terminate a launched worker, project owner or org admin to terminate another actor's interactive session — and each one also writes a SessionActionPerformed event into the target session's own history carrying the acting actor. Contract: docs/archive/decisions/session-actor-follows-the-person.md.
Registry, schema, and dispatch endpoints
The FastAPI app exposes three routes mounted under /v1/functions/:
| Route | Purpose |
|---|---|
POST /v1/functions/call |
Dispatch a FunctionCallRequest; returns the typed FunctionCallResponse. |
GET /v1/functions/registry |
Enumerate every registered function id (per family) plus metadata (stability, target_kinds, claim_required_kind, adapter_status). |
GET /v1/functions/schema/{function_id} |
Return the JSON Schema for one function id's request body. |
The same registry is enumerable in-process via yoke_core.domain.yoke_function_registry.list_entries().
Compatibility surfaces. POST /v1/functions/call and GET /v1/health are compatibility surfaces: clients and servers may run different engine versions, and both endpoints stay answerable across that skew. The server advertises its engine version in the health payload (engine_version, distinct from the constant API-contract version) and as an X-Yoke-Engine-Version response header on API responses; the CLI's https relay compares the header against the locally installed version and prints one advisory stderr warning per process on mismatch — it never blocks. Skew is expected mid-rollout; align the older side when behavior looks off.
Claim verification matrix
Every registered function declares one of five claim_required_kind values; the dispatcher verifies before the handler runs.
| Value | When the dispatcher enforces |
|---|---|
None |
No work-claim verification. Reads, claims.work.acquire, and project-wide operator-requested operations (board.rebuild, agents.render.run, project_structure.patch.apply). Project/org permission checks remain independently enforced. |
"item" |
Resolves the active work-claim row for target.item_id. The calling session's session_id must match. Otherwise error.code="claim_required" (HTTP 409). |
"epic" |
Same as "item" but resolves the parent epic id from target.kind="epic_task" (target.epic_id). |
"self_only" |
The claim itself is the target (e.g. claims.work.release). The handler reads the claim row by target and asserts actor.session_id == row.session_id. |
"operator_override" |
Requires the calling session to carry an operator-authored bypass marker (e.g. path-claim-override). Otherwise error.code="operator_override_required". |
The five values are the closed enum; the registry rejects any other string at import time.
Function families
The function id grammar is <family>.<subfamily>.<operation> validated by yoke_contracts.api.function_call.validate_function_id. Families today:
items.* — creation, structured field, section, and progress-log writes
Replaces every hand-authored printf '%s' "$content" | python3 -m yoke_core.cli.db_router items update <id> <field> --stdin / item_field_transform / sections upsert recipe.
| Function id | claim_required_kind | Handler | Result shape |
|---|---|---|---|
items.structured_field.replace |
"item" |
yoke_core.domain.handlers.items_structured_field → execute_structured_write |
{old_lines, new_lines, verification_status} |
items.structured_field.append_addendum |
"item" |
same handler → item_field_transform.append_addendum |
same shape |
items.structured_field.section_upsert |
"item" |
same handler → item_field_transform_sections.section_upsert |
same shape |
items.structured_field.section_append |
"item" |
same handler → item_field_transform_sections.section_append |
same shape |
items.section.upsert |
"item" |
yoke_core.domain.handlers.items_section → sections_cli.upsert |
{section_name, content_lines} |
items.section.delete |
"item" |
same handler → sections_cli.delete |
{section_name, deleted} |
items.section.get (read) |
None |
same handler → sections_cli.get |
{section_name, content} |
items.progress_log.append |
"item" |
yoke_core.domain.handlers.items_progress_log |
{old_lines, new_lines, entry_count} (read-then-upsert with ordering=200) |
items.scalar.update |
"item" |
yoke_core.domain.handlers.items_scalar → prepare_update |
{field, old, new} |
items.get (read) |
None |
yoke_core.domain.handlers.reads.items_get |
typed item payload (optional fields[]) |
items.public_ref.lookup (read) |
None |
yoke_core.domain.handlers.items_public_ref |
{refs: {internal_id: PREFIX-N}} |
items.create |
None |
yoke_core.domain.handlers.items_create → backlog_create_op.execute_create |
{item_id, public_ref, dry_run, log, execution_instructions, execution_instructions_considered} |
Canonical create — a non-web filer attests the operator instructions:
{
"function": "items.create",
"target": {"kind": "global", "project_id": "yoke"},
"payload": {
"title": "Fix the footer",
"workflow": "dash",
"instruction": "Correct the footer and verify every link.",
"entry_surface": "cli",
"execution_instructions_considered": true
}
}
execution_instructions_considered is a bare boolean attestation — no content hash, no staleness window — that this filer ran yoke workflow execution-instruction resolve --workflow W --project P before authoring. Every non-web entry surface (cli, harness_skill) must send it true; without it the create refuses with execution_instructions_not_considered and a message naming that exact retrieval command for the target. web_form renders the blocks in its own UI and promotion carries an already-filed item forward, so both stay exempt, as do dry_run previews and disposable test databases. CLI adapters (yoke dash, yoke task, yoke items create) expose --execution-instructions-considered and pass it through; they never set it for the caller, and the create receipt echoes the value it was accepted under.
Canonical write — full-field replace:
{
"function": "items.structured_field.replace",
"request_id": "<uuid>",
"actor": {"session_id": "...", "actor_id": "..."},
"target": {"kind": "item", "item_id": 42},
"payload": {"field": "spec", "content": "# Spec\n\n..."},
"options": {"sync_github_body": true}
}
Canonical write — additive transform (preserves prior content, appends a ## heading-led block):
{
"function": "items.structured_field.append_addendum",
"target": {"kind": "item", "item_id": 42},
"payload": {
"field": "spec",
"heading": "Refinement Addendum (2026-05-13)",
"source": "refine",
"content": "..."
}
}
The same handler accepts items.structured_field.section_upsert (replace a ## heading-led block in place) and items.structured_field.section_append (append after the block). All variants preserve the empty/shrinkage/freeze guards on execute_structured_write and report old/new line counts plus a verification status.
Canonical write — Progress Log entry:
{
"function": "items.progress_log.append",
"target": {"kind": "item", "item_id": 42},
"payload": {"headline": "kicked off engineer dispatch", "content": "..." }
}
The handler reads the existing Progress Log section, appends a timestamped entry, and upserts at ordering=200 (the canonical Progress Log convention — see AGENTS.md § Progress Log). CLI adapter: yoke items progress-log append PREFIX-N --headline TEXT --content TEXT (or --content-file PATH).
item_worktrees.* — explicit additional lanes, reads, and recovery
| Function id | claim_required_kind | Handler | Notes |
|---|---|---|---|
item_worktrees.create |
"item" |
yoke_core.domain.handlers.item_worktree_create.handle_create |
With an empty payload, idempotently ensures the sole policy-required default lane (PREFIX-N); with lane_role + branch, registers one explicit worker or integration lane. The item must be active and claimed, the path-claim worktree gate must pass, and the branch must be valid and project-unique. Multiple workers remain allowed; a second integration lane and branch-role reuse are refused. |
item_worktrees.get |
None (read) |
yoke_core.domain.handlers.item_worktrees.handle_get |
Returns one active lane selected by payload.lane_role; result.worktree is null when no matching lane exists. |
item_worktrees.list |
None (read) |
yoke_core.domain.handlers.item_worktree_paths.handle_list |
Returns every active lane in result.worktrees, preserving repeated worker lanes instead of collapsing by role. |
item_worktrees.path_record |
"item" |
yoke_core.domain.handlers.item_worktree_paths.handle_path_record |
Records an absolute machine-local path after provisioning. Requires the active item claim plus preconditions.worktree_id and preconditions.branch; a released/replaced lane or changed branch fails stale instead of updating another row. |
item_worktrees.release |
"item" |
yoke_core.domain.handlers.item_worktrees.handle_release |
Evidence-only recovery for a post-implementation stage of the item's pinned workflow on a single-implementation-lane item. Requires the fixed evidence-only-recovery reason and a fresh clean-lane attestation matching the sole active lane. The refusal names the accepted stages. |
Ensure the policy-required default lane with yoke item-worktrees create PREFIX-N; register an additional branch with yoke item-worktrees create PREFIX-N --lane-role worker --branch BRANCH (use integration for the one optional integration lane). Inspect the complete active set with yoke item-worktrees list PREFIX-N --json. Ordinary worktree preparation consumes that authoritative list over either local Postgres or HTTPS, provisions every lane locally, then records each exact path through yoke item-worktrees path-record PREFIX-N --worktree-id ID --branch BRANCH --path ABSOLUTE_PATH; the path-record adapter requires the item claim and sends lane-id/branch stale-state preconditions.
The read and recovery adapters are yoke item-worktrees get PREFIX-N --lane-role implementation --field branch and yoke item-worktrees release PREFIX-N --all-active --reason evidence-only-recovery. Release first verifies that the registered path is on the registered branch and has no modified tracked or untracked files; ignored-only residue is not dirt. Any dirt or unverifiable path fails closed.
workflows.* — immutable version and item-pin operations
| Function id | claim_required_kind | Handler | Notes |
|---|---|---|---|
workflows.definition.get |
None (read) |
yoke_core.domain.handlers.workflows_definition |
Lists selected immutable definitions, version history, gate catalog, and deployment flows. |
workflows.item.get |
None (read) |
yoke_core.domain.handlers.workflows_versioning |
Returns the item's exact pin, digest, stage, posture, interpreted lane policy, and active lanes. |
workflows.current.set |
"operator_override" |
same module | Selects an already-published version for subsequently created items; existing pins do not change. |
workflows.item.migrate |
"operator_override" |
same module | Atomically migrates one item when stage/posture, active lanes and claims, approval/QA gates, and delivery bindings remain representable; label-only changes are compatible, while retroactive unsatisfied gates are refused. |
workflows.item_posture.amend |
"item" |
yoke_core.domain.handlers.workflows_item_posture |
Sets, replaces, or clears ONE posture key on an already-filed item. The amendable roster is the item's pinned item_posture_allowlist; each key declares its own guard, so a key with none refuses as unamendable rather than stranding records. Refuses at a terminal stage, over a verification selection whose requirement already carries a recorded run, while path claims are registered under a selection being cleared, and while an owner decision is open on a cleared approval selection. Replacing a verification selection waives its unexecuted requirement snapshots, detaches the superseded plan, and attaches the new one in the same transaction. |
The operator adapters are yoke workflows item get PREFIX-N, yoke workflows current set WORKFLOW VERSION, yoke workflows item migrate PREFIX-N [--version N], and yoke workflows item-posture amend PREFIX-N --verification-plan ID_OR_SLUG --reason TEXT (--help carries the per-key decision tree).
workflow_item.epic_task. and workflow_item.epic_progress_note. — epic-task amendment
Replaces every hand-authored python3 -m yoke_core.domain.epic task-update-body <epic-id> <task-num> / task-upsert / direct epic_progress_notes choreography in /yoke amend and related skills.
| Function id | claim_required_kind | Handler | Notes |
|---|---|---|---|
workflow_item.epic_task.body_replace |
"epic" |
yoke_core.domain.handlers.workflow_item_epic_task.body_replace |
Wraps epic_task_crud.task_update_body; returns {old_lines, new_lines}. |
workflow_item.epic_task.split |
"epic" |
same handler → epic_amend.task_split |
Preserves dependencies; renumbers downstream tasks atomically; returns new_task_num. |
workflow_item.epic_task.reassign |
"epic" |
same handler → epic_amend.task_reassign |
Updates the worktree column; returns {old_worktree, new_worktree}. |
workflow_item.epic_task.add |
"epic" |
same handler → epic_amend.task_add |
Typed payload (title, body, dependencies, …); writes via task_upsert. |
workflow_item.epic_task.remove |
"epic" |
same handler → epic_amend.task_remove |
Cascade-removes dependency edges. |
workflow_item.epic_task.metadata_update |
"epic" |
same handler → epic_amend.task_metadata_update |
Accepts title, context_estimate, dependencies, and other epic-task scalar fields. |
workflow_item.epic_task.review_seed |
"epic" |
yoke_core.domain.handlers.workflow_item_epic_task_review.handle_review_seed |
Wraps epic.review_seed; idempotent requirement seed; auto-advances implementing → reviewing-implementation. |
workflow_item.epic_task.review_insert |
"epic" |
same module → epic.review_insert |
Payload {verdict: pass/fail (case-insensitive), body}; a pass auto-advances reviewing-implementation → reviewed-implementation. |
workflow_item.epic_task.review_get |
None (read) |
same module → epic.review_get |
Most recent review as a pipe row (id, epic_id, task_num, verdict, body, created_at); target_not_found when none. |
workflow_item.epic_task.review_list |
None (read) |
same module → epic.review_list |
Review history newest-first; {reviews, count} where count is review ROWS (bodies are multi-line); empty list is success. |
workflow_item.epic_task.body_get |
None (read) |
yoke_core.domain.handlers.workflow_item_epic_task_state.handle_body_get |
Wraps epic.task_get_body; returns the body verbatim. |
workflow_item.epic_task.update_status |
"epic" |
same module → epic.task_update_status |
Non-pipeline status write + GitHub label sync; terminal success statuses refuse with pipeline_required. |
workflow_item.epic_task.simulation_upsert |
"epic" |
same module → epic.simulation_upsert |
Epic-level target (no task_num); payload {phase, body}; parses CLEAN / GAPS FOUND; replaces prior runs for the phase. |
workflow_item.epic_task.submission_receipt_get |
None (read) |
same module → epic.submission_receipt_get |
Payload {after_note_count}; returns the validated PASS receipt line; receipt_invalid on failing fields. |
workflow_item.epic_progress_note.append |
"epic" |
yoke_core.domain.handlers.workflow_item_epic_progress_note.append |
Wraps yoke_core.domain.epic.progress_note_insert. |
Canonical write — epic task body replace:
{
"function": "workflow_item.epic_task.body_replace",
"target": {"kind": "epic_task", "epic_id": 833, "task_num": 5},
"payload": {"content": "..."}
}
Canonical write — epic progress note:
{
"function": "workflow_item.epic_progress_note.append",
"target": {"kind": "epic_task", "epic_id": 833, "task_num": 5},
"payload": {"note_num": 3, "body": "..."}
}
lifecycle.* — typed lifecycle transitions
| Function id | claim_required_kind | Handler |
|---|---|---|
lifecycle.transition |
"item" |
yoke_core.domain.handlers.items_scalar.lifecycle_transition — routes through the same engines that service_client advance/... uses. |
{
"function": "lifecycle.transition",
"target": {"kind": "item", "item_id": 42},
"payload": {"from_status": "implementing", "to_status": "reviewing-implementation", "reason": "..." }
}
claims.* — work and path claim mutation
| Function id | claim_required_kind | Handler |
|---|---|---|
claims.work.acquire |
None (chicken-and-egg — handler asserts no active claim) |
yoke_core.domain.handlers.claims_work.acquire |
claims.work.release |
"self_only" |
yoke_core.domain.handlers.claims_work.release |
claims.steering.acquire |
None (payload document narrows the seat to one strategy document and atomically pairs its lock; omit it for the whole project) |
yoke_core.domain.handlers.claims_steering.handle_acquire; a seat or document conflict rolls back both |
claims.steering.release |
"self_only" |
same handler; releases the steering claim and its paired document lock together |
claims.steering.list |
None (project-scoped read) |
same handler; project/holder/active filters |
steering.report.get |
None (handler requires the caller's live steering claim) |
yoke_core.domain.handlers.steering_report.handle_get — composes one report covering every held steering claim, or a single scope when --project is set; see steering-fleet-report.md. |
claims.path.register |
"item" |
yoke_core.domain.handlers.claims_path.register (routes through path_claims_resolve) |
claims.path.widen |
"item" |
same handler → claims_path.widen |
claims.path.release |
"item" |
same handler → claims_path.release |
claims.path.amend |
"item" |
same handler → claims_path.amend |
claims.path.override |
"operator_override" |
same handler → existing path-claim override gate |
claims.coordination_claim.acquire |
None |
yoke_core.domain.handlers.claims_coordination_claim.acquire |
claims.coordination_claim.heartbeat |
"self_only" |
same handler |
claims.coordination_claim.release |
"self_only" |
same handler |
claims.coordination_claim.list |
None (read) |
same handler |
db_claim.amend |
"item" |
yoke_core.domain.handlers.db_claim.amend — writes the db_mutation_profile and db_compatibility_attestation columns atomically through the unified payload described in items-and-epics.md § DB Claim. |
db_claim.prose_check |
None (read) |
yoke_core.domain.handlers.db_claim.handle_prose_check — prose-vs-claim detector for a stored item; https-relayable. CLI: yoke db-claim prose-check PREFIX-N. Idea intake prefers the local stdin mode yoke db-claim prose-check --stdin (no DB) via the same adapter. |
ephemeral_env.* — ephemeral environment lifecycle updates
| Function id | claim_required_kind | Handler |
|---|---|---|
ephemeral_env.update |
None (project-role auth requires items.write on the environment row's project) |
yoke_core.domain.handlers.ephemeral_env — updates one ephemeral_environments field by id via the authoritative ephemeral_env.cmd_update behavior. Terminal status values preserve the existing stopped_at auto-set. CLI adapter: yoke ephemeral-env update ENV-ID FIELD VALUE. Error codes: payload_invalid, not_found, invalid_field. |
qa., project_structure., orchestration, reads
| Function id | claim_required_kind | Handler | |
|---|---|---|---|
qa.requirement.update |
"item" |
yoke_core.domain.handlers.qa.handle_qa_requirement_update |
|
qa.run.record_verdict |
"item" |
yoke_core.domain.handlers.qa_run |
|
qa.browser_context.get (read) |
None |
yoke_core.domain.handlers.qa_browser — one requirement-scoped read for the shared case runner: the named unwaived browser-check / browser-inspection case plus (with expected_branch) the latest ephemeral_environments.deployed_sha; scoped to whichever subject the case names — an item target or a deployment_run target, exactly one — and echoes the resolved subject so ref-shaped callers learn it. Internal CLI adapter: `yoke qa browser-context get (--item PREFIX-N |
--deployment-run RUN-ID) --requirement-id N`. |
qa.run.add / qa.run.complete |
"item" |
yoke_core.domain.handlers.qa_browser_writes — the two-phase capture shape (add lands started/captured rows, complete finalizes in place); both verify the run belongs to the targeted requirement and emit QARunStarted/QARunCaptured/QARunCompleted by field presence. CLI adapters: yoke qa run add / yoke qa run complete. |
|
qa.artifact.add |
"item" |
yoke_core.domain.handlers.qa_artifact_add — records one qa_artifacts row against a run from either a typed artifact_handle or mutually exclusive inline content_base64 plus filename. CLI adapter: yoke qa artifact add. |
|
| Start-bound recording authority | — | All three recording legs accept execution_claim_id: the item claim the run pinned at qa.case_execution.begin, where the dispatcher verified it. The qa_subject check accepts that claim when the live one is gone, so an hour-long gate records the verdict it earned even after the stale-session sweep reclaimed the claim or the item was handed off mid-run. Owner: yoke_core.domain.qa_start_bound_authority; the window is AUTHORITY_WINDOW_SECONDS, sized to the longest permitted case command. |
|
| Browser method execution | — | The tool-shaped yoke qa case run --requirement-id N fetches one immutable case through qa.case_execution.get, then uses the Browser context/run/artifact ids above when its registered runner is browser_substrate. There is no aggregate Browser execution entry. |
|
qa.requirement.list / qa.requirement.get / qa.run.list (reads) |
None |
yoke_core.domain.handlers.qa_reads — typed qa reads over the canonical column rosters (qa_constants.REQ_COLUMNS / RUN_COLUMNS; run rows include execution_status). requirement.list filters by item target (relay shape), payload epic_id, or payload deployment_run_id. CLI adapters: yoke qa requirement list / yoke qa requirement get / yoke qa run list. |
|
qa.gate_summary.run (read) |
None |
yoke_core.domain.handlers.qa_reads.handle_qa_gate_summary — wraps yoke_core.domain.qa_gate_summary.render_gate_summary for an item or epic_task target with payload transition ∈ (reviewed-implementation, implemented); the dispatcher-backed replacement for the checkout-shaped db_router qa gate-summary agent leg. CLI adapter: yoke qa gate-summary. |
|
qa.requirement.add / qa.requirement.add_batch |
"item" |
yoke_core.domain.handlers.qa_requirement_create — item-attached requirement creation mirroring cmd_requirement_add/add_batch (shared validators from qa_requirement_policy_validation, pinned-workflow transition validation, per-row QARequirementCreated). Single adds require workflow_transition_id; every add_batch row requires it and targets the function-call item (one claim verifies one batch). Epic-task attachment stays on the operator-debug domain CLI and also requires a valid transition; deployment-run attachment stays operator-debug and may omit it. CLI adapters: yoke qa requirement add / add-batch. |
|
project_structure.patch.apply |
None (project-role auth requires project.admin on the target project) |
yoke_core.domain.handlers.project_structure.handle_project_structure_patch_apply — atomically applies project configuration ops. An optional item target supplies provenance context, never write authority. CLI adapter: yoke project-structure patch apply --project P --ops-json JSON [--item ITEM]. |
|
project_structure.architecture_health.get (read) |
None |
yoke_core.domain.handlers.project_structure.handle_architecture_health_get — coverage and violations for the project's declared architecture map from the shared computer (yoke_core.domain.architecture_health); {"declared": false} when no map exists. Serves the workbench Architecture page, and the board section shows the same coverage. CLI adapter: yoke project-structure architecture-health get --project P. |
|
project_structure.architecture_draft.get (read) |
None |
yoke_core.domain.handlers.project_structure.handle_architecture_draft_get — scan-derived draft map proposal (yoke_core.domain.architecture_map_survey) for operator review; an empty tree proposes the minimal vocabulary-only map. Apply the edited payload via project_structure.patch.apply. CLI adapter: yoke project-structure architecture-draft get --project P. |
|
projects.site.create / projects.environment.create / projects.environment.update |
None |
yoke_core.domain.handlers.projects_infrastructure_create and projects_infrastructure_update — idempotent site/environment registration plus in-place name update. Create keys a sites row by slug and an environments row by id under a project-owned site. Re-creating an existing identity reports outcome="already_present" and touches nothing (settings updates go through the settings surfaces); a slug/id owned by a different project or site refuses with a mismatch error. Update keeps the id/site stable and writes only name (prod or stage). CLI adapters: yoke projects site create / yoke projects environment create / yoke projects environment update. |
|
board.rebuild |
None |
yoke_core.domain.handlers.orchestration.board_rebuild — the operator-requested .yoke/BOARD.md refresh. Nothing dispatches it automatically; item, lifecycle, merge, and deploy operations never rebuild the board. |
|
board.data.get (read) |
None |
yoke_core.domain.handlers.orchestration.handle_board_data_get — server half of the board rebuild: runs the board's full DB query plan (yoke_core.board.data.collect_board_data) for the payload's query-shaping inputs (scope, config_values from DB project-policy.settings.board, zen_vision_count, repo_root_token, optional code_days upsert into project_code_days) and returns the recorded plan. The client (yoke board rebuild composition) renders markdown locally from this payload plus client-local inputs (board art, VISION entries) and writes .yoke/BOARD.md itself, so board rebuilds work identically over https and in-process. CLI adapter: yoke board data get. |
|
overview.activation.get (read + latch) / overview.module.dismiss / overview.module.restore |
None |
yoke_core.domain.handlers.overview_activation — the workbench Overview's activation modules. The get derives every module/submodule state from universe signals in one dispatch (payload {host_facts: {machine_connected?: bool}}) and latches newly satisfied universe modules into overview_activation_facts. The wizard's machine_universe submodule and the connect_harness module answer per registered machine (yoke_core.domain.overview_machine_activation, the one machine-identity read: session_relays plus harness_sessions.machine_id today, the machine registry row once it lands): the submodule counts and names the machines, the module carries a machines list — each with its own state, activated_at, connected, harnesses, surfaces, last_seen_at, and hook-health targets (hit, hook_health, per-target last_seen_at, and approval remediation) — latched per (machine_id, module_key) in overview_machine_activation_facts, and reads activated only when every listed machine has connected a harness. The run_onboard module carries an onboard object (yoke_core.domain.overview_onboard_progress) with the latest checklist run's live run_status, superseded_by, steps_done/steps_total, next, blocker, and the scaffold_installed / strategy_docs / environments outcomes its card is written from; that run must have no open rows to activate the module, or be closed as superseded by its project's deployments (yoke_core.domain.project_onboarding_run_supersede writes that status and the overtaking deployment onto the run row), and the facts stay live under the monotone latch. CLI adapter: yoke overview activation get. The dismiss/restore pair remains browser-proxied. A hidden module leaves Overview entirely (no count, no show-again); the way back is profile.onboarding.reset. The Profile page (yoke_core.domain.handlers.profile, reached from the actor menu, all browser-proxied, every one refusing without a bound actor) is profile.get (read) — the caller's own identity (actors name, kind, id, plus the newest actor_external_identities email and sign-in issuer when linked), org and project roles, live api_tokens rows (a machine-bound token names its machine and is ended by retiring the machine, never here), the profile.time_zone preference, and the hidden-module count — with profile.token.create (raw value returned exactly once), profile.token.revoke and profile.preference.set acting only on the caller's rows, and profile.onboarding.reset deleting every overview.module.dismissed.* preference for the caller and nothing else. |
|
harness.machine_report.upsert |
None |
yoke_core.domain.handlers.harness_machine_report — persist client-collected harness presence and approval state for one project on one machine into harness_machine_reports (payload requires machine_id). CLI adapter: yoke harness machine-report upsert --project-id N. |
|
packets.render / packets.check |
None |
same | |
packets.budget.get (read) |
None |
yoke_core.domain.handlers.orchestration_packet_budget.handle_packets_budget_get — each packet role's configured line budget, its current rendered usage, and the remaining headroom, plus the same figures for the aggregate corpus. Reports the usage the size caps enforce, so trimming a packet or raising a budget starts from a measured number; character counts are usage only, since no character limit is enforced. Named by every budget-exceeded message. Client-local like its siblings: it measures the packets this checkout renders. CLI adapter: yoke packets budget get. |
|
agents.render.run / agents.render.check |
None |
same (routes through yoke_core.domain.agents_render) |
|
doctor.run.run (read) |
None |
yoke_core.domain.handlers.reads_misc.handle_doctor_run — machine Doctor surface: takes {project, db_path, fix, only, quick, full, runtime}, returns structured {results[], scope, project, runtime, fail_count, warn_count, pass_count, na_count}. project defaults to the project bound to the caller's checkout. runtime names the deployment destination executing the checks (local / server / hosted); omitted, the handler derives it from the runner's own evidence. Checks outside the applicable set for that project and runtime come back with severity="N/A" and the reason in detail — they are never counted as passes and never dropped. Callers must pick exactly one scope (quick, full, or only); a JSON caller missing the scope flag receives error.code="scope_required". Unknown HC slugs in only return error.code="invalid_check". The retained human CLI is yoke doctor run --json, with byte-shape parity against this function. |
|
events.query (read) |
None |
same | |
items.get (read) |
None |
same | |
merge_queue.landing_pull_request.record / merge_queue.landing_pending.mark / merge_queue.landing.observe / merge_queue.landing_pending.clear |
None |
Internal, session-optional item functions owned by yoke merge item: record the pull request/admission; make one cadence-limited server GitHub sweep across the project's pending landings; return this lane's durable state, queue_holding, queue_entry_state, merge_when_ready, check evidence, and refresh/change times; then clear it after terminal close-out. |
|
session_ci_wait.record |
None |
Internal, session-required global function the CI gates call the moment a run id exists (yoke watch pytest's remote selection and the QA case command-ci runner): it records the (session, project, repo, run, head sha, kind, continue command) tuple in session_ci_run_waits so the control-plane sweep (yoke_core.domain.session_ci_wait_observer) can hand the session the verdict after the turn watching the run has ended. Re-recording one run for one session is a no-op, and supersedes_run_id drops the wait a re-dispatch abandons. |
|
github.merge_queue.readiness (read) |
None |
yoke_core.domain.handlers.github_merge_queue_readiness — item-scoped, non-mutating landing liveness read. It composes the pull request with mergeQueue(branch).entries, returns the exact queue_entry_state, and reports null arming as consumed while an entry exists rather than as cleared. CLI adapter: yoke github merge-queue readiness PREFIX-N --json. |
|
epic_tasks.list (read) |
None |
same | |
path_claims.conflicts.list (read) |
None |
same | |
checks.file_line.run / checks.idea_readiness.run / checks.path_claim_coverage.run / checks.schema_api_context.run / checks.agents_render.run / checks.event_registry.run / checks.migration_governance.run |
None |
yoke_core.domain.handlers.reads.* |
Adapter status
The CLI surfaces (db_router items update, service_client db-claim-amend, item_field_transform, epic task-update-body, etc.) remain live adapters — they construct a FunctionCallRequest internally and dispatch through the same registry. The adapter status (live, deprecated, retired, or internal) is recorded per registry entry and surfaced in the operator-readable Atlas; render it locally with python3 -m yoke_core.tools.atlas_render_docs render. An internal function is a typed service-to-service boundary without a retained operator CLI adapter, so it is excluded from CLI-adapter parity. That adapter classification does not authorize access; the function's authorization scope and guardrails enforce who may dispatch it. Skill prose, packet prose, and agent docs reference the function id; operator/debug invocations of the CLI adapter remain valid and clearly labelled.
Authoring conventions
- Idempotency. Always set
request_idfrom a stable id (the calling agent's turn id, a hash of the (item, field, content), etc.). Replaying with the same(function, request_id)returns the cached response fromfunction_call_ledgerand emitsDispatcherIdempotencyReplay; reusing arequest_idacross different function ids rejects withidempotency_key_collision. Ledger rows expire after the replay TTL (function_call_ledger.LEDGER_TTL_DAYS), after which the samerequest_iddispatches fresh. - Atomicity of mutation + side effect. Functions that mutate state plus emit downstream events (sync GitHub body, rebuild board) wrap the side effect in
options. Side-effect failures degrade to warnings viaDispatcherDownstreamDegraded; the primary mutation either fully committed or fully rolled back. - Reads return typed payloads. Function-call reads (
items.get,events.query,doctor.run.run) return structured objects, not parseable terminal text. Agents that branch on read output should consume the typed fields, not regex the prior CLI's stdout. - Verification status. Mutation handlers run a post-write re-read and report
verification_status. Treatverification_status="degraded"as the same severity as a partial-state warning.
Cross-links
docs/event-catalog.md(a yoke source-repo doc) —YokeFunctionCalled,DispatcherIdempotencyReplay,DispatcherDownstreamDegradedenvelope schemas.python3 -m yoke_core.tools.atlas_render_docs render— render the operator-readable Atlas of the agent-facing surfaces locally.- items-and-epics.md § DB Claim — unified amendment workflow — the
db_claim.amendpayload shape. yoke_contracts.api.function_call— Pydantic envelope models.yoke_core.domain.yoke_function_dispatch— dispatcher entry point.yoke_core.domain.yoke_function_registry— registry.yoke_core.domain.handlers— handler registration (idempotent).
Yoke Function Call Reference