Overview
This page documents the additional tool groups that extend Genesis beyond the original toolkit index. Use it together with Tools Overview when you need a complete map of the platform’s runtime capabilities.
Server error log inspection
get_error_logs reads the curated server error log and groups errors and
exceptions by signature. Use it for the server-wide error gate; use grep_logs
when you need pattern-based search through the full application log. Each call
reads the current error log and, when requested or when since is supplied,
every retained daily-rotated error log. max_groups limits returned groups,
not the files read, so avoid frequent polling.
The response includes
observed_at (the server’s UTC observation time), the
requested since value, and historical_records counted before the boundary.
Records at or after the inclusive boundary are grouped as current errors;
records with unparseable timestamps remain current errors. Log timestamps with
no timezone offset use the server’s local timezone. A missing timezone or a
future since value makes the call unsuccessful. When error logging is
disabled, the call also returns success: false; treat that as an inability to
verify, not as a pass.
Application log search
grep_logs searches the configured application log with a regular expression.
Use it to investigate a message or identify which mission produced a logged
error; it does not replace get_error_logs for the server-wide grouped error
gate. Searches with since scan complete logical records in the selected
application log files, including retained rotated files when requested. They can
read large logs, so keep patterns specific and avoid frequent broad searches.
Without
since, matching is line-based and the response includes success,
count, and formatted verbatim_output with the requested context. With
since, the pattern is matched against each complete record, including
continuation/traceback lines and decoded JSON message and exception fields.
Matches are returned oldest first with record_timestamp, record_text,
thread_id, parent_thread_id, line_number, and content; the response also
includes since, files, historical_records, unknown_timestamp_records,
truncated, and window_complete. The timestamp and identities belong to the
matched record itself, not a neighboring record.
window_complete is false when selected records have unknown timestamps or the
search results/output were truncated; such a result cannot prove that no match
exists. An invalid or unreadable search returns success: false. For example,
search the current and rotated logs from a captured invocation boundary:
action_review_tools
Read the current human’s Action Review queue in any lifecycle state: governed
actions awaiting review, as well as actions already approved, authorized,
executed, rejected, denied by policy or expired. Each row includes when it was
decided and whether a person or tenant policy authorized it. The caller must
have the approve_agent_action permission and pass the human-approval identity
gate. For Snowflake’s account-classification limits, see
Roles and Approvals.
For how a request’s decision reaches its originating agent, see the Action
Review decision hand-back.
list_action_reviews
List up to 25 visible proposals for the current human reviewer. user_id and
bot_id are implicit from the agent context, so the common call takes no
arguments and returns the pending_review queue.
Pass the optional string status to read any other lifecycle state —
authorized, claimed, executed, not_applied, reconciliation_required,
rejected, policy_denied, expired or invalidated. It defaults to
pending_review. A non-string value or a value outside that vocabulary is
refused rather than silently treated as the default.
not_applied means the handler or provider proved that the action was refused
before any write was applied. reconciliation_required means the action may
have applied; do not retry it. For execution details and a captured provider
error, inspect the proposal through the Action Review API.
If
truncated is true, tell the user that the list may be incomplete.
The page limit is not an incomplete_reason: compare total_count with the
number of returned proposals to detect that the page contains only the first
page, then point the user to the Action Review page for the remainder. Never
count, total or summarise the returned rows as though they were the whole set.
A probe_failure means Genesis could not determine reviewer access for one or
more proposals; suggest retrying rather than treating those proposals as hidden
permanently. A handler_unavailable means no handler is registered for an
action type in this deployment, and row_unreadable means a proposal’s stored
request is malformed. For either reason, tell the user that some items were
omitted and cannot be acted on here; do not suggest retrying because neither is
transient. Incomplete reasons take precedence in this order:
probe_failure, probe_budget, handler_unavailable, row_unreadable, then
scan_ceiling.
Read authorization_basis before describing anything as approved. A
policy_allow basis means tenant policy admitted the action automatically and
no person reviewed it; human_approval means the action passed the
human-approval identity gate, but does not prove a person was present. A row
with no basis was never granted at all.
Use salesforce_connector or hubspot_connector for CRM merge preview and
execution, not this listing tool.
show_action_review
Put an approve/reject card for one pending proposal into the current
conversation. Use this when an authenticated human signals that they want to
decide a proposal, or immediately after telling them about a pending proposal.
The card lets the human decide in the conversation; the agent cannot approve
on the human’s behalf.
success: true, card_sent: false, its status, and its
authorization_basis; report that outcome instead of retrying. Use the basis
semantics described for list_action_reviews above when explaining the result.
On successful delivery, the response contains success: true,
card_sent: true, and the proposal’s proposal_id, action_type, and title.
Tell the human that the card was sent and do not ask for a typed confirmation.
Card delivery is queued asynchronously, so card_sent: true confirms that the
card was accepted for delivery, not that it has already appeared. If delivery
fails, or the call cannot authenticate the human, check the returned error and
direct the reviewer to the Action Review page instead.
action_review_request_status
Read the current state and decision for an Action Review request you raised.
Genesis conversations receive the decision directly. An agent calling from
outside Genesis (over MCP or /api/tool_call) must poll this tool instead:
repeat every 30 to 60 seconds while state is pending, then stop and report
the result. Do not call the tool that opened the request again to check whether
it has been decided.
For an approved request,
state: decided means approval stands before its change
is applied; state: applied means the change was made. A not_applied status is
final and means nothing was written; reconciliation_required means the effect
may have applied, so do not retry. Follow next for the stop condition. Each
call reads the request’s full Action Review ledger row.
apps_tools
Build, verify, run, restart, and manage GenesisApps directly from chat. For the full app-building workflow, also see Genesis Apps and GenesisApps Tools.
Legacy dashboard SQLite reads
legacy_dashboard_tool(action="SQLITE_QUERY") reads rows from an existing
legacy dashboard’s dashboard_data.sqlite. It requires dashboard_id (string)
and sql (string); neither has a default. The shared SQL classifier must classify
the statement as READ; writes and UNKNOWN statements are refused before the
local store is opened. Dashboard tables are written by EDIT, through
populationSources.
agent_review_notes_tools
Consult the agent’s own behavioral review notes: recurring steering-correction
patterns observed in past reviewed conversations, filtered to the current
workflow type and data context. Assign this group to bots that should
self-check before repeating a corrected approach.
The group registers globally but is live-gated on agent_review.enabled in
AppConfig — when agent review is off, consult_review_notes is hidden from
the tool schema and returns an error if invoked. No server restart is needed
when an administrator toggles the flag.
When agent_review.feedback_to_agents.enabled is true, Genesis also injects
the same filtered AGENT REVIEW NOTES block into prompts automatically.
Use consult_review_notes as the documented fallback when injection is off
or when the agent wants to re-check mid-thread.
consult_review_notes
Fetch behavioral review notes relevant to the current conversation. Returns
only steering guidance — never domain facts about data or SQL.
Returns a dict with:
Unlike
search_data_context and find_past_queries, this tool returns
behavioral guidance about how the agent should work, not facts about the
data or prior SQL. On an empty result or failure, fall back to those
data-context tools; do not retry this one in a loop.
Example:
propose_learning_adoption
Propose adopting a mined learning candidate as a team learning. Use this when
the user asks to keep, promote, or make a recurring correction permanent. The
candidate must have been mined for the current bot, and the caller needs the
manage_agent_learning permission. The tool uses the candidate’s one Action
Review item: an existing pending or in-flight item is returned instead of
creating a duplicate, and a person’s declined decision is not replaced by a
new proposal. If the prior item expired, was invalidated, was not applied, or
was denied by policy, a later call can mint a fresh Action Review item. A
policy-allowed proposal can be adopted immediately; otherwise it waits for a
person in Action Review.
The result includes
success, error on failure, and action_review with the
proposal ID, action type, admission result, and status. A successful result
also includes the adopted candidate result (candidate_id, status,
statement_id, and adoption_id). A pending result sets pending_review: true
and means nothing has changed yet; do not call the tool again for the same
candidate. A policy refusal sets denied_by_policy: true. If a person has
already rejected or revoked this adoption, the result sets
declined_in_action_review: true; that decision stands and the candidate
should not be proposed again. An uncertain result has Action Review status
reconciliation_required; do not retry it, and check the anchor’s wiki page
when the candidate was anchored.
Example:
aws_tools
Perform AWS operations such as EC2- and S3-backed workflows from an agent conversation. This group is best suited to teams that already operate workloads in AWS and want agent-assisted cloud operations.
When these tools use a saved AWS connection, Genesis can authenticate with
either Access Key credentials or IAM Role (IRSA / Pod Identity) from the
running workload. See Connections for the exact mode
selection flow and field names.
aws_action access-denied errors
When AWS returns an IAM access-denied error (for example AccessDenied,
UnauthorizedOperation, or AccessDeniedException), aws_action enriches the
response with the caller’s IAM ARN when it can be resolved from the saved
credential_name via STS get_caller_identity.
When
credential_name is omitted or STS lookup fails, Genesis falls back to
the generic success: false response with error set to
AWS operation failed: ... and no caller_identity field.
This enrichment applies to AWS IAM permission failures from boto3. It is
separate from Genesis RBAC denials, which return
Access denied: user or agent does not have permission to view the requested information.blueprint_creation
Turn a successful thread into a reusable blueprint so the same workflow can be launched again with less manual setup.
create_blueprint
Use create_blueprint to generate a reusable blueprint from one or more successful threads, inspect an existing blueprint before editing it, and preview or apply targeted working-copy changes. Use CREATE_BLUEPRINT_FROM_THREADS for new blueprints from conversations, PREVIEW_EDIT to stage an update, and APPLY_EDIT to commit a reviewed preview.
CREATE_BLUEPRINT_FROM_THREADS runs background analysis through Genesis
utility LLM calls that request structured JSON output. This path works with
Claude models on Snowflake Cortex and on LiteLLM-backed providers
(including LiteLLM Proxy, AWS Bedrock, and Anthropic). On Cortex
Claude, Genesis omits OpenAI’s unsupported schema-less json_object response
format and relies on JSON-only prompts with parse retry. On LiteLLM Claude
routes, Genesis applies the same model-aware max_tokens defaults used for
chat so long blueprint manifests are not truncated mid-generation. Auxiliary
utility LLM calls raise structured provider failures (not_configured,
provider_exception, or empty_response) instead of returning provider error
text as job output. If creation fails with a provider error, verify the
active chat provider in Config → AI Providers and retry
CREATE_BLUEPRINT_FROM_THREADS.
For output-limit handling during analysis, synthesis, and optimization, see
Blueprint Library and Missions.action="GET_CREATION_STATUS"
Call this after CREATE_BLUEPRINT_FROM_THREADS returns a job_id.
Example:
Editing existing blueprints
CallGET_BLUEPRINT with blueprint_name to inspect the current manifest and
phase structure before building a targeted edit. For existing blueprints,
Genesis uses a preview-first workflow: PREVIEW_EDIT stages the change and
returns a preview_id, then APPLY_EDIT commits that preview after review.
Use structured edit_operations whenever the change decomposes cleanly into
specific fields, phases, actions, or exit criteria. Fall back to
change_description only when the requested update does not fit those
structured operations cleanly.
GET_BLUEPRINT is review-only. It returns the blueprint definition for
inspection or editing, but it does not create a Mission, enter a phase, or
authorize manual execution from chat. When the user wants to run a blueprint,
use start_blueprint_mission from
Project Manager Tools instead
of manually following the manifest or GET_BLUEPRINT_INFO output.GET_BLUEPRINT calls return the manifest plus source_type,
editable, read_only, execution_guardrail, and suggested next_steps so
callers can branch cleanly into edit-versus-run flows.
action="PREVIEW_EDIT"
Preview changes to an existing blueprint before applying them.
PREVIEW_EDIT requires blueprint_name plus either change_description or
edit_operations.
For phase exit_criteria authoring rules, enforced types, and examples, see
Exit criterion types.
A blueprint loads from one
blueprint_manifest.yaml file. Runtime loading
does not resolve $ref, include, or other multi-file phase-definition
patterns, and unknown phase fields are ignored at load time. Keep phases in
the manifest, and move only supporting prose or examples into companion
files such as Markdown documents.edit_operations patterns:
- Use
set_blueprint_fieldorappend_blueprint_listfor metadata updates. - Use
insert_action,replace_action, orremove_actionfor action-level edits. - Use
set_phase_fieldfor broad rewrites and include every phase field you intend to change. - Use one
PREVIEW_EDITcall with multiple operations when you want one combined preview.
action="APPLY_EDIT"
Apply a previously previewed edit.
branding_tools
Read and update organization branding settings such as colors, logos, and design guidance. This group complements the Branding setup page.
claude_code_tools
Use Claude Code from Genesis for delegated coding tasks. Workspace admins can
globally allow or block these tools in Config → Workspace Policies under
Tool Permissions → Coding Agent Controls. See
Coding Agent Controls for the
customer-facing workflow.
These delegation tools are unavailable in Genesis Desktop. For the Desktop
coding-agent workflow, see Coding Agent Controls.
The direct _claude_code tool is unavailable when the Genesis server runs on
Windows because it drives the CLI through a POSIX pseudo-terminal. Run Genesis
on macOS or Linux to use this tool.
For Claude Code clients using room actions, room_send is subject to the
per-sender, per-room limit documented in Agent rooms endpoints.
codex_code_tools
Use Codex from Genesis for delegated coding tasks. Workspace admins can
globally allow or block these tools in Config → Workspace Policies under
Tool Permissions → Coding Agent Controls. See
Coding Agent Controls for the
customer-facing workflow.
confluence_connector_tools
Search and manage Confluence spaces, pages, and attachments. See Confluence for setup.
When connection is omitted, Genesis resolves the effective default confluence connection for the current user and bot (My default, then Role default). Genesis injects bot_id, thread_id, and user_id from the active conversation automatically. User OAuth (Cloud) connections act as the requesting user; the caller must be present in the active thread context.
When the acting user cannot use the resolved connection (for example a
personal connection owned by someone else),
confluence_connector returns
Success: false with a Suggestion explaining that the failure is a connection
access/permission issue, not invalid credentials. Ask the connection owner to
run the request in-thread, or have an admin with manage_all_connections share
the connection.
connections_action_tools
Create, inspect, update, test, remove, and resolve defaults for saved external-service connections. It is the agent-facing companion to the Connections setup UI.
connections_action
UPDATE verifies connectivity before persisting a supplied locator_json. A
failed verification leaves the saved connection and its secrets unchanged. The
verification uses the credential that the update will retain: with
secret_conflict_resolution="use_existing", Genesis opens the stored secret;
otherwise it opens the submitted value. Metadata-only updates without a locator
do not perform a connectivity check.
For an MCP connection, CREATE and UPDATE also make one tool-discovery request
to the server. Their successful response includes mcp_tools with registered
(boolean), tool_count (integer), and message (registration message). A failed
registration does not undo the saved connection; startup replay can register its
tools later. See MCP server connections
for the connection lifecycle, including deletion.
TEST resolves the saved connection using the current bot_id, so the result reflects the active agent’s RBAC, connection assignment, and secret-access rules instead of a generic backend-only connectivity check.
GET_DEFAULT returns scoped-default metadata for one connection type in data.connection_type, data.system_default, data.user_default, data.role_defaults, data.effective_default, data.effective_default_source, data.matched_roles, and data.ambiguous. data.system_default is always null (system/shared defaults are no longer supported). data.effective_default is the resolved default after user, then role layers only; when no scoped default applies, it is null.
LIST accepts optional connection_type, resource_identifier, and limit parameters. When connection_type is set to a value that is not in the connection registry, the tool returns success: false with an error message listing valid types — not an empty data array. Use LIST_TYPES first to discover supported types (including types with no saved connections yet, such as mssql).
LIST returns only connections usable by the requesting user and active bot. Each data entry includes non-secret discovery metadata: connection_id, credential_origin (connections_api or legacy_db), is_user_default, is_role_default, is_effective_default, effective_default_source, and any warnings such as oauth_authorization_required, oauth_grant_expired, or egress_pending_approval. The response also includes resolution_by_type, which reports the resolution state, selected connection id and source, and any conflicting_connection_ids for each returned type. With resource_identifier, LIST adds ranking without changing the base rows. ranking.matches contains native Connections API rows with score, reason, strategy, separate match_warnings and discovery_warnings, counts, and unique_exact_connection_id when exactly one warning-free score-100 match exists.
Connection summaries returned by LIST, GET, CREATE, and UPDATE include connection_id (the Connections API’s <type>.<name> identifier) and canonical_connection_id (the canonical identifier used to match the same connection across listings).
Connector tools that resolve connections use the same requester-aware checks. If an omitted connection cannot be selected, the tool returns a structured success: false response with error_code, resolution_state, connection_type, safe candidates, and retry.tool_parameter. Retry with the candidate’s fully qualified id (for example linear.team-a) or ask the user to choose one. An explicit id may also be supplied as the provider-prefixed form or its legacy bare name; an id with a different provider prefix is rejected.
FIND is a deprecated one-release compatibility alias for LIST with a resource identifier. It returns the same structured catalog and ranking data and does not open a card, suspend a thread, execute a provider action, or generate a continuation. Agents should use LIST and ask an ordinary conversational question for ties, sub-100 matches, or warning-bearing results. A unique warning-free exact match may be used only by a subsequent explicit read-only or idempotent provider call after disclosing the selected connection.
LIST, GET, and TEST apply the same connection-scope and secret-access checks as the Connections API: LIST omits connections the active user or bot cannot use, while GET and TEST return a not-found-style error for inaccessible connections. See Connections — Personal vs shared for the visibility and credential rules.
On a successful CREATE, data.owner_user_id is the owner recorded on the
connection and data.created_by is the recorded creator. The response also
includes attributed_to_another: false when the owner is the signed-in user,
and null when the connection names nobody. A connection created without a
signed-in user is displayed as unattributed; its internal system principal is
not a person and is never presented as one.
personal_credentials controls whether a shared connection may resolve a
user-attributed principal credential. Set it on CREATE or UPDATE; it is
returned by GET and LIST. Users bind or unbind their own principal through
the Connections page or the personal credential endpoints.
Background operations continue to use the shared/service credential.
SET_DEFAULT supports default_scope="user" or role. CLEAR_DEFAULT supports user and role. Role defaults require manage_all_connections, and Genesis only allows them on shared non-legacy connections that the target role can already access. default_scope="system" and is_default=true on CREATE/UPDATE are rejected.connections_action enforces the PAT-connection gate on CREATE, UPDATE,
and TEST. If locator_json resolves to a PAT-class connection (auth_type
of pat, api_token, or api_key, or an omitted auth_type with PAT-style
fields such as access_token), the requesting user must have the matching
access_pat_connections_<category> permission for the target connector
category (databases, git, cloud, pipelines, or tools). Otherwise
the tool returns:
Your role does not allow PAT-based tool connections. Use OAuth instead, or ask an admin to enable PAT capability for your role.connections_action applies the same admin-only runtime-identity
authorization as the Connections API for BigQuery application-default and
Databricks Lakebase and Iceberg App-identity connections. See
Connections — BigQuery,
Databricks Lakebase connections,
and Databricks App lakehouse connections
for fields and runtime behavior.LIST_TYPES omits unavailable authentication modes and
HELP skips them, so the agent does not suggest credentials the save would
refuse. This includes host-identity modes unavailable in the App and AWS/MWAA
assume_role without bootstrap access keys. The Connections UI instead keeps
these modes visible but disabled with the reason; see Connection mode chooser.
On
CREATE, UPDATE, and DELETE, pass connection fields as top-level
parameters (connection_type, name, locator_json, scope,
roles_with_access, access_intent, secret_conflict_resolution). There is
no nested updates object — unknown parameters return
Unknown parameter(s) for <action>: ... so callers can self-correct.dataset_tools
Create, refresh, materialize, and delete datasets that support fast, governed data access for apps and analytical views.
Use inline_data only for tiny toy examples or a few hand-authored rows. Genesis caps inline_data.rows at 50,000 rows, and those rows still pass through LLM context. For synthetic or other bulk data, generate files first, load them into workspace_sqlite with _load_to_sqlite, then define the dataset with source_type="sql" and connection_id="workspace_sqlite".
Built-in Cost & Usage cube
Genesis ships a protected system datasetgenesis_cost_usage_cube_v1 and the
genesis_cost_usage_dashboard app. The preset materializes three system-metrics
sources:
Twin scan rows are read from
SCAN_USAGE_FACTS, which the background
twin_scan_cost_sync job populates on a schedule. Dataset refresh does not run
that sync — it only materializes rows already in the cube store.
The dashboard’s Top Threads by Known Spend section groups threads by
instance and thread and includes LLM and metered-service spend. It shows
unpriced and unknown-price call counts when pricing counts are complete; known
spend with incomplete pricing is shown as a lower bound, and spend with no
known price is unavailable. The section reads the materialized cost cube, so
new data appears after the next dataset refresh (the preset’s default schedule
is @daily). See the API reference for the thread-spend view
for its aggregation and fields.
Scan-cost views on the preset:
SUM(cost_total_usd) ignores NULLs, so unpriceable scan rows stay visible in
token totals without fabricating zero-dollar cost. The dashboard Scan Cost
tab renders these views.
default_cost_usage_cube_create_tool
Create or update the built-in Cost & Usage cube preset and return
dataset.<dataset_id> connection info plus an app_binding for
genesis_cost_usage_dashboard.
Example:
dataset_delete_tool
Delete a dataset, with a confirmation step when the dataset is still bound to one or more apps.
Genesis blocks deletion of built-in system datasets. When a dataset is still bound to apps,
dataset_delete_tool returns bound_app_count, bound_apps, and a confirmation hint instead of deleting immediately. With durable storage, Genesis removes remote snapshot copies before deleting the dataset record; a failed removal leaves the dataset intact. If an active refresh holds its lock for over 30 seconds, deletion returns a retryable busy error.
Example:
flow_tools
Create and manage Genesis Flows: lightweight deterministic SQL and Python workflows that run on demand or on a schedule. Flow runs are not the full chat agent loop; optional Python-step calls to genesis_flow.llm.ask route through Genesis model settings and bill like other base LLM usage. For the customer-facing workspace, see Flows.
flow_action
Use this function to create, list, inspect, run, update, delete, schedule, and validate flows.
To review a waiting change, first preview it, then pass its fingerprints back
unchanged when promoting:
CREATE, UPDATE, RUN, REVERT, PROMOTE, PROMOTE_PENDING, FORK_TO_STANDALONE, DELETE, SCHEDULE, and CANCEL_RUN refuse unrecognized keys in params; the response lists unknown_params and accepted_params, and nothing changes. UPDATE’s steps replaces the entire list rather than merging it: GET the flow first, then send every step it should retain and any new steps. The response includes step_count_before when the prior list is readable and always includes step_count for the replacement.
Flow runs started from a chat report terminal results back to the launching
conversation; see A run started from a chat reports back to it
for delivery timing and payload details.
When RUN starts a flow from a conversation, its response includes notify: true
and a next_step telling the agent to continue with other work; the run reports
back on the next tool result or as a new turn when the thread is idle. For a run
without a launching thread, notify is false and next_step directs the agent
to read the run with GET_RUN. External MCP and /api/tool_call callers also
receive notify: false; see the Flow run delivery guidance.
Treat wait_for_completion as a last resort for
short waits when the outcome is required before continuing, not as the normal
polling path.
See Flows for the
bulk_copy step’s external-target recipe, supported connection types, and transfer
limits. CREATE and UPDATE reject a bulk_copy definition unless it has a source
(query or source_table) and an output target that can accept a whole relation.
See Flows
for step timeout, concurrency, cancellation behavior, and external-write result
semantics, including the guarantee that a copy stopped before its final target
statement leaves the target unchanged.
That section also documents the values_nulled result field for SQLite empty
strings written as NULL, and the numeric-column outcomes reported by bulk copy.
Successful CREATE, GET, GET_VERSION, UPDATE, REVERT, and
VALIDATE_DEFINITION responses include definition_sha256: a canonical
SHA-256 fingerprint of the portable execution fields (description,
parameters / parameters_schema, steps, on_failure, tags, and
schedule when present). The hash excludes the instance-local Flow name so
you can compare a reviewed candidate to the definition you are about to apply,
revert, or promote without name drift.
SYNC_FROM_REPO runs in the active bot context, so the same managed repository
can hydrate separate Flow records for different bots. Managed source include
/ exclude selectors narrow which flow artifacts SYNC_FROM_REPO enables.
Flows that no longer match are retired on sync:
disabled, cron schedule removed from the scheduler, and managed dependency rows
cleared. Genesis retires only flows this source created (managed_sync:<source_id>);
a local flow with the same name stays enabled and scheduled.
For flow_action SCHEDULE, cron strings must contain exactly 5 fields in
minute hour day month day_of_week order. If you pass a structured Flow cron
trigger instead of a cron string, use minute, hour, day_of_month,
month, and day_of_week; Genesis normalizes day_of_month to the
scheduler’s day field when it syncs the saved Flow schedule.
For sandbox-backed Python steps, params.steps[*].sandbox_backend_options can also include saved target_env and security_profile names created through sandbox_env. At execution time Genesis merges those settings in this order:
target_envdefaultssecurity_profiledefaults- explicit
sandbox_backend_optionsvalues on the step
credential_name, namespace, or other backend-specific options. A typical step fragment looks like {"execution_target":"sandbox","sandbox_backend_options":{"target_env":"railway-analytics","security_profile":"analytics-reader","credential_name":"railway-prod"}}.
When you declare flow input parameters, use either parameters_schema or the
equivalent parameters alias. In either form, each entry can be a simple type
alias or a full object such as {"n":{"type":"int","required":true},"flag":{"type":"bool","default":"true"}}.
For one-shot model work inside a Flow Python step, use
genesis_flow.llm.ask(...). model_tier and provider are optional;
omitting them inherits the flow authoring thread defaults when available and
otherwise falls back to the flow bot’s default tier/provider resolution.
Legacy model="fast", model="main", and model="frontier" still map to
tiers, and the helper returns result.output plus result.usage with the
resolved provider/model details. Use forward calls when downstream steps
or branches must parse the model output; use side-channel calls for
optional narrative or audit text that must not gate the pipeline. The built-in
app-flow-llm-usage AgentSkill documents the same pattern for Genesis Apps.Flow SQL steps cannot persist namespace-level
CATASTROPHIC operations such
as DROP DATABASE, DROP SCHEMA, DROP CATALOG, or CREATE OR REPLACE DATABASE/SCHEMA/CATALOG. Flows run unattended and cannot provide the
interactive user_override these operations require, so run those statements
as one-off _query_database calls instead.inspect_flow_failure
Inspect the persisted execution evidence for a failed Genesis Flow run. Call this
before making any causal claim when an alert supplies a run ID, asks for
root-cause analysis, or reports that a pipeline exhausted retries.
On success, returns
success: true with evidence (run/job/task identities,
historical task definition, bounded preceding-step evidence, connection identity,
retry exhaustion, timestamps, error log, repository/orchestrator pointers),
inspection_receipt (thread-scoped receipt stamped in the current thread),
required_citations (exact label=value strings to copy into finalization),
and existing_outcome (any prior RCA outcome on the run, or null). On
failure, returns success: false with error.
For failed steps that write to external targets, the persisted error log uses
the masked or withheld form described in Flows → Inspect a flow or run,
including recognized quoted target column names while target values remain masked.
For ordinary Flow CRUD or successful run status use flow_action instead.
After correcting the Flow, use run_flow_rca_verification for durable
completion; use record_flow_rca_outcome for staged work or manual recovery.
If a downstream tool reports a missing or mismatched receipt, call this again in
the same thread.
run_flow_rca_verification
Finish an inspected Flow RCA with verified correction and durable evidence in
one combined operation. This tool runs (or reuses) a linked rca_verification
Flow run on a newer Flow version, then atomically persists the corrected RCA
outcome and protected gold record. If protected gold already exists for the
failed run, Genesis returns the canonical outcome without re-running verification
or overwriting the protected record.
Prerequisites:
- A matching
inspect_flow_failurereceipt in the current thread. - The current Flow version must be newer than the failed run’s version.
evidence_citationsmust include every value fromrequired_citations(run ID, task ID, connection ID, error-log SHA-256, Flow version, retry exhaustion, attempts, and repository or flow-store version pointer).
success: true with task_durably_complete: true,
failed_run_id, verification (linked verification run ID, status, Flow
version, timestamps), gold (gold_id and status), canonical_evidence_citations,
already_completed (whether protected gold already existed),
verification_reused (whether an existing completed verification run was
reused), thread_context_persisted, and next_action (instructions to restate
the cited result in the next assistant message). On failure, returns
success: false with error and may include run when verification execution
failed.
Prefer this tool for normal corrected completion. Use record_flow_rca_outcome
only for staged work or manual recovery when a completed linked verification
already exists. Do not call record_flow_rca_outcome after a successful terminal
receipt from this tool.
Example:
record_flow_rca_outcome
Preserve a staged Flow RCA or manually recover corrected finalization. Use this
after inspect_flow_failure when correction cannot yet run and you need to save
an exact staged next action, or when a completed linked verification already
exists and the combined finalizer needs manual recovery.
On success, returns
success: true with outcome, protected_gold (present
only for corrected outcomes backed by verification; null for staged),
already_completed (whether protected gold already existed), and
thread_context_persisted. Staged outcomes update the run’s rca_outcome but do
not create protected gold. On failure, returns success: false with error and
may include required_citations when citation validation fails.
For raw evidence use inspect_flow_failure; for ordinary Flow work use
flow_action. Prefer run_flow_rca_verification for normal corrected
completion.
feed_metadata_review_tools
Review a proposed feed_metadata onboarding row against its source, intermediate
silver, and BigQuery publish contracts before human approval. The review is
offline and uses only the row, mapping evidence, runtime type overrides, and DDL
supplied in the call; no configuration or connection is required.
review_proposed_feed_metadata
Use this tool when authoring or reviewing a feed mapping, especially when the
migration includes source-to-target casts, audit fields, data-quality rules, or
SAP identifiers. Supply source declarations and rule evidence separately in
mapping_rules; the proposed row is not treated as proof of its own behavior.
The result contains:
valid—trueonly when no blocking contract errors are found.findings— errors and unresolved-evidence warnings, each withcode,severity, anddetail.stages— the intermediate silver business type (STRING) and the typed BigQuerypublish_schema.ready_for_parity_claim— alwaysfalseuntil independent source behavior is proven; missing RCTL records or stored-procedure behavior must be supplied by a source owner.
inferSchema or cloudFiles.inferColumnTypes enabled, non-empty schemaHints or
cloudFiles.schemaHints, and DECIMAL or NUMERIC types without precision.
The SAP identifiers REQUESTID, MATNR, WERKS, MEINS, EBELN, EBELP,
VBELN, and VBELP must map to a STRING publish field with a preserve cast;
feed-rule artifacts additionally require both source and target types to be STRING.
A CSV or TSV reader, directly or through
cloudFiles.format, whose mode is not FAILFAST must also provide evidence in
mapping_rules that short rows are routed to the error table:
evidence or pilot_assumption with non-blank reviewed text. The
guard is evidence checked by the review tool; it does not configure the reader or
route rows at runtime. Without FAILFAST or valid guard evidence, the review
reports a blocking finding because short rows may be null-padded or dropped
without being counted.
propose_feed_metadata_from_mapping
Use this tool to draft a reviewable feed_metadata row from a separately
reviewed mapping manifest and a pinned target template. It derives the row and
column override changes, preserves provenance, reports explicit unknowns, and
runs the feed contract review. The result is a proposal only: its
approval_status is always pending_human_review.
The tool validates the template pin and mapping provenance before proposing
changes. Each operative template cast for a publish field needs an evidenced
retain, replace, or remove disposition; generic overrides for absent
columns are derived from the difference. Missing pin, provenance, or required
override evidence raises a validation error. Do not fill missing cast,
data-quality, default, or exception rules from sample rows.
The result contains:
rowandcolumn_overrides— the proposed feed row and runtime type overrides.row_diffandoverride_diff— changes from the target template, with provenance and override dispositions.row_provenanceandoverride_provenance— evidence references for proposed values.unknownsandreview— unresolved behavior and the existing feed contract review.approval_status,template_sha256, andmapping_review_ref— review state and proposal provenance.
gcs_tools
Google Cloud Storage (GCS) object storage: list buckets, list objects, download
objects, and preview small text objects using a saved Google Cloud (gcp)
service-account connection. This is the GCS analogue of the S3 read path in
aws_action. It reuses the same gcp connection type that powers
gcp_cloudrun_tools — no separate connection type is
required. Create the connection under Config → Connections with
Service Account credentials (project_id, client_email, private_key).
gcs_action
Use this function to list buckets, list objects in a bucket (optionally by
prefix), download one object into the bot git repo, or preview a small text
object inline. Start with list_buckets or list_objects to confirm
authentication before downloading.
Actions
On success, responses include
success: true plus action-specific fields. On
failure, responses include success: false with an error string.
Example:
gcp_cloudrun_tools
Build and deploy applications to Google Cloud Run and related GCP delivery services.
gcp_cloudrun accepts tail_lines (integer, default 100) for the
GET_BUILD_LOGS action. bot_id and thread_id are implicit from the acting
agent context; user_id is implicit from the requesting user context.
gcp_secrets_tools
Store and retrieve secrets through GCP Secret Manager. It pairs naturally with Cloud Run deployment workflows.
gcp_secrets receives bot_id and thread_id implicitly from the acting agent
context and user_id implicitly from the requesting user context. Its
page_size parameter is an integer with default 50 and controls the number of
results returned for list actions.
genesis_enhancement_tools
Create, synchronize, and package Genesis enhancement or support requests, including automatic CREATE_REPORT submission when configured, plus offline ZIP-based exchanges.
genesis_enhancement_action
Use this function to create, inspect, update, submit, and synchronize Genesis support or enhancement reports. For support workflows, CREATE_REPORT can export a thread, attach the resulting bundle directly to the report, and return a delivery object that tells you whether Genesis actually submitted the ticket.
The requesting user’s identity is supplied implicitly for report attribution;
see the Genesis Enhancement API report fields.
Key parameters
If the tool has an active thread context, omitting
attach_thread_id auto-attaches that thread. attach_thread_id="current" forces the same behavior explicitly.
When report attachments are created, the report payload includes an attachments array that the Support and Enhancements UI exposes as downloadable files.
Successful CREATE_REPORT, UPDATE_REPORT, and most SUBMIT_REPORT calls can also include a bundle object for the scrubbed support ZIP and its delivery affordances. The ZIP contains report.md, report.json, scrub_manifest.json, and any attached artifacts collected for the report. When bundle scrubbing is enabled, Genesis redacts supported text artifacts before packaging and leaves binary attachments unchanged. download_url is returned as a root-relative Genesis link on the current origin, resolving as /api/git/... in standalone and local deployments and /git/... in SPCS.
UPDATE_REPORT always regenerates bundle from the current report content after a successful update. SUBMIT_REPORT also attaches a fresh bundle when delivery did not succeed online (queued_offline, send_failed, receiver_not_configured, and similar outcomes) so manual follow-up links reflect the latest report. When SUBMIT_REPORT returns success: true with mode: online, Genesis omits a redundant local bundle because the receiver already received the artifacts.
For generated email affordances, titles longer than 120 characters are clipped at a word boundary and marked with an ellipsis in the subject only. The report body includes the full title.
Successful
CREATE_REPORT calls also include a delivery object that reports the actual submit outcome instead of implying the report was queued.
When
delivery.status is submitted, share delivery.ticket.ticket_url if it is present and stop there. Otherwise quote delivery.message, then offer eml_link, mailto_link, and download_url in that order. download_link is the Markdown-formatted equivalent of the final fallback.
GET_SETTINGS returns the current enhancement settings, and UPDATE_SETTINGS accepts a partial settings object. Bundle-delivery fields in that object are:
Omit a field in
UPDATE_SETTINGS to keep the currently stored value.
Cursor Agent actions
START_CURSOR_AGENT, GET_CURSOR_AGENT_STATUS, and FOLLOWUP_CURSOR_AGENT
use the same launcher as the Software Factory page. Genesis resolves
Cursor Cloud credentials from the calling user and bot context when the cloud
adapter is active.
Together these actions form a dispatch → watch → steer lifecycle:
The action names retain
CURSOR_AGENT for compatibility, but dispatch through
the provider-neutral backend selected by
genesis_enhancements.coding_agent.backend. Cursor Cloud supports multiple
concurrent runs; Claude Code uses a per-run worktree and is bounded by
genesis_enhancements.coding_agent.claude_code.max_concurrent_runs (default
1). FOLLOWUP_CURSOR_AGENT is supported when the selected backend exposes
follow-up sessions; an active Claude Code run returns busy: true and
retryable: true until it reaches a terminal state.
For Linear automation, each queued attempt has its own orchestration thread and
idempotency seed. Keep that seed unchanged for the lifetime of one attempt, but
use a new seed when an issue is re-queued after a failed attempt; a previous
terminal run is not reused for the new dispatch.
The launcher is enabled by the selected backend. Cursor uses
genesis_enhancements.cursor_agent.enabled; Claude Code uses
genesis_enhancements.coding_agent.backend: claude_code and
genesis_enhancements.coding_agent.claude_code.enabled. Configure a local
Cursor runner with CURSOR_AGENT_RUNNER_COMMAND, a cloud Cursor adapter
with a shared Cursor connection plus
genesis_enhancements.cursor_agent.connection_name and
genesis_enhancements.cursor_agent.target_repo_url. On the cloud adapter,
set genesis_enhancements.cursor_agent.model to pin a Cursor Cloud model slug
for new runs (empty string inherits the Cursor workspace default), or pass
model on a task_prompt start to override that setting for one run. For
Claude Code, configure the claude_code connection, target repository, and
GitHub connection described in Cursor and Claude Code coding backends.
See Support and Enhancements — Software Factory.
Example:
discard_enhancement_report
Use this tool when a support or enhancement ticket was filed in error and has not
been sent to Genesis online. It accepts reports with status draft, queued, or
send_failed. A report handed over in an offline export may already be with
Genesis; if it later returns with Genesis’s status, it cannot be discarded here.
Discarded reports remain as records with status
discarded and the discarder’s
identity, time, and reason. They stop appearing in report lists, summaries, and
unsent exports; LIST_REPORTS with status="discarded" can still retrieve them.
Discarding the same report again changes nothing. Reports already sent to Genesis
are refused; use genesis_enhancement_action with ADD_FEEDBACK to explain why a
sent report is no longer needed, or UPDATE_REPORT to correct its content.
The caller needs either manage_genesis_enhancements or access_config_panel.
A successful call returns success, report_id, title, status, and the
discard details. A refusal returns success: false with an error.
Each call reads the report store once; the first successful discard also performs
one atomic rewrite. Repeated discards and refusals do not rewrite the store.
Example:
Thread goal tools
Two tools, carried by the always-availablecontext_tools group: get_thread_goal and
declare_goal_turn_status. Use them on a thread pursuing a goal to report where the
goal stands and to close it.
Goal mode has no checkers. Every item on a goal’s finish line is attested by the
agent pursuing it: an item reads met because the agent declared it met, and a goal
reaches met when every item does. Nothing else closes one. A blueprint phase
separately enforces its own exit_criteria at its exit gate, so declaring an item met
does not get a phase past a deliverable it is missing.
A thread that is pursuing a goal carries an ACTIVE GOAL ON THIS THREAD block in the
agent’s context, re-rendered every turn and beside every tool result. No block means
no goal, so neither tool is the way to find out whether one exists; a thread with no
goal is told nothing at all about goals, and calls on such a thread are refused.
get_thread_goal
Reads the goal and how far along it is. Takes only the implicit bot_id and
thread_id, and returns:
declare_goal_turn_status
Declare where the turn left the goal, before finishing any turn on a goal thread —
including a turn where nothing worked out. A turn that declares nothing counts as a turn
that made no progress. After declaring, tell the person where things stand rather than
ending the turn on the declaration.
A turn is one reply to the person, not one tool call. You can declare more than once in a
turn; the last declaration stands. If one reply crosses multiple blueprint phases,
declare for each phase before leaving it. Item IDs from a phase are refused after the
mission has left that phase, so do not wait until the end of the reply to declare them.
Questions in
questions_for_person are queued for the person while the agent carries
on. They do not pause or end the goal. awaiting_person pauses it until the person
replies, and resumes it on that reply. Mark an item blocked only when a reply on this
thread cannot move it: leave the item unmet and use awaiting_person when the person
can move it by replying or acting here. A blocked item ends the goal, though a
person’s next turn or a later declaration with no blocked items can revive it.
get_thread_goal reports the previous block in revival after that happens.
Each stance says what the goal is waiting on, and they are not interchangeable:
awaiting_run is an asynchronous job the agent started, while awaiting_agent is
another agent owing it an answer. finished says the agent has nothing further to do —
with every item met that closes the goal, and with items still open it leaves the goal
for the person rather than being nudged again.
A person’s reply does not pause a goal already marked awaiting_person; it resumes it.
For a goal that ended blocked, the person’s next turn revives it as well. If that
blocked ending remains in effect, do not declare the same item blocked again: that
declaration is refused. Instead, report the currently true stance and statuses without
marking an item blocked, or tell the person what still needs to happen outside this
thread.
When the write is refused after the goal has been read, the error explains what was
rejected and appends a reminder that nothing was recorded and the turn currently counts
as no progress. An unknown item error also lists the goal’s valid item IDs. Fix the
named issue and call again in the same turn before finishing.
success, declared, explanation, and the projected
outcome. The declared field echoes the accepted stance and criterion_status; the
explanation notes that the declaration is parked until turn end. The declaration
is recorded against the current turn and applied to the goal when the turn ends; until
then, a goal block rendered during that turn still shows the state before the
declaration. Declare finished items as you complete them: declarations from separate
turns accumulate on the goal. If you call more than once in the same turn, the later
call replaces the earlier one, so repeat every ID you still want applied. Each
declaration is parked against the goal bound when it is made — in a blueprint, the
active phase. finish_line_after_this maps every finish-line item ID to its status
after the declaration is reconciled. goal_after_this gives the goal’s projected
status, verdict and resulting questions_for_person queue. For a goal covering one
blueprint phase the shape differs: there is no status key, because a phase-scoped
"status": "ended" was read as the mission ending while the phase was still open. That
shape carries scope and holds_if, plus phase_still_open (always true),
you_still_owe (the call that leaves the phase), phase_finish_line (where that
phase’s finish line lands), goal_record_status (the lifecycle word status would have
held), exits_phase and phase_ends_when: exits_phase is always false, because
declaring that the finish line is met ends the goal, not the phase. The phase remains
active until you call PROCEED_TO_NEXT_PHASE or EXIT_PHASE; on the blueprint’s last
phase, that call also completes the run. The phase still enforces its own exit criteria
at the exit gate. Entering another phase binds a new goal and discards a declaration
parked against the previous one. The projected status and verdict include whether the
goal is paused; use get_thread_goal when you need the committed record mid-turn.
If the turn outcome cannot be judged, the declaration is still recorded, but the
response returns projection_unavailable instead of the projected fields. Call
get_thread_goal to read the goal’s current state.
Declare for a blueprint phase before leaving it; its item IDs are no longer valid after
the transition. Only the declaration for the goal still bound at the end of the reply
is applied, so a reply that crosses phases reports the last phase. Do not call
declare_goal_turn_status in the same parallel batch as PROCEED_TO_NEXT_PHASE or
ENTER_PHASE: whichever call lands first determines which phase the declaration
applies to, and a batched finished stance can close the goal before the phase-exit
gate runs.
The nudge budget
A goal-mode thread is carried on by a nudge: when a turn ends with the goal unfinished and nothing being waited on, Genesis sends the thread one message asking for the next step. Only aprogressing stance is nudged; other stances indicate that
carrying on is not what is missing. The per-progress ceiling defaults to three nudges
without progress (goal_mode.max_nudges), and resets when the agent reports progress.
A separate lifetime backstop defaults to 50 total nudges for the phase
(goal_mode.max_total_nudges) and is never reset by progress. Reaching either ceiling
stops nudging and leaves the goal open for the person — it does not end the goal or
discard the work. The limits apply to newly created goals; a running goal keeps the
limits it started with. See Goal mode limits
for configuration details.
autodev_lane_tools
The autodev_lane_tools group dispatches Genesis development tickets to a
background coding run that ends in a branch, pull request, and verification
verdict. It is separate from the in-thread coding tools, which do not publish a
pull request. The start, status, and followup actions use the same run
metadata described above; the review actions below manage the server-owned PR
review cycle for enrolled Factory runs.
For a Factory turn, Genesis injects the shipped Factory orchestration procedure
before dispatch and supplies repository-backed coding workers with the checkout’s
root rules and full repository skill catalog. The worker starts with
factory-repo:factory-execute; this runtime context is supplied by Genesis and
does not add a separate tool, permission, or configuration setting.
Review actions
review_source identifies a GitHub node with { "kind": "thread" | "review", "id": "..." }.
Each findings item includes source, disposition (accepted, fixed, or
declined), and code-bound evidence. Read a fresh snapshot when an operation
reports a stale snapshot; do not repost or start another run after an unknown
dispatch or reply result.
For enrolled Factory runs, the factory_result response contract and terminal
state semantics are documented in Coding Agent run metadata fields.
The review loop is enabled by default with
genesis_enhancements.coding_agent.review.enabled; max_rounds: 0 means
unlimited correction rounds, and active_cycle_timeout_seconds applies only
while active correction is underway. Cursor runs are not enrolled in this loop.
Runtime recovery
When an enrolled coding run stops at a trusted runtime boundary, its status containsfactory_result.recovery with the blocker or pending human-answer
candidate. Call recover with the exact recovery_snapshot_id from the latest
status. Use recovery_kind="retry" only for a confirmed transient fault;
use context or environment only after applying the corresponding supported
change. Use ask with handoff_reason and a complete recovery_handoff when
the next step needs a specific human decision or access, or use stop with a
concrete technical reason when no useful remedy remains.
For ask, Genesis posts the question to the assigned Linear issue. The Linear
automation poller checks for a matching reply every
ticket_automation.linear.poll_interval_seconds seconds (default 60), then
wakes the same orchestration thread. A sufficient answer starts a fresh coding
run on the same task, thread, and branch; it does not resume the prior SDK
session and does not require a manual restart. When a reply is pending, pass
its exact recovery.candidate.id as recovery_answer_id and use the current
recovery snapshot.
recovery_handoff must provide non-empty reason, evidence, checked,
why_human, and resume_condition values. The server owns Linear comments,
state transitions, recovery deadlines, and duplicate prevention.
Example:
delivery so the caller can tell the user whether the report was submitted or still needs manual follow-up.
google_calendar_tools
Create, update, list, and delete Google Calendar events for scheduling automation.
handoff
Spawn worker threads, delegate work to another bot, and retrieve or cancel results. See Process Manager Tools for the full lifecycle.
jams_tools
Interact with JAMS job scheduling systems from Genesis. This group uses the
effective default jams connection for the current user (My default, then Role
default) from Connections unless you pass a
specific connection, and it accepts either numeric IDs or qualified names such
as \\Finance\\DailyClose.
jams_tool
When multiple role defaults for
jams conflict, Genesis returns an error directing you to set a user default or pass connection explicitly. See Default connection layers.JAMS connections support Username & Password (JAMS API login) and HTTP Basic (IIS/Windows) when IIS gates the REST API. If authentication fails and Genesis detects an IIS/Windows challenge, the error suggests switching auth type in Config -> Connections. See JAMS connections.
Available actions
Submission workflow
- Use numeric IDs or qualified names such as
\\Folder\\JobName. Avoid bare job names because they can be ambiguous across folders. - Call
GET_JOB_PARAMETERSbeforeSUBMIT_JOBto discover valid parameter names and required fields. Genesis treats a JAMS parameter as required when the API marks eitherrequiredormustFill. SUBMIT_JOBfollows the JAMS v7 swaggerSubmitInfoflow: Genesis first fetches the job’sSubmitInfo, applies matchingparameters, then posts the fullSubmitInfoobject back to JAMS.- When
SUBMIT_JOBreturns ajamsEntry, useGET_ENTRYwith that ID for the most reliable status check.GET_LATEST_ENTRYis still useful when you need to look up the newest entry by job.
jenkins_tools
See Jenkins for the customer-facing setup and CI/CD workflow path. When connection is omitted, Jenkins tools resolve the effective default jenkins connection for the current user (My default, then Role default).
jenkins_config
Manage the Jenkins configuration used by Jenkins tools. SET saves the install-wide jenkins.shared connection; it does not save the token to a local plaintext file or environment variable. A complete set of values replaces the shared configuration. If values are omitted, SET fills them from the existing shared connection. Changing the URL requires a new api_token; the stored token is not reused for a different server. GET returns the current resolved configuration with the token masked, and TEST checks connectivity. When testing a different URL, provide its api_token explicitly.
Example:
matillion_tools
Operate Matillion Data Productivity Cloud projects, pipelines, and executions from
Genesis. When connection is omitted, Matillion tools resolve the effective default
matillion connection for the current user (My default, then Role default). If no
default is set and exactly one Matillion connection is accessible, that connection is
used automatically. When multiple connections exist without a default, pass
connection explicitly or call LIST_CONNECTIONS to discover available options. For
setup and workflow details, see Matillion Connector.
Use airbyte_connector for Airbyte data syncs instead of matillion_connector.
For UPLOAD_ARTIFACT, each publish replaces the environment’s entire published
bundle — include every pipeline that must stay runnable in one call. Prefer
yaml_repo_id + yaml_file_paths (paths and/or globs) to publish multiple files
atomically; use yaml_content + artifact_path or yaml_repo_id + yaml_file_path
artifact_pathfor a single file. Usegit_actionwhen you only need to read, commit, or branch pipeline YAML without uploading to Matillion.
matillion_connector
Available actions
Every action returns a dict with
success. On success, payload keys depend on the
action — for example connections, count, and message for LIST_CONNECTIONS;
executions, count, status_counts, and failed_count for LIST_EXECUTIONS;
published_pipelines, artifact_history, published_count, artifact_count, pipelines, count, and note for LIST_PIPELINES; published_files, evicted_pipelines, and warning for UPLOAD_ARTIFACT; projects for LIST_PROJECTS;
status for GET_JOB_STATUS. On failure the response carries error (sometimes with
troubleshooting). Recover with TEST_CONNECTION, RTFM, LIST_CONNECTIONS, or by
naming the Matillion connection explicitly.
LIST_CONNECTIONS response details:
LIST_EXECUTIONS response details:
LIST_PIPELINES response details:
When
runnable_only=true, the response contains only published_pipelines, count, and note (upload history omitted).
UPLOAD_ARTIFACT response details (success):
Example:
mcp_admin_tools
Connect Databricks Genie spaces and other HTTP MCP servers at runtime without restarting Genesis, list configured runtime MCP servers, and remove them when no longer needed. Genesis registers each remote MCP endpoint as a persistent tool group and exposes its remote tools to the active thread.
These runtime registrations are persisted under the mcp_servers configuration
key (type dict, default {}). The Connections UI also uses this store for
saved MCP Server connections; see MCP server connections
for authentication modes, shared/private visibility, and interactive sign-in.
All tools in this group require the manage_all_connections permission.
This group is distinct from the hosted Genesis MCP Gateway that exposes Genesis to external MCP clients such as Claude Code. See Agent Gateways and Hosted MCP for Claude Code for that outbound integration path.
Grant the mcp_admin_tools tool group to agents that should perform these
operations, and ensure a saved Databricks connection exists before
connecting Genie spaces. See Databricks Action Tools
for workspace connectivity.
Connection parameters accept either a bare connection name (for example genie_sp) or the fully qualified form shown in connection listings (for example databricks.genie_sp). Genesis normalizes to the bare name before lookup.
list_genie_spaces
List Databricks Genie spaces visible through a stored Databricks connection. Use this before add_genie_space when the user does not know a space ID.
add_genie_space
Connect one Databricks Genie space as live MCP tools for the current thread. Genesis builds the Genie MCP URL from the workspace host and space ID, mints a bearer token from the stored Databricks connection, and registers the remote tools.
add_mcp_server
Connect a generic HTTP MCP server as live tools without restarting Genesis. Prefer add_genie_space for Databricks Genie spaces because it constructs the correct Genie MCP URL from a space ID.
list_mcp_servers
List runtime HTTP MCP servers persisted in Genesis. Tokens and resolved credentials are never returned.
remove_mcp_server
Remove a runtime HTTP MCP server and its live tools from the registry.
Typical Genie workflow
After
add_genie_space or add_mcp_server succeeds, the user can ask natural-language data questions against the connected Genie space or remote MCP tools. If registration fails, verify the Databricks connection, space ID, workspace permissions, and that the caller holds manage_all_connections.onedrive_tools
Microsoft OneDrive personal-drive operations via Microsoft Graph API. This tool is not for SharePoint site URLs or SharePoint Connections; use sharepoint_tools for SharePoint content. See Microsoft OneDrive for the customer-facing setup and usage path. When the onedrive tool runs without a named connection, Genesis resolves the effective default onedrive connection for the active agent (My default, then Role default). Legacy credentials from Config -> Microsoft OneDrive apply only when no scoped default resolves.
outpost_tools
Configure Genesis Outposts: a small program a customer runs inside their own network (a laptop to try it, a VM, Docker or Kubernetes, on AWS, Azure, GCP or on-prem) that dials out to Genesis so it can reach private hosts such as internal databases, Jira or GitLab Data Center, and internal APIs. A connection goes through an Outpost when it is set to Through a Genesis Outpost, or when its host matches a domain pattern the Outpost routes (for example *.corp.internal). A connection’s password or secret can stay in the customer’s secret store as outpost_<outpost>/<secret-name>#<json-field>. See Genesis Outposts for setup, security and troubleshooting.
For self-hosted Docker listener behavior and Outpost port availability, see Genesis on Docker.
All tools in this group require the manage_all_connections permission. The in-product skill outpost-setup walks an agent through the whole setup.
save_outpost creates the definition but does not issue its tunnel key. After creating an
Outpost, open Config -> Outposts -> Install and choose New tunnel key; Genesis shows
the key once. See Each Outpost’s tunnel key
for the setup and migration behavior.
list_outposts includes tunnel_key_warning when Genesis has not issued an Outpost a tunnel
key, even when include_status=false. Relay the warning as written; it says the Outpost cannot
sign in and how to issue its key. For a key_refused diagnosis, see
Outpost Troubleshooting.
When the Snowflake Native App does not expose the Outpost tunnel endpoint, list_outposts
reports the feature as disabled, and set_outposts_enabled with enabled=true and
get_outpost_install_instructions fail with the reason Outposts are unavailable; relay that
reason as written and do not retry. Native App support is version-dependent; see
Genesis Outposts for availability.
outpost_tools parameters
For example, check whether a database locator would use an Outpost before
creating its connection:
explain_outpost_routing; it returns the selected Outpost
or says that the connection will be reached directly. See Connect a system through an Outpost
for the dashboard flow.
power_bi_tools
Browse Microsoft Power BI workspaces, inspect reports, check dataset refresh
history, trigger refreshes, and update dataset data-source bindings or
parameters. This group uses the effective default power_bi connection for the
current user (My default, then Role default) from
Connections unless you pass a specific connection.
Grant agents the power_bi_tools tool group and a saved Power BI connection
before calling these actions.
power_bi_connector
Available actions
Successful responses include
success: true plus action-specific fields:
workspaces for LIST_WORKSPACES, reports for LIST_REPORTS,
latest_refresh and refresh_history for GET_REFRESH_STATUS, and message
for write operations. When no effective default Power BI connection exists for
the current user, Genesis returns an error directing you to Config ->
Connections. When multiple role defaults conflict, pass connection explicitly
or set a user default.
Example:
openmetadata_tools
Search and manage OpenMetadata entities and governance metadata. When
connection is omitted on openmetadata_connector, Genesis resolves the
effective usable openmetadata connection for the current user and active bot
(My default, then Role default). Pass an explicit connection name such as
openmetadata.prod when you need a specific saved connection. If no usable
default applies, the tool returns the structured connection-selection response
described in connections_action.
See OpenMetadata for the customer-facing setup and governance usage path.
openmetadata_connector
Use ADD_TAGS or REMOVE_TAGS to apply or remove classification tags on an
OpenMetadata entity or one of its columns. These actions find a column by name
or fully-qualified name, so you do not need to calculate its position in the
entity’s columns array.
Adding a tag preserves existing tags and adding the same classification tag
twice does nothing. Removing tags affects only the classification tags named
in
tags; glossary-term tags are left unchanged, even when their names match.
Use UPDATE_ENTITY with method=PATCH to attach a glossary term with
source set to Glossary.
When the requested tags already match the current state, the response includes
changed: false and no write occurs. Tag updates read the current list and
replace it with the merged list, so a tag added by another writer between the
read and write can be overwritten.
Examples:
railway_tools
Railway-backed runtime choices are documented in Sandbox Sessions.
railway_action
Use this function to inspect available Railway connections, list projects, retrieve project inventory, manage environment variables, trigger deploys, and run GraphQL passthrough operations.
Railway auth can resolve from
credential_name, an explicit token, or environment variables RAILWAY_TOKEN and RAILWAY_API_TOKEN. For Railway-backed sandbox and terminal flows, Genesis keeps the auth mode that passed its live SSH check so reconnects reuse the verified credentials.
Example:
remote_app_deploy_tools
Set up Snowflake SPCS ingress access for remote apps, deploy Genesis Apps to
external sandboxes, tear them down, and check remote health.
remote_app_deploy_action
bot_id and thread_id are also injected implicitly from the active tool
context and do not normally need to be supplied manually.
Remote deployments mint
GENESIS_APP_TOKEN for the delegated caller
identity, so remote apps can keep calling Genesis APIs with
X-Genesis-App-Token when platform auth is enabled.status queries the live deployment backend when possible. Its response can include the resolved URL, URL Type (such as external or cluster_internal), backend status, ready replica counts, and health-check results.
Example:
palantir_foundry_app_tools
Prove that a GenesisApp rebuilt from a Foundry Workshop app displays the same
values as the Workshop app. Assign this group alongside palantir_foundry_tools,
then build the app from foundry_describe_app’s spec and land its ontology
tables in Databricks. For the migration workflow and verdict meanings, see
Migrating and proving a Workshop app.
foundry_prove_app
Compares each displayed value, compiled chart layer, pivot table, and object table
from Foundry’s Ontology API with the rebuilt app for supplied or randomly sampled
inputs. The result includes passed, a verdict summary, mismatches in
findings, unsupported values and widgets in not_covered, rendered-page checks,
the inputs and random seed, and a proof_file containing every check. For
mismatch diagnosis and verdict meanings, see the integration guide.
bot_id, thread_id, and user_id are injected from the active tool context.
The proof can make multiple Foundry and app requests per input. See the integration
guide for end-to-end cost and deployed-app behavior.
rbac_action_tools
Automate role, permission, and access-governance tasks. For the administrative model and governance guidance, see Users and Roles and RBAC Practical Guide.
rbac_action
Read actions validate identifiers before returning data. When
role_name or agent_id does not exist, rbac_action returns success: false with an error message instead of an empty success payload. Role and agent lookups can include Did you mean: ...? suggestions when Genesis finds close matches.Successful write actions (ASSIGN_ROLE, REVOKE_ROLE, and other mutating actions in this tool group) also append rows to ADMIN_AUDIT_LOG with source=bot and the acting bot ID as actor_user_id. See RBAC Practical Guide → Admin audit log.sandbox_tools
Provision and operate sandbox execution environments, then run commands,
install dependencies, move files, and inspect results. This is also the
preferred first tool group for AWS infrastructure analysis, EKS/Kubernetes,
Helm, kubectl, AWS CLI, boto3/AWS SDK, cloud deployment, and cloud
monitoring tasks.
sandbox_action
Use sandbox_action for long-running image builds and registry readiness
checks when you need a polling-friendly status contract.
For EKS/K8s backends, Genesis injects AWS credentials from the caller’s scoped
default AWS connection when credential_name is omitted from
backend_options. For Railway-backed flows, Genesis resolves the caller’s
scoped default Railway connection when no explicit credential_name is
provided. Jenkins image builds resolve the scoped default jenkins
connection the same way. See Default connection layers.
For EKS/K8s work, prefer
backend="eks" or backend="k8s" with a saved
target_env when possible, or include explicit backend_options plus
credential_name so cluster auth does not depend on a kubeconfig in the
Genesis application container. The packaged guidance skill for this workflow
is aws-eks-sandbox-operations; the older
deploy-helm-chart-eks name remains a compatibility alias.Default backend
Thebackend parameter defaults to "local". When the operator configures
sandbox.default_backend (for example via Helm sandbox.defaultBackend on
EKS, GENESIS__SANDBOX__DEFAULT_BACKEND, GENESIS_SANDBOX_DEFAULT_BACKEND,
or sandbox.default_backend in genesis-config.yaml), calls that omit
backend or pass backend="local" automatically resolve to that configured
default (for example "eks" on EKS deployments). Explicit backend values
other than "local" are always honored.
In a Databricks App, local is unavailable because it starts Docker on the
Genesis host. It is omitted from the backend list and an explicit local start is
refused; choose a remote backend instead.
Azure Container Instances
Setbackend="azure_aci" to run a Linux sandbox in Azure Container Instances in the customer’s
own Azure subscription. For what it is, setup, everyday use and error messages, see
Azure Sandboxes,
Set Up Azure Sandboxes,
Use Azure Sandboxes and
Azure Sandbox Troubleshooting.
Each sandbox is one container group (genesis-sbx-<id>) with one container. start waits for the
group to run (about 25 to 30 seconds with the default image, up to 10 minutes), and stop deletes
it. The container’s main process sleeps for the session’s max_lifetime_minutes (default 480)
with restart policy Never, so it exits and stops billing even if Genesis is down; the sandbox
monitor also stops sessions past their idle timeout (default 30 minutes for an agent start) or
maximum lifetime. Each command adds about two seconds of overhead; its output is
SHA-256-verified end to end.
For Azure sessions, output from sandbox tool commands is also mirrored into the session’s
terminal history, alongside interactive terminal activity.
start requires a saved Genesis Azure connection: credential_name in backend_options, or the
caller’s My default, then Role default. Inline tenant_id, client_id or
client_secret in backend_options is refused, because the session must be reattached and
deleted as the same identity after a restart. Connection access is checked as the calling user
and agent. A started sandbox stays bound to the connection, subscription, resource group and
region it resolved.
Run check_backend_connection with backend="azure_aci" before starting. It requests a token
from Microsoft Entra ID, reads the resource group, and reads the principal’s effective
permissions there to confirm container-group read, write, delete and exec (one token request and
two Azure Resource Manager calls). list_backend_connections with this backend lists the Azure
connections the caller can use.
When image is omitted or is python:3.11-slim, Genesis pulls
mcr.microsoft.com/mirror/docker/library/python:3.11-slim, because Docker Hub throttles
anonymous pulls from Container Instances. Any other image is used as given; it must be Linux and
provide /bin/sh, base64, sha256sum, cat, cut, wc, cp, dd, tr, mkdir and rm.
Genesis must reach
login.microsoftonline.com:443, management.azure.com:443 and the exec
WebSocket host *.<region>.atlas.cloudapp.azure.com:19390; see
Allow Genesis to reach Azure.
For example, start a sandbox in a specific saved connection:
Repository file transfers
Use the repository transfer actions when a sandbox needs files from a Genesis Git repository or when a downloaded sandbox file must be saved back to one.
For repository-backed transfers, provide repository-relative paths only. A
Mission-restricted upload uses the complete Mission repository id, not the
uploads repository used for incoming chat attachments.
Sandbox transfer notes.
action="check_image_tag"
Check whether a tag manifest is available in a registry before starting a deployment or waiting on a build to publish.
Example:
wait_for_image_tag uses the same registry and auth parameters, then adds poll_interval_seconds (number, default 30) and poll_timeout_seconds (number, default 900) for automatic polling. Long-running build_image and get_build_status calls follow the same tool_result_status and next_poll_seconds contract while a build is still in progress.
sandbox_spec_tools
Save and manage reusable sandbox specifications such as target environments, security profiles, and container definitions.
sandbox_env
Use this function to save and validate reusable sandbox specs, target environments, and security profiles, including Railway-backed target-environment planning and apply flows.
Railway planning and apply actions also accept
workspace, project_id or project_name, service_id or service_name, environment_id or environment_name, create_project_name, create_service_name, create_environment_name, and image when you need to discover, select, or create the target resources.
Example:
sharepoint_tools
Read-only SharePoint Online file operations via Microsoft Graph API with per-user OAuth. Genesis resolves an omitted connection_name only when the effective sharepoint connection is usable by the requesting user and active bot; otherwise it returns the structured connection-selection response described in connections_action. See SharePoint for OAuth provider and connection setup.
If an operation using an omitted connection_name fails after Genesis selected the effective default, and another accessible candidate includes a warning-free option, the response also includes connection_recovery. It preserves the original error and provides the failed failed_connection_id, the default selected_source, alternative connection summaries in alternatives, and retry.tool_parameter = "connection_name". Preserve the original error and ask the user which alternative to use; Genesis does not retry automatically. Explicitly named connection failures do not trigger this recovery response.
sharepoint
Available actions
Listing folders
ForLIST, Genesis selects the folder to browse in this order:
item_id— a folder DriveItem id (from a priorLISTorGET_METADATA); lists that folder’s children.folder_path(or aliaspath) — a path relative to the drive root (e.g.Reports/2024)./or omitted lists the drive root.- With neither
item_idnorfolder_path/path, Genesis lists the drive root.
LIST responses echo the selector Genesis honored: item_id when listing by id, otherwise folder_path.
Example:
chat_work_tools
Promote the current Slack, Microsoft Teams, or Google Chat conversation into a tracked work
item on the Requests page. When
ticket_automation.auto_track_chat_requests is enabled (the default), accepted
chat messages already create a Request; agents call this tool when the user
explicitly asks to track, log, or follow up on work, or to split separate work
in an already-tracked conversation. When automatic tracking is disabled, this
tool is the only way chat becomes a work item. Correlation stays deterministic
in either mode — there is no heuristic auto-attachment.
promote_conversation_to_work
Returns
{success, work_item_id, provider, created_by, attributed_to_another} on success, or {success: false, error} when called outside a supported chat conversation or when the ledger is unavailable. created_by is the creator recorded on the work item, not necessarily the current caller: a repeat promotion keeps the original promoter, and a record with no named creator is returned as created_by.display: "unattributed". attributed_to_another is true when the record names someone else, false when it names the current caller, and null when nobody is named or the creator could not be read back. Calling the tool twice for the same conversation is safe and returns the same work item. In automatic tracking mode the conversation may already have a Request, making a repeat call idempotent unless start_new_item is true.
After promotion, replies in the same Slack thread, Teams channel reply chain
(and quoted replies in Teams chats), or current Google Chat DM episode attach to
the item automatically. Google Chat episodes do not cross a /new boundary.
On success Genesis also stores external_url on the work item so the
Requests row deep-links back to the chat
message: Slack via a best-effort permalink (chat.getPermalink using the bot’s
slack_app_token), Teams via a teams.microsoft.com/l/message/... URL from
tenant, conversation, and activity identifiers. Google Chat does not add an
external URL. Missing tokens, API failures, or incomplete identifiers omit the
link without blocking promotion. Automatic
tracking (ticket_automation.auto_track_chat_requests) applies the same
external-link behavior when it creates the Request.
Example:
slack_webhook_tools
Send outbound Slack notifications and Block Kit payloads through incoming webhooks.
Genesis injects bot_id and thread_id implicitly at runtime, alongside user_id;
callers normally provide only the notification fields.
teams_bot_tools
Send proactive messages and list reachable conversations through the Genesis
Teams Bot Framework app. Messages post as the Genesis bot principal, not as a
connected human user or a Power Automate Workflow. Requires the bot to have
Bot Framework credentials configured on Agents → [bot] → Teams, the server-wide
teams.enabled switch on, and a stored conversation reference from a prior
install or user message.
Use Activate Eve in Teams (Bot Framework)
for Azure Bot, messaging endpoint, and Teams app package setup. For posting via
a workflow webhook URL without a bot install, use teams_webhook_tools. For
posting as the connected human user via Graph OAuth, use teams_tools.
teams_bot_action
Available actions
Returns a dict with
success (bool) and either message on success or
error on failure. LIST_REACHABLE adds conversations — a list of dicts
with bot_id, tenant_id, conversation_id, conversation_type,
user_name, last_seen_at, and expires_at.
Example:
SEND_PROACTIVE returns success: False with a message about no stored
conversation reference, the bot has not been seen in that conversation yet —
ask the user to message the bot or install the Genesis Teams app in the target
channel, then retry.
If SEND_PROACTIVE returns success: False with
Teams is disabled server-wide (config teams.enabled is false); proactive sends are refused., the operator has turned off the global Teams kill-switch — set
teams.enabled back to true (or GENESIS__TEAMS__ENABLED=true) before
retrying proactive sends.
teams_tools
Send Microsoft Teams channel and chat messages through Microsoft Graph, list
Teams, channels, or chats, and look up users by email. Use
Microsoft Teams for Azure App Registration,
OAuth provider bootstrap, and connection setup.
Messages sent by teams_tools appear as the connected Microsoft user, not as a
bot. Teams channel messages cannot be deleted through the API, so verify
team_id and channel_id carefully before sending. Use delegated
User OAuth for messaging, listing, and lookup actions. Client Credentials
can validate credentials but cannot send, list, or look up in v1.
teams
Available actions
For
content_type="adaptive_card", pass the Adaptive Card body itself. Do not
pass the outer Teams wrapper envelope with type="message" and
attachments; Genesis builds that wrapper for Microsoft Graph.
Example:
type = "AdaptiveCard" and a
body list. Serialized card size is capped at 28 KB.
teams_webhook_tools
Send Microsoft Teams alerts, notifications, scheduled reports, approval
handoff cards, raw Adaptive Cards, and recent delivery lookups through
incoming webhook endpoints. This path does not require a
microsoft_teams connection or delegated OAuth.
Genesis accepts HTTPS webhook hosts matching *.logic.azure.com,
*.api.powerplatform.com, or *.webhook.office.com.
Legacy
*.webhook.office.com Office 365 connector URLs still work but return
a deprecation warning because Microsoft is retiring that connector family.
Prefer Microsoft 365 Workflows / Power Automate webhook URLs when possible.teams_webhook_action
Available actions
Delivery results
Webhook sends retry transient failures up to 3 attempts. Genesis retries connection errors, timeouts, and HTTP429, 500, 502, 503, and 504.
The result always includes delivery metadata you can inspect or log:
delivery_status:success,retried_success, orfailedattempt_countandattempts: retry count plus per-attemptattempt,status_code,duration_ms, anderror_excerptwebhook_host,payload_digest_sha256, andfinal_status_codefinal_error_excerpton failuresdeprecation_warning_present, plusdeprecation_warningwhen you use a legacy*.webhook.office.comconnector URL
teams_webhook_recent_deliveries
Recall Teams webhook delivery history from the last 7 days across threads.
Use this after teams_webhook_action when you need to confirm whether a send
arrived, how many retries it took, or why it failed.
Returns a list of delivery summaries with
timestamp_utc, bot_id,
thread_id, tool_action, status, delivery_status, attempt_count,
attempts, webhook_host, payload_digest_sha256, final_status_code,
final_error_excerpt, and deprecation_warning_present.
Example:
transition_contract_tools
Compile and execute governed transition contracts with first-hand evidence
for estate migrations (for example Postgres → Databricks). Agents use this
group to characterize source and target inventories, propose table mappings and
correspondence rules, qualify rules against edge fixtures, store transition
objectives, compile contracts, execute verification runs, and render cutover
dossiers.
characterize_source only reads estates whose engine can execute the catalog
statements through Genesis’s database connector. If the connection names an engine
whose inventory is served through its own transport rather than a SQL catalog surface,
the tool refuses before reading anything with a NON_DATABASE_ESTATE error that names
the engine. This is an engine limitation, not a permissions or transient connection
problem; do not retry it or substitute a different database or schema list.
When schemas is pinned and estate_char.characterization.full_source_default is enabled
(default true), the tool performs one schema-discovery read to detect whether the pin
exactly matches the full-source scope. See Agents and the API
for how that preserves the estate boundary and finding identities.
Estate-backed timestamps returned by this group are UTC-aware ISO-8601 values; see
Agents and the API for the shared timestamp
contract.
Human approval is out of band. Agents can propose correspondence rules and
report whether their fixtures pass, but they cannot qualify or ratify an estate
correspondence rule. A genuinely authenticated human performs those acts for the
concrete estate pair in the Ratifications worklist. Transition-contract
artifacts are qualified through Migration verification (/data/verify/overview/)
or POST /api/transition_contract/rules/{rule_hash}/ratify; when compile or
execute hits the license gate, chat shows an inline transition_contract_refusal
card with the refusal case and a deep link to Migration verification.
When an agent proposes an estate rule, its display name from the runtime bot
registry is recorded when available, so a person can identify the proposal as
coming from that agent (for example, “from Eve”). The rule-list response fields
are documented in the correspondence-rules API reference.
Long-running transition verification is handed to the registered serving loop. If
that hand-off is refused, the affected run is closed with status: "error" and the
tool returns success: false plus its run_id, so callers should not keep polling it
as running. If closing the row also fails, the response includes
terminalization_failed: true and the row may remain running until startup
reconciliation.
characterize_source accepts notify (boolean, default true) alongside its
bounded wait_seconds window. When it is enabled from a Genesis thread, the thread
receives the terminal result on its next tool result, or in a new turn after it goes
idle, so it does not need to poll get_characterization_run. Set notify=false when
you specifically want to check the run yourself.
The comparison-scoped worklist filters foreign proposals and exposes blocked_reason
for proposals that remain visible but cannot be approved; see the worklist and
withdrawal endpoint.
Its rows also expose default_refusal for rules that must not be offered as
pre-ticked platform defaults; see the rule-review endpoint
for the response semantics.
Withdrawing a correspondence proposal is allowed only while both the rule definition
and this comparison’s binding still say proposed. If the definition is retired, the
pair binding was revoked, or the rule is ratified for this pair, the refusal explains
that state and says there is nothing to withdraw. If this pair has no binding, the
response reports that fact without treating a definition’s historical ratified flag
as a live licence for this comparison; revocation is a human authority act, not a
proposal withdrawal.
The proven bigquery->databricks pair has default binding correspondence decals,
so its observed type-name spellings and value-rendering differences are licensed
without per-migration ratification. This covers exact-preserving mappings such as
NUMERIC to decimal, INT64 to bigint, and UTC timestamp or decimal-scale
rendering differences. The built-in mssql->snowflake type rule also licenses
T-SQL float(53), float(24), and real against Snowflake FLOAT (the target’s
single 64-bit float representation), including Snowflake’s equivalent float
spellings such as DOUBLE. Exact decimal and numeric types remain distinct from
this approximate-float family, so a decimal-to-float change is still unlicensed.
The built-in mssql->databricks pack also covers T-SQL varbinary, binary, and
image storage families to Spark binary, the two-valued bit rendering (1/0
to true/false), and UTC or offset-less datetime2, smalldatetime, and
datetimeoffset renderings to Spark timestamps. These are checkbox rules: binary
value differences remain content findings, NULL remains owned by nullability,
and a non-UTC offset still flags because it can identify a different instant.
It also includes a checkbox rule for T-SQL geography and geometry (including
geography(max) and geometry(max)) rendered as Spark string. This licenses
the type spelling only: spatial values are not compared, their content and
boundary findings remain indeterminate, and the target text is not asserted to be
well-formed WKT, WKB hex, or GeoJSON. The reverse mapping and xml→string are
not covered.
For text distinct-count comparisons, the MSSQL digest adapter now hashes the
operand with a SQL Server 2019+ _UTF8 collation so byte-identical non-ASCII
content can be corroborated against Databricks’ UTF-8 digest.
The same mssql->databricks pack recognizes engine-issued surrogate keys from
source catalog provenance: SQL Server IDENTITY columns, columns whose
DEFAULT draws from a SEQUENCE, and declared foreign keys onto those columns.
It licenses value-level differences that can result from rebuild renumbering,
including bounds, content digests, and category distributions, but not
cardinality differences. The rule is source-side and does not use a column-name
pattern, so date columns such as Invoice Date Key remain ordinary findings.
When the schema has no foreign key for a known engine-issued ledger, a named
person may pass a provenance_assertions proposal to characterize_source to
identify the source column and its exact dependent columns. The scan verifies
the source against the live catalog and refuses contradictory assertions; the
proposal only makes those columns eligible for the ordinary rule, which still
requires binding and human ratification.
The built-in sqlite->databricks and sqlite->snowflake packs likewise seed
assumptions for proven exact type spellings, so those spellings are not reported as
findings by default. The precise mappings and the rejected narrowing or cross-class
landings are documented in Genesis Prover’s assumption rules.
The postgres->snowflake and postgres->databricks pairs also have built-in platform
type rules. They bind automatically as declared-type assumptions rather than pack
proposals; built_in_count includes these rules when availability_only=true. Their
exact type-preserving mappings and limits are described in Genesis Prover’s assumption
rules.
Genuine value changes, lossy cross-class mappings, and unmapped types remain
unlicensed and are still reported by the diff.
For the structural-only eligibility boundary and single-rule path for
data-derived differences, see the platform-default consent endpoint.
Row-identity keys can be single-column or composite. Compiled obligation
frames carry key_columns (ordered list) and key_source (declared when the
source estate supplied the key, designated when a human asserted it). The legacy
key_column field is populated only for single-column keys. A human key
designation — asserting which columns identify rows when neither estate declared
one — is also out of band: put_transition_objective refuses objectives that
include key_designations. Operators designate keys from the run-detail UI or
via POST /api/transition_contract/objectives/{objective_hash}/designate-keys,
which derives an immutable successor objective. Column order in a designation is
significant — it becomes the comparison sort order.
For keyed table spot checks without the transition-contract registry, use
verify_against_contract from system_diff_tools instead.
ratify_correspondence_rule
This tool does not ratify a rule. It refuses the agent’s authority act and returns
the Ratifications worklist address for the human operator to qualify and ratify
the rule in the specific estate comparison. Pass diff_hash when available so
the worklist opens on that comparison; without it, the returned actionable value
is false and the Qualify and Ratify controls are disabled.
Returns
success: false, an authority-refusal error, ratification_url, and
actionable. The refusal identifies that ratification is a named human’s act.
ratify_delta
This tool does not ratify a declared delta. It returns an authority refusal and
the System diff panel address, where the human operator performs the delta Ratify
action. It returns actionable: true because that panel owns the control and does
not require a comparison-specific deep-link parameter.
Returns
success: false, an authority-refusal error, ratification_url, and
actionable.
See Data Explorer — Migration verification for the operator UI and transition-contract API for REST equivalents.
spec_author_tools
Author a sealed conformance spec incrementally in one thread. Assign this
persistent group to an agent that needs to write structural checks and
derivational obligations against a live, read-only estate without inspecting
the build target. Register each item separately, resolve estate-grounded
ambiguities, then seal the validated artifact to a content-addressed
spec_hash.
See _query_database.
Source-side source_sql and source-relation invariants are resolution-checked when
registered, each in the form its dialect resolves without running the statement:
EXPLAIN where the dialect has that verb, a prepare-only call on SQL Server, and a
zero-row derived-table probe on every other engine, including Palantir Foundry. Foundry
connections are transport-backed rather than DatabaseConnector connections, so the
authoring gate reaches the tenant through the saved palantir_foundry connection and
uses Spark SQL identifier quoting (backticks). A refusal names the resolution form that
was actually sent, so a Foundry failure is not reported as an unsupported EXPLAIN check.
A recompute’s grain_probe runs against the estate at registration time; undeclared
fan-out is rejected with the measured row and key counts, while fanout_declared accepts
the author’s rationale and returns the measurements. Target-side SQL and target-relation
invariants are not executed during authoring because the build target may not exist yet.
When the run places the target on an engine with a supported SQLGlot dialect,
register_obligation parses each non-empty target_sql in that dialect and refuses syntax
or dialect errors with the parser’s message. This checks syntax only: it does not resolve
columns or functions or check types, which remain for the target engine at sealing. The
parse is skipped when the run places no target or the engine has no supported dialect.
When a blind compile has a target snapshot, the server uses its characterized column types
only to decide whether a synthesized numeric domain invariant can resolve. It synthesizes
numeric bounds only for characterized numeric target columns; projection aliases
and non-numeric columns with numeric-looking names are recorded as
unresolvable_domain_invariant notes instead of being emitted as checks against
the base relation. The target characterization remains server-side and is never
included in the author’s brief.
The blind compile scopes a large source catalog before building its authoring
brief. Relations named by the instruction are shown first, followed by
name-adjacent relations, schema siblings, and then the remaining catalog
entries, subject to the render bound.
Existence checks still use the complete bound catalog, not only the relations
shown in the brief. Consequently, declare an already-held relation with the
change kind for an existing relation rather than add_table or
add_derived_mart, and do not declare an already-held column with
add_column. Source-side SQL in obligations must read relations held by the
source catalog (or relations declared as build outputs); a same-named relation
found only in the target catalog does not count as source-held. Unresolved catalog
references and structural/catalog kind conflicts are retried within the
bounded authoring loop. If the retry cannot resolve one, the seal is refused
and the finding is returned in validation_findings.
At finalize_spec, an add_table item is refused with rule
add_table_source_held when the latest source scan resolves its locus by name and
either the object is file-backed or a complete target scan has no object in the
source object’s schema. It is also refused when the latest target scan’s table at the
locus has files matching exactly one file-backed source object. This covers
file-backed datasets even though their SQL read reports no schema. The refusal names
the held object and any add_column items on the same locus; carry the object in
scope instead (same if unchanged, changed if the ticket orders a change), and
remove those structural items. If they came from a prior spec, declare the deletion
with an amendments_json entry before finalizing. See Foundry datasets without a
schema for how the
Prover measures those files.
Relation observation evidence
The seal requires evidence that each relation named on an obligation’s source side was observed during authoring; it does not require one particular bind mechanism. A receipt records the normalizedrelation, observed_via,
transport, connection, observed_at, and receipt_basis. The connection
is the estate the read was taken through, not merely the connection bound to the
thread. The available observed_via
values are bind_probe (the zero-row resolution check), transport_query (the
same check through a registered query transport), catalog_read (the estate
catalog returned that relation’s columns), and sample_read (an executed query
returned rows). The receipts are written to seal.json beside the compiled
artifact, so they document how the estate was observed without changing the
artifact’s spec_hash.
finalize_spec also records observation receipts when its source-engine
preparation accepts a deferred source-side statement; those receipts enter the
evidence ledger on the next round.
Relations declared as outputs by this spec are deferred until post-build
grading. In a repair round, source relations already named by the prior sealed
spec are carried with the prior spec_hash; a newly introduced source relation
still needs a receipt.
A declared output is not taken on the declaration alone. The gate resolves every
registered relation against the measured catalog of the bound estate — the estate’s
own enumeration of the schemas the payload names — never against the text that registered
it. A relation declared created by a structural item or by the scope’s new entry is
deferred until grading and must be absent from that catalog: a new object the estate
already holds is not new. A structural item and scope may both declare the same relation;
the structural item is the receipt’s named declarer. A create that neither declares is a
fabrication, and both kinds of conflict refuse by name. A thread that has registered no scope at all is the partial
exception — a repair round seeded from a prior seal carries structural items and no scope —
and there only the SCOPE question is skipped: the create is reported unmeasured instead of
refused for being unscoped. The catalog question is still asked, because “the estate
already holds this” is an independent conflict that the scope has no bearing on, so a
scopeless create whose relation the measured catalog holds is still refused by name.
The check is per relation, not per statement: a statement that reads a declared output
alongside other relations still has those other names checked against the catalog. Those
are the refusals that offer nearest measured names — a name read beside a deferred one
is a candidate misspelling, so the catalog’s closest spellings help. A create refusal does
not offer them: the remedy there is to scope the object or drop the create-declaration,
not to correct a spelling.
An accepted register_obligation response carries resolution_clean, which is a
measurement, not an assertion. It is true only when every relation the call touched
was seen — planned against the estate, or confirmed new by the scope and absent from the
catalog. It is false when something was not measured, and the response then names what:
resolution_unprobed for statements nothing was sent for (a connection type this process
cannot execute against), and resolution_unmeasured for relations the catalog would not
answer about. resolution_deferred lists the statements held back because they read a
relation this spec creates. On a run that places source and target in separate catalogs of
one connection, a declared invariant_side: "target" is bind-checked only in the target
catalog; successful checks appear in resolution_target_catalog and do not create source
observation receipts. Target-side query evaluation remains deferred to grading.
Before writing the sealed artifact, finalize_spec refuses any finding from
the artifact’s seal gate: invalid artifact shape, a commitment rule activated
by the artifact’s doctrine stamp, or a catalog conflict that the bounded retry
could not resolve. Every multi-member ambiguity_group must carry a committed
lean on one of its members, or a written abstention explaining why the axis
cannot be leaned. Assertions must also stay at the resolution stated by their
own rationale: for example, a rationale that records an exact measurement must
not be sealed as a presence-only check or with a looser tolerance. The
validation_findings in the compile result report the same findings that
caused the seal decision.
Spec-author identity and constitution
Genesis seeds the built-inspec-author system agent as a normal bot that can
open a thread. Its default thread-start loadout includes context_tools,
spec_author_tools, and data_connector_tools; these are defaults rather than
a confinement, because the bot uses tool_access_mode: "all". The agent’s
authoring boundary is enforced inside each tool, not by the advertised tool
list.
The seal provenance records surface: "seat" only when the spec-author identity is the
only contributor to the draft. A direct call to these tools from another agent records
surface: "tool", even if that caller later invokes finalize_spec; direct tool calls
are outside the seat’s constitution. Use author_spec when the ticket must be authored
under the seat’s constitution.
The agent’s identity names the spec-author-constitution skill and the pinned
constitution, which ships as three files — constitution_v9_34.md,
constitution_v9_34_part2.md and constitution_v9_34_part3.md (version v9_34,
sha256:7f0d4d4fe9641de07d05c53f901112486de7ea9288af7323148fb6489a3f6bb6 over the three
concatenated in that order). It is split because the assigned-skill reader serves at most
50,000 characters per file; the three are one document and the pin covers all of them. Read
every file in full before the first estate query or registration call; the reads may run in
parallel. If any reply reports truncated: true, follow that file’s continuation_hint
until it reports truncated: false. Every sealed spec records the constitution version and
hash used to author it.
The open interpretation policy and its spec-author-open bot are retired: lean is the
only policy, and author_spec refuses a run that names open.
Constitution v9.5 makes collection normalization explicit: when a check reduces a
collection to one value, its source and target expressions must define what an empty
collection and a NULL collection become, rather than relying on dialect defaults. If the
ticket is silent, normalize both sides to one representation (commonly
NULLIF(<joined>, '')) and state that choice in the rationale; apply the same rule to
NULL elements inside a collection. A target statement the engine accepts is also run
over at most 1,000 rows of each relation it reads, which catches an error a real row raises
(an array index past the end) only when such a row is in the sample, and says nothing about
which value an empty collection becomes, so it does not settle this empty-versus-NULL
behavior.
Constitution v9.6 treats a declared unknown member as a row of its target: when the mapping
declares an unknown member, a ghost or a placeholder row (a dimension’s -1 surrogate, a
hub’s ghost key), every domain rule over that relation must exclude it — written as a
recompute whose target_sql filters the member out by its key — and the member is
asserted in its own check. An invariant has no row filter, so it is evaluated over the
member too.
Constitution v9.10 also requires checks for period-derived flags such as an effectivity
satellite’s is_active to be evaluated against the rows the clause itself produces. Before
registering the check, work through one ended and one still-open relationship with each row’s
flag, and verify the predicate counts zero contradictions; a target-side sample cannot establish
that the check matches the clause. The v9.10 seal refusals are listed under
finalize_spec. Constitution v9.22 tells the seat that a commissioned run
which places no target is refused at the seal under target_not_placed, which only the
commissioning caller can fix, and that a check the degeneracy probe measures degenerate no
longer decides an item on a carried column. Constitution v9.23 restates that doctrine as one
current text, with every amendment folded into the section it governs; no rule changed.
Constitution v9.24 states that a lift-and-shift (a scope with no changed and no new
entry) always carries one explicit membership obligation, and the seal refuses one without it.
Constitution v9.28 retains floor F1-D for derived builds: when scope contains an input or the
registered mapping declares a derived target, structural items must describe ordered outputs
on the target side, including required column items. The seal also checks that each output’s
linked obligations are explicit and that outputs are scoped new, except an image carried
under its legacy object’s name, which is changed; see finalize_spec
for the refusal conditions and the Registrar guide for the
registration workflow. Constitution v9.27 scopes a carried image that keeps its legacy
object’s name changed and a renamed image new (the source already holds a same-name
image, so new would declare it created and refuse every check reading the legacy object),
and the derived-build seal also refuses a column item the grade attributes no check to.
Constitution v9.28 states how a conditional rule is encoded: “when X, then Y” is a
self_consistency violation count over the target — source_sql SELECT 1 AS grp, 0 AS violations, a target_sql counting the rows where X holds and Y does not, keyed on grp —
expected 0, never a membership between an X-filtered side and an unfiltered or Y-filtered
side. A membership restricted to the same population on both sides stays a membership, and
de-duplication or current-row filters are not conditions. This is the check the
conditional_rule_advisory from register_obligation already names.
Constitution v9.29 adds partial seals. A numbered clause the seat cannot prove yet is
accounted for as open with register_clause_accounting; its accepted reasons, remedy
fields, and reserved mapping values are listed in the tool reference below. The rest of the
spec seals. The open clauses are sealed in the artifact’s
coverage block, inside its hash, and the seat run reads sealed_partial. The seal refuses
an open clause with no reason, remedy and evidence (open_without_remedy), and a ledger that
seals no clause at all (nothing_sealable), which still declines. The seat examines every
mapping entry and clause before it returns, and a finding against the mapping still declines
the run: the mapping_entry_contested reason and the supply_mapping / restate_entry
remedy kinds are reserved, and refused (reserved_open_value). A follow-up is commissioned with repair_of naming the partial seal:
load_prior_spec returns open clauses still stated in the repair document as
open_clause_drafts; clauses moved to another key or absent from that document are reported
separately. The reseal re-runs every gate.
Constitution v9.30 lets the seat decide what a migration already answers. A run stops when
it does not understand the DATA. It never stops merely because a decision hasn’t been
rubber-stamped. Where the target reproduces the source — an object scoped same, or an
output that must match a reference — the preserve-the-source properties (NULL counts, empty
string vs NULL, whole-row multisets on every table in scope, type families, nullability, row
identity, the row count per key, value domains, referential integrity) are migration
defaults: the seat adopts them silently and never asks the owner (v9.31: if the answer would be
the same for every customer, it is not a question). On a same object the system diff checks them from both estates’
characterization, and the seal refuses a check that restates one. On a derived output the seat
registers the check with requirement_source {"kind": "migration_default", "property", "citation": "migration default: target reproduces source — …"}, and a default that reads no
target is refused. A question about what the source holds is answered by measurement, never
asked: the seat reuses existing measurements and, when profiling is needed, runs one profile
query per table rather than one query per question, profiling at most 200 columns. Only an
intended deviation (a rename or drop with no stated reason, a business rule nothing measures)
goes to the owner, as an open clause whose owner remedy carries a recommended_answer (so does
an operator remedy: a person is never handed a bare question, and since v9.31 is asked in the
business terms of their own data, with no Prover vocabulary); the
rest of the spec seals. A clause is not_applicable only with
evidence measured on the source or the ruling_id of a clarification the run was
commissioned with; a ticket calling a clause “out of scope” is not a ruling, and a clause the
seat cannot prove is open.
The Prover Spec Registrar is the first product seat declared by Genesis. Its durable principal is
agent:spec-author, and its escalation mode is configured per deployment rather than per
thread. The default human mode reports an estate question the seat cannot settle and may
hold the compile; set estate_char.spec_author.escalation_mode to "autonomous" for a
deployment with no human court, so the seat forks the reading, annotates the artifact, and
continues. The setting is read at call time and unrecognized values fail closed to "human".
See In-product spec author settings
for the complete configuration entry.
When a spec-author run is submitted through the API, the returned run uses the same
envelope as every other Prover run. By default it is asynchronous; callers may provide
wait_seconds when they prefer a bounded wait, with the ceiling and expiry reported in
the response. See the author-seat API reference
for the request parameter and response behavior.
Every tool in this group — every row of the table below, with no exceptions — refuses the
call when the constitution skill is not active, cannot be read, or resolves to
bytes that do not match the pinned hash. Activate the skill with
manage_context(action="ADD_CONTEXT", active_skills="spec-author-constitution"),
then read the constitution before retrying.
finalize_spec also verifies the constitution that this thread actually received. The
thread must have been served exactly the two pinned files, in the pinned order, with
contiguous pages from each file; Genesis compares each file’s recorded SHA-256 with the
pin before sealing. Missing or extra files, out-of-order reads, interrupted paging, or a
per-file digest mismatch refuse the seal. Read both pinned files again from the first file
in the required order, then retry finalize_spec. A successful seal records the aggregate
constitution pin (constitution: name, version, SHA-256) as its doctrine identity; the
per-file check happens before the seal and is not repeated on it.
The pinned constitution also teaches three seal-gate requirements that affect every
registered check. Quote relation and column identifiers using the case stored in the
bound estate, including identifiers in source_sql, target_sql, grain_probe,
invariants[].column, and envelope_receipt.derivation_sql. Genesis preserves plain
identifiers so the warehouse can apply its normal case folding, and automatically uses
the registered connection’s dialect quoting for names that need it, such as
Fact.Stock Holding or a column named Stock Item Key; the gate reports
r6_quoted_identifier_unresolved or r6_catalog_unmeasured when that evidence is
missing or does not match. Keep the source side blind to the build: source_sql and
source-side invariants must not read a relation the spec asks the builder to create or
a column it asks the builder to add, or the gate reports
r7_source_reads_created_relation or r7_source_reads_added_column. Finally, when
an author chooses a value-obligation tolerance, it must cover the measured
quantisation envelope and include a re-runnable envelope_receipt; the gate refuses
an under-sized or non-executable receipt with p6_envelope_receipt_failed. Tolerances
that come directly from the ticket are not changed by this requirement. R7 binds only
the source side: target_sql and target-side invariants read the target as the subject
of a check, and finalize_spec prepares and samples them on the target.
When a structural item declares expected_type, expected_type_family, or
expected_scale, include type_license as "ticket" or "inferred"; see the
compile API reference
for how the tag affects type-mismatch severity.
expected_type_family accepts numeric, text, date, timestamp, temporal,
boolean, or binary. expected_scale is a non-negative integer for numeric
declarations; omit both fields when the structural item should use existence-only
grading.
Structural loci must use the addressing contract expected by the Prover: whole-object
changes use schema.table, while column-level changes use schema.table.column. Do not
include a catalog or database prefix, leave any component blank, or put a column component
on add_table, add_derived_mart, drop_table, or drop_constraint. When a blind author
compile has a target snapshot, the schema component is also checked against the target’s
namespaces case-insensitively; a locus that still violates the contract after the bounded
retry remains in the run’s validation findings rather than being silently discarded.
During grading, a sealed deliverable may use the graded side’s catalog-qualified spelling
(target_catalog.schema.table or target_catalog.schema.table.column). When
target_catalog is supplied to the grading endpoint and matches that leading catalog,
the Prover strips it for attribution and emits the canonical schema.table[.column] locus.
Catalog-qualified targets for any other catalog remain unmatched; use the catalog that the
graded side actually resolves against.
Compiled-spec verification records the catalogs that each obligation actually read as
source_catalog_effective and target_catalog_effective. A keyed obligation records both
bound catalogs; an invariant records only the side it graded and leaves the other field
null. An ERROR obligation leaves both fields null because no verdict was read. When
source and target use the same connection, selecting invariant_side="target" also
requires target_catalog; without it, the verifier refuses the invariant rather than
silently grading the source catalog.
Invariant verification also reports rows_compared, the population examined by the same
scan as the violation count; see the compiled spec API response for the response contract and its null error behavior.
Relations are named schema.relation; the database or catalog is a property of the
bound connection, not of the item. Three segments are ambiguous, because the per-column
locus schema.relation.column has the same depth as catalog.schema.relation, so a
three-part name is RESOLVED against the bound catalog rather than assumed:
- leading part IS the connection’s database — normalized to two parts, in the locus and in every SQL field, outside string literals and comments; the reply names what it rewrote;
- leading part is a schema of the bound catalog — a column locus, preserved exactly;
- anything else, or a catalog that cannot be read — preserved and UNCHECKED, never refused, because the two shapes cannot be told apart without that fact.
FROM/JOIN target, where three segments are
unambiguous: a read position cannot be schema.relation.column. A build that lands in a
different database can never hold such a name.
Normalization is re-applied at finalize_spec to everything the draft holds, so the rule
does not depend on the order items were registered in or on a connection lookup that failed
earlier.
For register_obligation and register_settlement, an omitted connection_id
uses the connection already bound by an earlier registration in the same thread;
an explicit connection always wins. There is no default estate: a thread that has
bound no connection refuses the call with no connection bound for this thread
rather than choosing one, so the first registration of a run must name it. The
estate checks and grounding query
run as the requesting caller, so that caller must have access to the selected
connection’s credential. register_structural does not bind or change a
thread’s connection. When an estate check cannot reach the selected connection
or resolve its credential for the caller, the tool reports an access problem
rather than treating the SQL as an unresolved relation; re-register with the
connection used by the rest of the run, or ask the stack administrator to grant
the caller access to the connection’s secret, instead of renaming relations or
columns.
Catalog checks use the selected connection’s platform-specific metadata capability,
not a universal information_schema query. If the caller can reach the estate but
cannot read its catalog under the bound role, register_obligation keeps the
obligation and records unmeasurable_under_role with the role or login that could
not enumerate it; it does not narrow the obligation to the objects that happened to
be visible. A catalog read that reaches its row cap is also treated as unknown rather
than as a partial catalog.
The group is prototype-scoped: in-progress drafts are held in memory per
thread and are lost on process restart. Successful finalize_spec calls write
compiled_spec.json and seal.json under
~/proto_agentic/<thread_id>/, then register the sealed artifact with the
source-contract front door. A front-door failure does not remove the disk
seal; the tool reports REGISTRATION_FAILED so it can be registered manually
through the compiled spec API.
Finalized artifacts can be used as relocation-proof evidence; see Relocation proofs
bind once.
For a repair round, call load_prior_spec once before any other registration
tool. It seeds the empty draft with the prior artifact’s structural items and
obligations, preserving their SQL bodies, tolerances, and probes. Settlements
are not seeded because the sealed artifact stores them in notes; the response
returns those notes verbatim and parses their SETTLEMENTS entries into drafts
ready for register_settlement. Re-registering
an item replaces that entry, while untouched items remain in the new seal. The
tool refuses to seed a draft that already contains registered work. The clause ledger is
the exception to whole-artifact seeding: it is matched to the document this round was handed,
by clause wording before key, so renumbered clauses follow their wording and entries for
clauses no longer stated are returned separately.
A repair round needs no file access to the prior artifact. load_prior_spec
returns a manifest of every seeded spec_id and obligation_id with the
relations it names and the named fork axis it belongs to; list_draft returns
that manifest again at any point in the round; and add_lean commits a fork by
attaching a lean to one member addressed by id, without resubmitting the
member’s SQL, tolerance, keys, or rationale.
A seeded repair round is a diff against the prior artifact, not a re-authoring. Every
obligation and structural item must carry forward byte-identically except for edits made by
the finalize-time relation normalizer or an explicit amendment. The default round_kind is
qualify: it may give relation names their schema, but refuses a weakening even when an
amendment supplies a basis. Use round_kind="authoring" only when the spec is deliberately
being re-authored against new information; a weakening or deletion then still requires a
named amendment with a non-empty basis. Deleting an obligation or structural item is named
with field="<deleted>". Unlicensed changes are refused rather than silently resealed.
An amendment can change one field of a carried obligation without re-registering its full
body: give finalize_spec an amendments_json entry with its obligation_id, field,
to, and a non-empty basis. The seal keeps the same id and every other sealed field;
declare the amendment on each finalize call that should apply it. For example,
[{"obligation_id":"obl-1","field":"title","to":"Current customer key","basis":"The owner clarified the check title"}] changes only the title. A reworded title or rationale does not require
round_kind="authoring" because it does not weaken the carried check.
On a Registrar repair round, an owner clarification can also authorize withdrawing one
carried obligation through withdraw_obligation with its clarification id as ruling_id.
That ruling is recorded with the withdrawal and licenses the deletion in the reseal;
other carried obligations remain in place. See withdraw_obligation
for the parameter and restrictions.
Classic repair tooling has no withdraw_obligation verb. Declare the ruled deletion on
finalize_spec instead, using the carried obligation’s id and the commissioned
clarification’s id: [{"obligation_id":"obl-1","field":"<deleted>","ruling_id":"clarification-1","basis":"The owner ruled this check out"}].
The seal removes only that check under the named ruling, whatever the round kind, and
records it in the finalize round’s ruled_withdrawals. The ruling must be one of the
clarifications this run was commissioned with; an uncommissioned id refuses the round
without sealing or removing anything. For other deletion amendments, the seeded-round
diff rules still apply.
When a repair round re-registers a seeded structural item or obligation unchanged, the
registration carries the prior declaration’s conditional fields and is accepted even if a
current conditional rule would reject that already-sealed shape. This applies to the
structural type-declaration fields (expected_type, expected_type_family, and
expected_scale) and to the obligation’s conditional declaration fields (kind, root_axis,
elected_reading, eliminated_reading, elimination_evidence, ambiguity_group,
target_sql, and measured_by); adding, removing, or changing any of those fields makes the
item newly authored and runs the conditional validation again. A new item, or an item whose
identity was not present in the seeded seal, is always validated as new.
After finalization, inspect the terminal author-seat summary for
sealed_obligations and
clause_dispositions. The author-seat status response
defines these fields and the persisted Registrar checkpoint order.
For the live table-accounting check applied to mappings made only of derived targets,
see Declared target mappings and Data Vault shapes.
register_target_model also probes each declared reference whose source and referenced
columns are readable: one query scans the referencing object and checks each non-NULL
value against the declared referenced column. A reference with values but no matches is
returned as a finding; a reference column with no non-NULL values is not. Probe failures
join the other failed source probes. This adds one query per measurable declared reference,
with a correlated lookup of the referenced object per source row.
For how declared satellite history affects rendered link-membership checks and which history
columns must be present, see Declared target mappings and Data Vault shapes.
register_target_model looks up the run’s source and target engines before rendering; this
adds one indexed run lookup and, when target_connection_id is set, one connection-record
read. A mapping that needs engine-specific identifier quoting is rendered for that pair
only when the run places its target. Without a placed target, rename the identifier to a
plain name or place the target; a grade on a different engine pair refuses the rendering.
See engine-pair renderings.
withdraw_scope
Withdraw entries that are wrong in kind, such as a legacy object scoped same before the
seat knew its declared target model splits it into images. This removes the object from the
spec’s scope; it does not register replacement entries. Register each image separately with
register_scope. To correct an expectation rather than remove an entry, call register_scope
again for that object.
For example, pass
objects_json='["PUBLIC.ORDERS"]' to withdraw one entry. The call is
all-or-nothing: if any named object has no entry, nothing is withdrawn and the response names
the missing objects. On success, the response includes withdrawn and the remaining
scope_count. This is in-memory only; it performs no estate query, connection read, or model
call.
load_prior_spec
Use this tool at the start of a repair round to load the prior sealed artifact.
Address it by its spec_hash — the only address form, and the way every other
verb in this surface names a spec. A prior this deployment’s store does not hold
is refused with the remedy that finishes: register the sealed artifact through
POST /api/estate/spec-conformance/compiled, then repair by the hash that
returns. It accepts only an empty draft, so call it before register_structural,
register_obligation, or register_settlement.
A run commissioned with repair_of seeds only from that seal, and any other hash is
refused. If the run-store lookup fails, the seed is refused whatever the run’s tooling,
because which seal it may repair cannot be checked. Retry once the run store is readable;
if it stays unreadable, report the failure to the commissioning caller and stop. The store
error is logged but is not included in the reply. A readable store with no seat-run row for
the thread does not block seeding. When the seat run exists, its commissioned connection
is bound to an unbound draft as part of the same seed write, even if the repair only amends
or withdraws carried checks and registers no new check. An already-bound draft keeps its
connection. This keeps finalization on the connection the repair run was commissioned to
use. When there is no seat run, the prior’s recorded connection is inherited instead; if the
prior also has no connection, seeding follows its parent seals to the nearest recorded one.
The inherited catalog placement is carried into the reseal when it is bound to that same
connection. A read failure while resolving this lineage leaves the draft unbound.
When the active run was commissioned with
repair_of, this tool accepts only that
spec_hash. Naming a different prior is refused before its artifact is read, and the
response directs the seat to the commissioned hash. Enforcing this binding adds one
indexed run lookup.
On success, the response reports the seeded structural_items and
obligations counts and settlements_seeded: 0, plus everything the round needs
about the prior artifact without opening its file:
Before reading the prior grade or sealing the artifact, the tool checks whether the
thread’s draft is still empty. If it already contains registered work, the seed is
refused without those reads and the draft is unchanged. This is an advisory pre-check;
the seed repeats the binding check under its write lock, so work registered concurrently
can still make the seed refuse. When seeding succeeds, the prior-grade block is read once
and stored with the round; later reads of the draft use that fixed block rather than
re-reading the newest grade.
prior_notes— the prior artifact’snotes, verbatim.settlement_drafts— itsSETTLEMENTSentries, each already in the shaperegister_settlementaccepts. The notes grammar is written and parsed by one codec in the artifact-format layer, so whatfinalize_specseals is what a later repair round reads back. A line that does not carry the four labelled parts is returned verbatim undersettlements_unparsedrather than dropped.settlements_note— present only when no draft could be built, stating that no settlements were recorded. No empty list is returned in its place.manifest— every seededspec_idandobligation_idwith its locus, the relations it reads, its fork axis, and whether that axis is committed.prior_grade_run_id— the succeeded grade run that supplied the prior’s latest grade reading, ornullwhen no grade of this spec was found in the recent window.prior_grade_unverified— the obligations that grade could not decide, each with itsobligation_id,status,error, andcause. An empty list means the grade read successfully and found nothing undecided; the field is omitted when the grade was found but its verdict coverage could not be read.prior_grade_unverified_note— explains whether the latest grade found no undecided obligations, recorded obligations it could not decide, or supplied no readable coverage. This reading is taken once while the round is seeded and does not change if a newer grade arrives mid-round; start a new repair round to read it.clause_accounting_not_carried— present when an entry could not be assigned a current document key: its old key is absent and its recorded wording could not be matched uniquely to an unused new key, or another carried entry already owns that key. Each entry retains the oldclausekey and clause text; an open entry includes its reason, remedy, and evidence. If the document still states that clause under a new key, register it under that key; a removed clause needs no re-accounting.clause_accounting_not_carried_noteexplains the case, including when the current document numbers no clauses.clause_accounting_rekeyed— present when carried entries match clause wording under a different key in the current document; each item hasfromandto. These entries are already seeded under the new key.clause_accounting_reworded— present when a carried entry’s recorded words differ from the document’s clause under the same key. Each item includesnow_reads, the wording in the current document; check whether the entry still accounts for it and re-register it when needed.clause_accounting_ungrounded— present when a handed document includes a priorNOT APPLICABLEclause whose sealed note has neither a measurement that reads a name in the current clause nor an owner ruling still in force. These clauses are not in the draft. Re-account for each asnot_applicablewith evidence or a commissionedruling_id, or asopenwith its reason, remedy, and evidence; the seal refuses any left unaccounted.clause_accounting_ungrounded_noteexplains this requirement.
seat_settings_inherited is present when the repair inherits an unset authoring setting;
it maps each adopted key to its value, from_spec_hash, and default_was value. When
repair_of names the prior and authoring_tooling was unset, submit inherits that seal’s
tooling, so the run handle names the effective tooling from the start. The load also
reports that inherited setting. It inherits each source_catalog or target_catalog a
repair was commissioned without when the prior is loaded: each comes from the placement
the prior spec was sealed with, the source catalog only when the repair authors against
the prior’s connection and the target catalog only when its target is on the prior’s
target connection (default_was is empty for a catalog). A setting or catalog the caller
named is never changed.
seat_settings_note accompanies it with an explanation of the inheritance; if the tooling
becomes classic, the note says Registrar verbs are withdrawn and to use the classic verbs.
If the artifact cannot be
read, does not satisfy the sealed artifact contract, or the draft already has
registered work, the tool returns a rejection and leaves the draft unchanged.
register_substrate
Record the customer’s stated requirements for how the change must be built. The
section is optional: use it only when the ticket names a build mechanism, where the
transformations live, a re-run rule, or another constraint on how the copy is done. Do
not infer a mechanism from the estate or recommend one. The substrate states no
obligation and nothing in it is graded; it is sealed with the spec so a later building
agent can retrieve and certify against the customer’s words.
The tool normalizes whitespace, accepts at most
25 clauses, and limits each clause to
2048 characters. Empty clauses are rejected. Calling it again replaces the prior
clauses for that thread rather than adding a second contradictory section. The operation
is in-memory only; the clauses reach the sealed artifact when finalize_spec runs.
After sealing, read the section with GET /api/estate/spec-conformance/compiled/{spec_hash}/substrate.
That response distinguishes declared: false (the ticket stated no substrate) from an
empty clause list. After the build, the spec-conformance API reference
documents the separate statement surface: a declared substrate produces an anchored
self_certification, while declared: false records the builder’s own substrate choices
or departures as substrate_declaration with anchored: false. Neither record is a Prover
verdict.
list_draft
Lists what the active thread’s draft holds — counts, the bound connection_id,
and the same manifest load_prior_spec returns. Use it mid-round to recover the
ids to address. It returns no SQL bodies: repair an item by re-registering its
id, commit a fork member with add_lean, and every untouched item is carried
into the new seal unchanged. A thread holding no draft receives zero counts and
an empty manifest, not a rejection.
By default it returns every section. Pass sections to request only the sections
you need — for example, sections: ["counts"] requests just the counts (a
no-draft response also includes its explanatory note). The
available sections are counts, connection_id, structural_items, obligations,
fork_axes, settlements, prior_grade, and reseal_preview. An empty list or
any unknown section is refused. structural_ids filters the structural_items
manifest list by spec_id; obligation_ids filters the obligations list by
obligation_id. Counts always describe the whole draft, and each returned fork
axis always includes all its members.
On a round seeded by load_prior_spec it also carries reseal_preview, the
repair dry run: obligation and structural counts before and after, the prior
ids this draft no longer holds and the ones it added, per-kind counts on both
sides, and shrank. A round that dropped obligations while editing something
else sees it here, before anything is sealed.
The draft’s connection binding is also included in connection_id. If load_prior_spec
bound an unbound draft to the commissioned seat run’s connection, this is the connection
used when the repair finalizes, including a round that only amends or withdraws carried
checks.
edited_obligations is the other half: every obligation the round CARRIES
FORWARD with a changed field, each field with its before and its after, read
off the same walk the seal gate refuses on. Where the edited field is a
source_sql body, the entry also carries movement — the prior body and this
one, each run once against the bound estate, joined on the obligation’s keys,
and compared using the grade’s declared-column rules.
columns_missing lists declared compared columns neither body projects. It reports
rows_changed, max_delta with
its column and key, keys_dropped / keys_added, columns_compared /
column_tolerances, the rows whose movement one form’s tolerances admit and the
other’s do not (rows_closer / rows_farther, with a verdict_basis saying
these are the two SOURCE forms and not the source-vs-target verdict). An edit whose
movement was not measured says why instead of
reporting zeroes — a tolerance edit on an unchanged body moves no row on the
source side, because the seat never executes target_sql.
preview_licensed_edits: true says the edits are reported; whether one was
LICENSED is still decided at finalize_spec, against the name pass’s own
receipts. A freshly authored draft carries no reseal_preview — there is no
prior, so there is no denominator.
On a repair round, list_draft also returns the prior_grade_run_id,
prior_grade_unverified, and prior_grade_unverified_note from the grade reading held
when load_prior_spec seeded the draft. It does not perform a second grade lookup, so
the repair inputs remain fixed for the life of the draft; start a new round to pick up a
newer grade.
Cost. A call that leaves reseal_preview out reads one copy of the in-memory
draft only — no estate query, file access, or grade lookup. Including
reseal_preview assembles the artifact that finalize_spec would seal. On a
repair round that edited a source_sql body, it also pays one connection-record
read and then two statements per edited obligation (one where both forms share a
body), capped at 10 statements and 2,000 rows each per call; edits past the cap
are reported with their movement unmeasured.
register_structural
For how an object-level
add_table item is decided when its legacy object is split, see
the Prover grade overview.
For a drop_constraint item, put the key being removed in description or
expected_effect: the grader confirms only a named key kind (PRIMARY KEY/PK or
UNIQUE) and, when supplied, its column list. Use UNIQUE with a key indicator such as
UNIQUE (email); the ordinary word “unique” does not name a key. The wording must name
only one key kind and at most one column list. If it names no key or is ambiguous, the
item remains indeterminate; if a different key was removed, it is not implemented. See
the Prover grade overview
for when a confirmed key removal meets a changed scope entry.
Once the scope is registered and makes the spec a derived build, register_structural and
register_structurals refuse an item whose inputs name neither a scope entry nor an output
of the spec, with the finding finalization would give, and write nothing for that item.
Register the input as an input scope entry first. An item registered before its scope is
still judged at finalization.
register_obligation
For the allowed
kind values and the grading behavior for an unknown non-null value, see
how agents drive the Prover.
In a derived build, a membership or recompute check that reads an output which must equal
its reference, and that reference, is answered with value_coverage while the output still has
columns no check compares with the reference: columns_counted, why when the check counts
none (for example, its target_sql cannot be read in the target engine’s dialect, or its keys
are not columns it reads), and every uncompared_columns entry. register_obligations lists
each such note under its item.
For a recompute with a constant expected side, or an invariant on a referenced output,
registration also runs the check’s rule against the reference original. If the original
already violates that rule, registration refuses the check: a faithful build would fail
it too. A check is exempt only when the ticket orders the output to differ from its
reference; set reference_contradiction_declared: true and provide
reference_contradiction_rationale quoting (in double quotes) a sentence from the ticket
that states the rule. A quote not found in the ticket is refused before the estate is read.
When the reference cannot be checked, the accepted response gives the reason in
reference_probe_unmeasured; that does not refuse the obligation. This probe is read-only
and checks no more than 50 rows; a result over that limit is reported as unmeasured, not
compared partially.
register_obligation rejects an obligation when any executed SQL field
(source_sql, target_sql, or grain_probe) hard-casts a column from a raw or
staging relation. This includes qualified relations with a segment beginning
with raw_ or stg_, or a segment named raw or staging, whether the
relation is referenced directly or through an alias. Use a tolerant parse such
as TRY_CAST or a TO_* function with a safe fallback instead; tolerant
parsing yields NULL rather than failing the statement on the first
unparseable value.
Registration also refuses an executed SQL field whose NOT IN subquery can
yield NULL: SQL then never evaluates the predicate as TRUE, so an
unmatched-row check can count nothing and pass vacuously, while a grain_probe
measures nothing. This check covers source_sql and grain_probe in the
source connection’s dialect, and target_sql in the placed target engine’s
dialect; when no target dialect is available, it checks target_sql as ANSI
SQL instead. Rewrite the predicate as correlated NOT EXISTS or a LEFT ANTI JOIN, or filter every selected subquery column with IS NOT NULL (qualified
with the subquery’s alias when it joins multiple tables). A repair that
re-registers a field unchanged from its seal is not checked again for this
rule; edited fields are checked normally.
Before resolution checks and probes, register_obligation refuses a comparison
with check_measures_nothing when neither source_sql nor target_sql measures
a relation. It also refuses when owning_relation, or the loci linked by
spec_item_ids, name the asserted object, a non-measuring statement reads it,
and every measuring statement reads only other relations. A FROM, CTE, or
derived table that supplies only fixed rows does not make a typed value a
measurement. Keep a literal on at most one side and make the other query the
object; in a migration, it can query the same-named source counterpart. The seal
repeats this check for carried obligations too. A statement the SQL reader
cannot parse is not judged. Re-register the obligation under the same
obligation_id with the fix named by the finding, then finalize again.
A source-anchored statement that reads a relation the draft’s own structural
items declare created — an add_table or add_derived_mart locus — cannot be
PLANNED, because the relation does not exist until the build runs. It is not
taken on the declaration alone: the relation must also be scoped new, and must
be absent from the estate’s measured catalog. Only then is the statement
deferred, and the response carries resolution_deferred, one entry per
(statement, relation) pair — a statement reading two created relations yields two
entries — naming the relation, the declaring spec_id, and which of the two
checks actually ran for it.
The deferral is per relation, not per statement: every OTHER relation the
statement reads is checked against the measured catalog, because no probe will
see them. A create the scope does not hold as new, and a new object the
estate already holds, are both refused by name.
On a run whose target is on another connection or in another catalog,
finalize_spec prepares each deferred source_sql and the violation count for
each invariant still graded on the source against the source engine, using the
same no-read resolution form. If the source engine reports that a declared
build-output relation is missing, sealing is refused with
source_reads_target_only_relation; the finding names the obligation, relation,
and engine error. For an invariant, it also says to declare
invariant_side: "target" so the check asserts about the build. This check is
skipped when the build is in the source’s own connection and catalog. It adds
one live source-engine round trip per deferred source-side statement on a
separate-target run. For a check between two derived tables, put the comparison
on the target side only; when reconciling against the source, read the source
relations the derived table is built from.
For an invariant whose invariant_side is omitted, registration records
invariant_side: "target" when the declared target model builds the relation, the
resolution check deferred it as a created relation, and the source catalog was
measured without that relation. The response includes invariant_side_inferred
with side: "target" and the basis for the inference, so the invariant is graded
on the build rather than against the legacy source. This inference is not made
when the source catalog could not be measured or the relation was not probed.
When the target model builds the relation but the source also holds a relation of
that name, registration refuses the unsided invariant because either estate could
be intended; resubmit with invariant_side: "target" or invariant_side: "source".
On successful registration of a newly authored membership obligation with no root_axis,
the tool sets root_axis: "population" and returns root_axis_defaulted: "population". An
explicitly declared valid axis is retained, and seeded declarations carried unchanged into a
repair are not defaulted again.
This covers a check over an upstream model of the same build. An obligation whose
source side reads the relation its own target side reads is also refused, but the
finding distinguishes two cases. If the spec declares that relation created and the
bound estate does not hold it, the source reads the post-build world; read the source
inputs (or the original named by the item’s reference) instead. If the bound estate
already holds the relation, it is not a created output: remove the create-declaration
and re-scope it changed or same. These are declaration/scope faults, not spelling
faults; the response gives the corresponding remedy, including when both kinds of
fault occur in one registration. For self_consistency, the declared relation is
its target relation for this check, even when target_sql does not read it. A read of
an absent relation the spec does not declare is still rejected with the estate’s own
error.
If the connection drops before an obligation’s SQL or grain probe is evaluated,
the response is retryable rather than a modelling rejection: it includes
retryable: true, rejected: false, and a hint to call again with the same
payload. The same transport classification applies when register_settlement
executes grounded_by_sql; a dropped connection is not evidence that the SQL or
the settlement is wrong.
When the registered query transport cannot be opened, register_obligation does
not reject the obligation only for that reason. It records the statement in
resolution_unprobed, accepts the obligation without claiming that the statement
was checked, and reports any source relations without a receipt in
relations_unobserved. Before finalization, read those relations with an
available tool: re-register the obligation when its resolution or grain probe
can run, use register_settlement for an executed grounding query, or let the
finalize-time catalog read observe a relation’s returned columns. A successful
empty result is not a sample_read receipt.
register_time_value_binding
Register the source binding for each declared TIME column ratified for STRING
HH:mm:ss storage, and for each such encoding carried into a repair round. The target
relation and column must match this run’s declared target types or a carried encoding.
The seal builds and owns the keyed check from this binding; do not register a TV- check
yourself. A repeated call for the same column replaces its earlier binding.
For example, bind
PUBLIC.EVENTS.START_TIME to six-digit text in
PUBLIC.RAW_EVENTS.START_TIME on EVENT_ID with source_form="hhmmss_text" and
key_columns='["EVENT_ID"]'. The source value is compared with the stored target text,
along with a hidden validity marker; malformed values, values in another form, mismatches,
one-sided NULLs and fractional seconds fail grading. For hhmmss_text, 000000 is
marked unruled_initial and fails: it can mean midnight or no time recorded, and passing
it requires a person’s ruling. A carried binding without a declared source form must be
registered again; no form is assumed. finalize_spec refuses a missing binding
(target_time_value_check_missing) or a held check that is not the current rendering
(target_time_value_check_stale), and retires checks for encodings no longer ratified.
Unsupported engines or zoned TIME columns are refused by name. If an engine cannot render
a check, finalization sends the refusal to the commissioning caller even when that check
is already held; it does not ask the author to register a binding the seal cannot use.
SQLite source checks validate six-digit hhmmss_text in UTF-16 databases as well as other
SQLite encodings. Source checks support BigQuery, Databricks, PostgreSQL and SQLite; target
checks support Databricks and SQLite. SQLite checks reject time text with NUL-hidden trailing
bytes; see the Prover’s SQLite time-text rule.
Cost: one run-row read, two connection-record reads and the source resolution check;
each registered check adds one keyed comparison per grade, reading the bound source
columns and target columns.
register_settlement
register_settlement returns the measured grounded_result, axis,
settlement_id, and settlement_count. When a settlement replaces an earlier
one on the same axis, it also returns replaced_previous: true and
previous_settlement_id; use the same axis to correct a settlement instead of
registering a rival entry.
declare_migration_shape
Use this deterministic repair when a grade reports structural items as
indeterminate because their migration shape is undeclared. The REST contract and
refusal conditions are documented in Declare migration shape.
The response contains the new
spec_hash, its parent, and a declared receipt
with the value written, item count, and item overrides. Grade with the returned hash.
add_lean
Commits an ambiguity fork by attaching a lean to one member already in the
draft, addressed by obligation_id. It writes only that field, so no SQL,
tolerance, key, rationale, or reading can change through this path — which is
what lets a repair round commit a fork whose member bodies it has never read. It
runs no estate query, because nothing new is submitted. Use it instead of
register_obligation whenever the lean is the only thing being added.
Fork membership is read through the seal gate’s own grouping, so this tool cannot
accept a lean on an obligation R1 does not regard as a fork member.
For grade-result interpretation, see what a run reports back.
finalize_spec
Before sealing, the draft must carry a row-set claim. A lift-and-shift, whose
scope asserts no
changed or new object, must include at least one obligation
with kind set to membership; its keyed same scope entries do not replace
it. Any other draft must include such an obligation or a same scope entry
carrying row_identity. This row-set claim must state which source rows must appear in
the target by providing keys, source_sql, and target_sql; without it,
finalize_spec rejects the draft because the spec cannot detect rows dropped
from or invented in the target.
For an estate that is not multi-member, when complete latest source and target
scans are available, finalize_spec also refuses a carried same or changed
scope entry if neither snapshot can resolve its object name. Nothing is sealed:
use the name held by the scans (for a Foundry dataset, its RID or scanned name;
for a table, its schema-qualified name), then finalize again. This catches a scope
the proof could only grade as unmet; see [scope verdicts]
(/docs/Genesis-Prover/Agents-And-The-API#scope-verdicts) for the grading behavior.
A locus or relation written <database>.<relation> is also refused, naming
the schemas of the bound connection to write instead. A spec is graded against a
build that does not land in the database it was authored against, so a
database-qualified name can never resolve there. The three-part form is
normalized rather than refused; a head that is neither the bound database nor a
known schema, and an unknown schema list, both pass.
On a round seeded by load_prior_spec, the seal reports coverage: obligation
and structural counts before and after, the ids dropped and added, per-kind
counts, and shrank. counts alone is unreadable on a repair, because “25
obligations” is a whole spec or an amputation depending on what the prior held.
The registration declares that prior as parent_spec_hash, which puts it under
the compiled-spec front door’s own coverage gate — and the block reported here is
the one that gate measured, carried through with its coverage_basis, not a
second measurement taken by the seat. Where the store reports no measurement, so
does the seal.
A refusal from that gate fails the round. If the store judges the registration
and says no — a shrink with no stated basis, a declared parent it does not hold, a
declared parent that contradicts the stored lineage — finalize_spec records the
round failed with the store’s own basis and publishes nothing, so the staged files
never become the sealed spec. An infrastructure failure is the opposite case and is
non-fatal: the artifact is good, the store is merely behind, and the response says
REGISTRATION_FAILED with the manual registration path.
After the artifact contract passes, finalize_spec also runs the seal gate’s
lint rules and refuses to seal when they report a refusal. For an uncommitted
fork, either commit the member you choose with add_lean, or record the
abstention and why the axis cannot be leaned; then finalize again.
For comparison obligations (membership, recompute, and self_consistency),
the dated R9 rule refuses a seal when source_sql has a top-level LIMIT n and
target_sql establishes more than n rows through top-level UNION ALL
branches, each an unconditional aggregate. In that case, the expectation cannot
state a value for every target key; add an expected row for each key or narrow the
target query to the keys the expectation covers. The rule does not infer a target
row count when those branch conditions are not established. Artifacts not stamped
2026-10-13.an-expectation-covers-every-key-it-grades or later receive a review
finding rather than a refusal.
Before sealing, Genesis reads and verifies the pinned spec-author constitution
from the assigned skill package; if it cannot load or verify that digest, no
artifact is written or registered.
For a fresh Registrar authoring round, constitution v9.27’s F1-D seal gate applies
when the scope contains any input entry or the registered target mapping declares a
derived target. It refuses a derived build whose structural tier is empty, an item whose
locus is a scoped input or is not read by its linked checks on target_sql (unless
the mapping declares that derived target), and an ordered output without a column
item. It also requires column items for output columns the checks key or compare on a
single target relation, target-side invariant columns, and columns declared by the
derived mapping. Link each obligation to the structural items it proves with
spec_item_ids; if an obligation links none, the gate evaluates each item against
all obligations. same scope entries cannot name an output; a changed output must
be read by a check on the source side or it is refused as absent from source. Scope
an output new, except an image carried under its legacy object’s name, which is
changed; put source lineage in each item’s inputs, and name an original to
reproduce in the object’s reference. A copy (no input and no derived target)
does not acquire this structural-item requirement. Repair rounds are not re-judged
by F1-D. These findings are returned with the other seal findings; nothing is sealed
until corrected.
When a commissioned draft declares target_model, finalization refuses with
carried_column_added if a structural add_column item names a column the model
carries from a source into an image with a different name. add_column is decided
against the same-named source object, which does not exist for that image, so the
grade can never decide the item. Drop it; if the ticket requires a property of the
column, register an invariant or recompute obligation that reads it on the
image. On a prior-seeded round, declare the deletion in amendments_json with
obligation_id equal to the item’s spec_id, field: "<deleted>", from, to,
and a basis naming this finding, and use round_kind: "authoring". Nothing is
sealed on refusal.
On a fresh Registrar round, constitution v9.34 also refuses with
target_design_column_undeclared when a registered target mapping lists an image
column in metadata_columns but no column structural item declares it. The check
does not apply to repair rounds or images assigned a vault role. A column item
declares the image column by its locus, a rename’s new_locus, or a
propagates_to entry; a removal item does not declare it. Register an add_column
item with source-column inputs (or inputs: [] when the design gives it no source
input), the design’s expected_type and expected_type_family, and a linked check
where one can be written. Use a recompute check for a computed column and a
population check for a column with no source input. Nothing is sealed until every
reported column is declared.
Finalization refuses with carried_column_item when any other column item on such a
carried column cannot be decided: a transform_values, modify_etl_derivation or
type_change item, or an item declared must_match, that no obligation reads at the image
(the grade compares a column item with the same-named source object, which does not exist,
so only the item’s own checks can decide it), and any drop_column or rename_column not
declared must_match, which contradicts the carry. An item whose checks include one the
degeneracy probe measures degenerate on the source (empty, all-NULL, all-zero) is refused
too, naming the check and the probe’s rule: the grade voids such a check, so it decides
nothing. The seal runs that probe, one read-only source query per such check, only over the
checks that alone keep a carried item sealable. State the claim as an obligation that
reads the column on the image, or drop the item, with the same deletion amendment on a
prior-seeded round.
Finalization refuses with invariant_grades_nothing when an invariant obligation declares
no constraint the grade counts: every rule is finite only (recorded, never counted) or
names no column. The grade builds no violation query for it, so it would error on every
proof. Record a limitation in the spec’s notes or history_not_testable instead, or give
the invariant a counted constraint (not_null, min, max, allowed_values).
For allowed_values, a text value is compared as text even against a numeric member: text
"01" does not match numeric 1.
Finalization refuses with written_by_without_write_history when a written_by obligation’s
target engine has no per-relation write-history query (writer_history_sql is None). Such
an obligation would error on every build, including a correct one; a Flow-run record cannot
replace write history the engine does not expose. Drop the obligation, or, if this round was
seeded from a prior spec, declare its deletion in amendments_json with round_kind: "authoring". If the producer requirement still matters, record that this target cannot
evidence it in the spec’s notes instead of making it an executable check. Nothing is sealed
on refusal.
On a commissioned run with target_model, finalization also refuses an input scope that
the mapping does not declare as read. The mapping must list the object in a split with
images: [], as a source of a derived target, or as a relation declared in an image’s
history; an object carried into an image is not an input under this check. An input that
exists only in the target catalog is treated as a target-side relation read by the build
and does not need a source-to-target mapping entry. The refusal uses undeclared_input,
reports the objects that do not agree, and leaves the draft unsealed for the proposer to amend.
Finalization also refuses with same_over_split when scope expects same for a source
object that target_model splits into one or more images. Drop that object’s same entry
and register each declared image, citing its mapping row: an image under a new name with
expectation new, and an image that keeps the source object’s name with expectation
changed; then finalize again. The seal is not written on refusal. Once
register_target_model has registered the mapping, register_scope refuses such a same
entry at the call under the same rule and writes nothing from that batch, including when an
image keeps the source object’s name. This catches the mismatch on the first scope
registration rather than waiting for finalization.
Finalization also refuses with new_over_carried_image when scope expects new for an
image target_model carries a source object into under that object’s own name. The source
already holds that name, so the build does not create it, and every check reading the source
object on its source side would be refused as reading the build. Scope it changed: on a
split the grade reads changed as it reads new, every image on the target. Once the
mapping is registered, register_scope refuses such an entry at the call under the same
rule.
For a fresh Registrar round’s derived build, finalization also refuses under
derived_build_items a column item the grade attributes no check to (a removal excepted,
which the diff confirms; a column the value floor names is refused under
declared_rules_unchecked instead): a check whose
spec_item_ids name only an object item reaches none of that object’s column items, and an
item with no check reads unverified on a correct build. Each finding names the check that
reads the column and the item ids to add to its spec_item_ids, or the item no check reads.
register_structurals and register_obligations return the same list as
unchecked_column_items while any remains.
For column items outside the value floor, this gate also requires an attributed check: a
check with spec_item_ids naming only an object item does not reach that object’s column
items. When a check reads a column but omits its item id, the finding names the check and
asks to add the item ids; when no check reads the column, it asks for a check linked to the
item. Removal items are confirmed by the diff, and items already covered by the value-floor
rule are handled under declared_rules_unchecked instead.
Finalization also refuses with excluded_but_delivered when scope expects excluded for
an object target_model delivers: a source object it splits into one or more images, or an
object it declares on the target (an image, a vault entity, a derived target). The grade
reads either entry as unmet on a correct build. Drop the entry and scope each image: new
for an image under a new name, changed for one that keeps the source object’s name;
unnamed target objects are reported as scope_unclaimed when the scope does not claim the
whole target, or as blocking surplus when it does.
excluded remains valid for an object the mapping loads nowhere.
On a commissioned run with target_model, finalization also refuses with unrendered_link
when a declared link renders no membership check. The finding names each link and source and,
when a participant is unreachable, the missing reference to declare. Fix the proposer-owned
mapping and retry; do not register a hand-written check in place of the model’s missing check.
For reference spelling, including schema-qualified split names, see Declared target mappings
and Data Vault shapes.
Finalization refuses with unforked_link_population when a hand-written membership check
compares a historized link’s population as one reading without a fork for that same link.
The source rows and declared history can represent both the current pair per key and every
pair any version related. Put the check in an ambiguity_group with at least one other
membership check reading that link, and give each obligation its reading, or drop the
hand-written check; the model’s generated check reads the accumulated population. Then
finalize again. Nothing is sealed on refusal.
When no target_model was proposed, finalization also refuses a spec that scopes tables as
input while describing a same or changed table that the source catalog does not hold,
when the obligations read that table. This indicates a target built from other tables rather
than a one-to-one source copy. The refusal uses unmapped_reshape, names the affected tables,
returns RESULT with spec_hash=NONE and an open question asking the proposer for the
source-to-target mapping, and seals nothing. The seat does not author the mapping; after the
proposer supplies it, retry with target_model.
Finalization also refuses when an obligation’s source side names a relation with
neither an observation receipt nor one of the documented deferred or carried
bases. On success, the response and seal.json include relations_observed,
with one entry per relation and its observation basis. This evidence is stored
beside, not inside, the compiled artifact, so it does not change spec_hash.
The response and seal.json also include clause_gate, which reports
clauses_counted, numbered_items, and table_rows. When the commissioned document
has no numbered item or table row, the block includes a note stating whether the run
had no document or the document had nothing to count; the absence of a clause is not
reported as silent coverage.
The seal also compares each receipt’s connection with the source estate named by
the run. If any source relation was observed through another connection, finalization
refuses with re_anchored: a landed copy is a different estate, even when its current
contents match. The refusal names the declared and observed connections, the affected
relations, and the observing tool. To accept a substitute deliberately, the operator
must submit source_estate_basis on the author-seat run with both connection_id and
reason; when every foreign receipt matches that declared substitute, the seal proceeds
and records re_anchored_from with declared, observed, and basis. Seals that do not
use a substitute carry declared_source_estate, re_anchored_from: null, and one of
observed_on_declared_estate, declared_source_estate_unrecorded, or
no_receipt_to_compare as re_anchored_basis.
The seal also reports an unlicensed_lineage review finding when a structural
description/expected_effect/rationale or obligation title/rationale says that a source
NULL or missing value makes the target value legitimate, acceptable, expected,
or otherwise permitted. A source NULL explains a finding; it never licenses
skipping a required invariant. This is a review finding on an otherwise sealable
artifact, not a substitute for adding the required check.
finalize_spec applies the relation-name rules to everything the draft holds,
seeded and newly registered alike, before it assembles the artifact. It refuses
when the thread’s bound connection changes while it is reading the estate: one
seal describes one estate, and its names, its bind catalog and its provenance all
come from the connection the draft was bound to when the finalize began.
A locus on an add_table or add_derived_mart item that carries no schema is
qualified with the connection’s default schema, receipted on the response as
requalified_loci. Loci on other change kinds are left alone: for those, one
segment is a column, not an unqualified relation.
A read that names a relation the spec’s own structural items declare created but
carries no schema is then qualified from the declaring item’s locus, receipted as
requalified_reads. When the declaring item names no schema and the connection
supplies no default, names a schema the bound catalog does not hold, or two
declared relations share the name, the read is refused by name instead of
guessed. A read of a relation the spec does not create is left alone — it names
the frozen source estate, where the connection’s own default schema resolves it.
An invariant obligation’s bare relation field is qualified by the same pass. A relation
declared by this spec resolves to that declaration’s locus; otherwise a bare name resolves
against the connection’s default schema when that schema is known. Already-qualified names
are unchanged. If more than one declared locus matches, the pass refuses rather than guesses.
The rewrite appears in the finalize response’s relation receipts and is included in the
seeded-round diff as a licensed normalization; it does not authorize any other obligation
change.
Both receipt lists ride every finalize response — the seal and every later
rejection alike — and are recorded on the run row’s finalize round. A rejection
is not a rollback: the rewrites stand, and the next round starts on the rewritten
draft. Neither list is written as an empty list: absent means the rule found
nothing to rewrite on a round that reached it.
If the connection’s schema list cannot be read, the created-relation rules cannot
decide anything, and finalize_spec refuses any draft that holds a name they
would have had to decide: a relation-creating locus written with no schema, or a
read with no schema of a relation the spec declares created. The refusal reports
catalog schemas unavailable for <connection> and names each such item, and
seals nothing. A draft holding no such name is unaffected and seals normally, so
a transient metadata failure does not block a spec the rules had nothing to say
about. The test is of the draft’s contents, not of how it was filled — an
authored locus registered before the run bound a connection has not been through
the registration-time locus rule either.
Example sequence:
load_prior_spec and start with the registration tools.
finalize_spec records each attempt on the thread’s run history. A rejected
attempt is recorded with its findings, while an interrupted seal is recorded as
pending or failed; retrying finalize_spec for the same artifact completes
that attempt instead of creating a second one. A successful response includes
sealed: true, the spec_hash, artifact counts, and the published artifact
path. If the final history write fails after the seal and front-door
registration succeed, the response still reports the completed seal and tells
you to rerun finalize_spec to complete only the history transition.
A successful response can also include review_findings. These are advisories:
they do not prevent the seal, and apply under either interpretation policy.
contradictory_live_clarifications names live
estate rulings that disagree. Only structured TIME-encoding statements can
disagree: they are compared by relation and column, and the finding names
every live ruling on that column. Prose statements are never read for their
meaning, so they are never called contradictory. Instead,
overlapping_live_clarifications names every live ruling on one subject when
there is more than one. It says whether they record the same ruling, without
claiming whether reworded rulings agree. Subjects match when they are equal
(ignoring case and spacing). Reworded subjects match only when they name the
same identifiers and one subject’s content words contain the other’s. Word
order and filler words do not matter, and a word may be added, but a word is
never replaced: “rounding of orders.amount” matches “orders.amount rounding”,
while “timezone of orders.created_at” and “precision of orders.created_at” stay
separate, as do “legitimately empty” and “correctly empty”. A ruling joins a
group only when it matches every ruling already in it. Retired rulings do not
count. If the register cannot
be read, the finding says the contradiction check was not completed. To resolve
a duplicate or superseded ruling, withdraw it on the owner’s word or have a
person overturn it on the review screen. When the run names an estate, this
check reads the clarification store twice.
uncovered_structural_item names an add_table, add_derived_mart, or
add_column structural item with change_expectation: "must_match" that no
sealed check reads and whose source catalog has no same-named object or column
to compare. The item therefore remains unconfirmed on every build, including a
correct one. Register an obligation that reads the item, or explain in the
thread why it remains unconfirmed. This source-catalog check runs only when
such an uncovered item exists and a source connection is bound; it uses one
metadata round trip per distinct schema and one per relation named by those items.
See the spec conformance endpoints for reading the registered artifact by hash and running downstream grading.
author_spec
Hand a migration ticket to the spec-author seat. The run refuses a sealed spec when
its relation evidence came from a different connection than the requested estate,
unless the operator explicitly declares that the other connection is the source of
truth for this run.
Before the seat starts, Genesis checks that the configured model provider answers;
an unavailable refusal carries the classified cause and its remedy instead of
starting a run. The shared probe and its cache window are configured by
llm.provider_preflight_ttl_seconds.
See the Genesis Prover overview for how specification-
authoring model usage appears in Pulse Costs.
If an authoring run later makes no progress for estate_char.spec_author.no_progress_seconds,
the seat stops the stalled turn through the owning runtime before returning
error_type: "run_stalled"; refused stop requests are retried under
estate_char.spec_author.stall_stop_attempts and
estate_char.spec_author.stall_stop_retry_seconds. Poll the run after a stall and check its
summary before submitting again, because the summary says whether the runtime accepted the
stop or the retry limit was exhausted. For terminal run-summary fields, see the
author-seat API reference.
A one-line ticket is a valid brief — “Migrate the SALES database to the target
system as-is; the data values must match” — and is the right one for a lift-and-shift. Pass
the user’s own words; do not pad the ticket with what the system diff already measures
(object presence, column presence, types, row counts with row identity, value
distributions, keys). Write more into the ticket only where the user states something
the diff cannot see: a business rule, a derivation, a domain, a reshape, an aggregation
or a new mart. The diff only compares the two estates, so anything the user states as an
absolute — “exactly 1.2M rows”, “this column must be DATE” — belongs in the ticket even
though the diff measures that property relatively. And a comparison the diff could not take
is not one it passed: it skips wherever either side is unmeasurable, so where it abstained
only an obligation in the spec delivers a verdict.
Separate the commission from operator background. Pass the business request and requirement
documents as requirements (or under the older ticket_text name); if both are supplied,
they must contain the same text. Pass build history, reload details, or earlier findings as
context, not as requirements. The seat sees context in its own block and records it apart
from the ticket. At sealing, an obligation whose rationale cites only context is refused
with operator_context_obligation; context is background, not evidence of a requested
check. A written_by obligation is refused with unrequested_mechanism_obligation unless
the requirements name its demanded mechanism, such as a job, notebook, or pipeline. Record
build background with register_substrate when appropriate.
In a repair round, these checks carry forward independently by obligation_id: the context
check does not re-judge an obligation whose rationale is unchanged from the prior seal, and
the mechanism check does not re-judge one whose kind and demanded writer.mechanism are
unchanged. Other edits, such as rewording the title, do not by themselves make the carried
part a new demand. A changed rationale is checked for context support, and a changed kind
or mechanism no longer meets the mechanism check’s carry-forward test; a non-carried
process obligation is checked against the requirements again.
A repair round loads its named prior seal before registration and carries forward the still-
standing clarification rulings already cited or used to answer questions anywhere in that
seal’s repair lineage. Caller-supplied clarification_ids are still validated against the
named estate_id; retired or cross-estate caller ids refuse the submit, while a carried ruling
that is no longer valid is left behind. The run summary records inherited ids in
clarifications_carried_from_lineage, separately from caller-named ids. On the brief, the
seat is told the prior seal’s ticket and which ticket lines are new, when both ticket texts
were recorded. It is also given earlier rounds’ questions and proposed owner-rule checks, so
it does not ask the owner the same question or offer the same check again on an unchanged
fact. Earlier answers superseded by a later resolution are not carried as current rulings.
Every open question and proposed rule must be returned in the same RESULT line; withholding
one for a later round would offer it again on reseal. Exact repeated rule offers are retained
in owner_rule_offers_already_made in the run summary rather than being presented to the
owner again. A repair may ask or offer again when the ticket or measured estate changes the
fact the earlier question or offer rested on, and must state that change.
For a document attached to the current chat, use its File ID or Git Path as an upload.
The attachment notice may also spell its Git Path as a repository asset in uploads:
repository: {bot_git_repo: "uploads", path: "<notice path>"} is read as that upload
when this instance has no local bot-git repository named uploads, and its ref may be
omitted. If a local uploads repository exists, include its ref to read the path from
that repository; omitting the ref is refused. Other repository assets require a ref.
When a conversation resubmits the same commission without
repair_of (same conversation,
source and target connections and catalogs, and spec_name), it may omit target_model only
if a seat in that commission’s last 20 rounds registered the newest mapping previously
proposed; it is carried unchanged under its original asserted_by, and
data.target_model_carried_from names a round whose seat registered that mapping. estate_id
does not split the commission: for a resubmission that names an estate, the pre-check reads
rounds for that estate or for no estate; when the resubmission names no estate, it reads all
rounds in the commission. If no compatible round’s seat registered the newest proposal,
submit refuses before starting another seat and asks for the mapping again. With no earlier
proposed mapping, the pre-check leaves the request to the seat. A commission that should carry
no mapping needs its own spec_name. An omitted mapping without repair_of costs one indexed
run-history read and one batched read of two summary fields for up to 20 rounds; it reads no
estate and makes no model call. See the [author-seat API reference]
(/docs/Genesis-API/API-Reference#post-api-estate-spec-conformance-author-seat) for the HTTP
request and response fields.
The sealed provenance also records which authoring settings the deployment default decided
in seat_settings_defaulted; see run provenance
for how to read that field.
Layered Medallion mapping rules are documented in Declared target mappings and Data Vault
shapes.
author_spec returns layered_source_undeclared or unanchored_derived_target when those
checks fail; neither refusal seals the specification.
For a stalled author_spec run, follow next; see the author-seat API reference.
Send source_estate_basis only when the operator has made that declaration in words;
quote the operator’s reason. Do not infer it from a ticket, an estate, or an earlier
run. A partial object is refused and no authoring run starts. When the declaration
matches the observed substitute connection, the sealed result records the substitution.
When one connection serves both estates as two catalogs, pass both catalog names so the
seat reads each side in the intended catalog. Omit them when the connection’s own catalog
already holds the tables; an omitted side reads that connection catalog. The commissioned
catalogs are kept on the run and used by estate reads, so a same-named relation in a
different catalog is not silently accepted. On a split-catalog run, a declared
invariant_side: "target" routes its registration check only to target_catalog; other
registration checks use source_catalog.
On Snowflake, each named catalog must be a bare identifier or one complete
double-quoted identifier; double quotes inside the quoted name must be doubled. A
catalog name outside those forms is refused before the authoring run starts. This checks
whether the name can be bound safely, not whether the database exists or is accessible.
When the seal reads schema and relation names returned by Snowflake’s catalog listing, it
addresses each listed name as stored: mixed-case and lowercase names are double-quoted, so
they are not folded to a different uppercase object. Names not returned by the listing
continue to use the spelling supplied by the artifact. If a listing contains both an
uppercase name and a case-insensitive match, the uppercase name is selected, matching the
object a bare Snowflake identifier reaches.
When ticket_text is present, the sealed artifact retains it as
provenance.instruction_text and records its byline in
provenance.instruction_text_submitted_by. A direct operator call is recorded as
user:<operator>; when an agent relays the ticket through this tool, it is recorded as
agent:<bot_id>. The byline identifies who submitted the retained prose, while the run’s
operator remains the authenticated person who invoked the tool. If no ticket text was
submitted, neither field is added.
Pass clarification_ids when the seat may rely on decisions the ticket did not settle.
Each id must name a record created by record_clarification, and estate_id is required
when ids are supplied. An unknown id, an id recorded for another estate, or ids without an
estate refuses the request before a run starts. The seat and the sealed specification carry
the record’s label and recorded identity; prose in the ticket is never substituted for the
record. A completed run may also surface a true check declined because the ticket states no
rule requiring it. A numeric maximum or minimum may be labeled an observed bound in
the notice; see Prover guidance
for what that means and how to offer the check to the ticket owner.
For target_type_dispositions, the referenced clarification must belong to the run’s estate
and a signed-in person must ratify it through the clarification review API.
Record its statement as the prefix TARGET TIME ENCODING v1: followed by one JSON object
with exactly relation, column, physical_type, and encoding_rule; the fields must state
the exact choice for that column. For example, the statement for EVENTS.START_TIME is
TARGET TIME ENCODING v1: {"column": "START_TIME", "encoding_rule": "HH:mm:ss", "physical_type": "STRING", "relation": "EVENTS"}.
After the person ratifies that clarification, pass its id in the matching disposition:
{"relation":"EVENTS","column":"START_TIME","physical_type":"STRING","encoding_rule":"HH:mm:ss","clarification_id":"<id>"}.
The author_spec seal validates the current ratification and stores the selected encoding
in the sealed specification. A repair round revalidates a carried encoding against the
current clarification record and drops it if that column is newly declared non-TIME. Do not
invent a disposition or ratification; native TIME storage is not supported by this gate yet,
and TIMETZ or TIME WITH TIME ZONE cannot use HH:mm:ss because it would discard the
offset.
Pass target_model when the user describes a target that does not keep the source’s tables
one for one — a Data Vault, a Medallion build, any split, merge or derived table. It is the
source-to-target mapping, and the proposer writes it: the seat never does. A mapping that
does not parse refuses the request before a run starts. The seat checks one that parses
against the source (every source column carried or declared dropped, every named column
present, each hub’s business key unique and non-null, and each rendered link’s full key
identifying one junction row), registers it with the obligations it renders, and otherwise
ends the run unsealed with its findings for the proposer. When a key can be read, the
refusal reports repeated link keys with the source row, distinct-key, and repeated-key counts
and names a dependent child to add; it reports key parts that are NULL too. An unavailable
or unsupported source is reported as unmeasured rather than unique. A vault or
Medallion ticket sent without one is returned asking for it; if the resulting spec scopes
inputs and describes a non-source target, finalization returns unmapped_reshape and seals
nothing until the proposer supplies the mapping.
Finalization returns unassessed_but_assessed when the spec also assesses a table the mapping
leaves unassessed, and unassessed_without_scope when the spec declares no scope. The
Prover mapping guide
gives the declaration shape and comparison behavior.
Every input in the spec must also agree with that mapping before the seat can seal. The
mapping must declare the input as loaded into nothing — a split with an empty images list,
or a source of a derived target. If the mapping carries the input into an image, or does not
name it at all, finalize_spec refuses the seal with undeclared_input; the refusal lists
each offending object and nothing is sealed. The proposer must correct target_model, or
remove the input scope when the ticket does not describe an input.
Before sealing a spec with a declared target_model, finalize_spec also prepares each
obligation’s target_sql against the empty target catalog described by that model. For an
invariant declaring invariant_side: "target", it also prepares the target-side
violation-count statement the grade composes for that invariant. Each relation is checked
against its own declaration: when the SQL names a schema where the model declares that
table, the check uses that schema’s declared columns plus any unqualified declaration of
the table; when the SQL names another schema, it uses the union of the table’s declarations.
If either statement reads a column or table the model says is absent, the seal is refused
with unrunnable_on_target_model; the refusal names the affected obligations and the
missing relations or columns, and nothing is sealed. Rewrite target_sql to use only
declared objects — for example, join a link’s hash keys to its hubs to reach a business key,
or read the hubs, satellites, and links that receive a split legacy table; a legacy table
that only derived targets are built from (a Medallion gold table’s sources) is read in
source_sql, with the derived target in target_sql — then re-register the obligation
under the same obligation_id and finalize again. A spec without target_model keeps the
prior behavior and does not run this target-catalog check.
finalize_spec asks the target engine to prepare, without reading a row, every obligation’s
target_sql and the check of every invariant declaring invariant_side: "target", and then
runs each statement it accepted with every relation the statement reads capped at 1,000 rows
(each relation replaced by (SELECT * FROM <relation> LIMIT 1000)), so an error the engine
raises only while evaluating a row — INVALID_ARRAY_INDEX from array[0] on an empty
array — is found before the seal rather than on every proof. A run error refuses the seal
with target_engine_rejected, quoting the engine; a statement that cannot be bounded that
way, or whose bounded form the engine does not accept, is not run and is listed under
not_executed. This adds one live round trip for each accepted statement and one more when
a sampled run errors and its bounded form must be prepared. Only the sampled rows are
evaluated, so a row outside the sample can still raise the error at grade time. When
target_connection_id was commissioned, preparation uses that connection and its engine;
otherwise, it uses the seat’s connection when a target_catalog or source_catalog places
the target there. A statement the engine rejects refuses the seal with
target_engine_rejected, naming the obligation and quoting the engine’s error; rewrite it
in the target’s dialect, re-register it under the same obligation_id and finalize again.
A statement over a relation the target does not hold yet is not refused, unless a relation
it reads is one the spec declares on the source side (an input or excluded scope entry,
or a legacy object the target_model puts on no target) and the target engine, asked about
that relation alone, does not hold it: the seal is then refused with
target_reads_source_object, naming the obligation and the relation. Read a source relation
in source_sql only. This adds one live round trip for each such relation. The result — a
refusal included — carries target_engine_prepare, whose status is prepared only when
there are no rejected statements, rejected when a statement fails at either prepare or
run, and not_prepared when the target is not placed on a connection or the engine cannot
be reached or refuses this caller access. A seat run commissioned with no target placement
at all (no target_connection_id, no target_catalog or source_catalog) and holding a
target-side statement is refused with target_not_placed, naming each statement it could not
send; commission the run again with target_estate_id, target_connection_id or a catalog.
A thread with no seat run keeps the not_prepared record and seals. Its connection identifies the selected target
connection. execution_row_cap is 1000; executed lists the obligation ids whose sample
runs succeeded, not_executed lists checks not run with their reasons, and each entry in
rejected includes stage (prepare or run). A run-stage rejection means the engine
accepted the statement but raised an error while evaluating sampled rows.
On a spec whose target_model declares a placeholder row — a hub’s ghost_keys, or a
derived target’s unknown_member ({"column": …, "values": [...]}) —
finalize_spec refuses with invariant_over_declared_unknown_member a target-side
invariant over that relation that puts a constraint the grade counts on any other column (a
finite-only rule is never refused), or constrains the member’s
declared key with a constraint its declared value breaks, judged as the grade counts it: a
NULL key breaks only not_null, and finite, which the grade records and never counts,
refuses nothing. The refusal names the obligation, the
relation and the member. It reads those fields only — never the derivation’s prose, never a
row of the build; restate
the rule as a recompute that excludes the member, re-register it under the same
obligation_id, and finalize again.
When assets is supplied, the intake and seal also carry asserted_by, stamped from the
call’s own identity (agent:<bot_id> or user:<operator>), and a label such as
canonical, asserted by agent Eve. The asset cannot override that byline.
An asset may carry its document as inline content (up to 2 MiB, or 2,097,152 characters),
as repository (bot_git_repo, ref, and path), or as upload (file_id), never more
than one. An upload is a file attached to the current chat; use the File ID or Git Path
shown by its attachment notice. The repository must be a
local Genesis bot-git repository that the submitting operator can read, and an upload uses
the same read grant as the uploads repository. Genesis reads the
file at submit, accepts it only when it is whole text within the limit, and refuses the
submit before starting a run when access or reading fails. Asset names must be unique across
label-only and document-carrying entries. The document is stored with the run rather than
copied into the brief, so the seat reads it with read_spec_asset before authoring. The
intake and seal retain only its pin: source, chars, content_sha256, and the storage
metadata needed to identify the bytes read.
Before a run starts, the seat counts the numbered items and table rows in the ticket and
its document assets. It refuses the submission when that total is greater than the
capacity of the registration budget: at most 100 clauses per
register_clause_accounting call, multiplied by
estate_char.spec_author.max_registration_calls (default 200, bounded 10..5000).
The refusal is returned as validation error 422 and no authoring run is created. This is
an upper bound rather than a guarantee, because other registration calls share the same
budget; a bundle below the clause ceiling can still exhaust it during authoring.
If a pinned document cannot be read when the seat finalizes, the round is refused with
rule: "asset_documents_unreadable". The refusal records whether the asset was missing
or the asset store failed, and does not treat the unreadable document as an empty document
or as an accounting gap.
read_spec
Read a sealed specification by spec_hash. Alongside the seal-verified artifact and
authoring provenance, the response includes who_decided: the reliance sentence, each
recorded clarification with its label, each declared asset with who asserted its label,
the byline for submitted ticket prose, and—when the specification carries a proposer’s
target_model—target_model_asserted_by, the server-stamped identity that supplied the
mapping. It also returns offered_not_adopted: checks the sealing seat offered as stated
rules, and preserve-the-source migration defaults it offered instead of registering, that
the seal does not carry. Each entry has its obligation id, statement, seat run id, and a label
stating that it is not graded. These offers are listed once per obligation id as context, not
added to the specification. A migration-default offer is not an owner question; commission
a repair with repair_of for the seat to register it. A seal made before clarification
provenance was recorded reports clarification provenance unknown; it is not treated as a
customer’s ruling. The tool requires ratify_source_contract and does not recompile the
artifact.
spec_author_registrar_tools
The Registrar’s authoring tools for a spec-author seat run commissioned with
authoring_tooling: "registrar", the deployment default. A per-run classic override is
accepted only when repairing a spec sealed with classic. The seat service adds this group
to that run’s thread, alongside the seat’s own default groups. It remains through the seal’s closing turn and is
withdrawn when the run becomes terminal; a Registrar call after sealing refuses and
withdraws it immediately. It is not in the default tool groups. The classic
spec_author_tools group and its behavior are unchanged. The run must use the registrar
tooling recorded at submit; these verbs refuse on a classic run.
Progressive authoring
A fresh registrar round begins atscope_population. The four phases are:
Each closed phase is checkpointed on the run row with a digest, counts, registered ids, and
closed_by, which identifies what closed that phase. It is advance_author_phase for an
explicit advance, register_model_fields when that registration completes model_fields,
and finalize_spec when sealing closes a phase. When later-phase content is first
registered, the draft at that point is pinned for the phase it moves on from: a structural
item ends scope_population, while the first obligation or settlement ends
scope_population and model_fields. That checkpoint names the first registration that
crossed the boundary as first_<kind>_registration (for example,
first_structural_registration). If that phase’s check passed on the pinned draft,
closing it later—including at finalize_spec—records that snapshot, not the later draft.
If it did not pass then, its checkpoint uses the draft as it stands when the phase actually
closes.
The shared classic registration verbs remain available throughout. register_model_fields
returns a phase block with the current phase, phases closed by that registration, next
instructions, and any outstanding requirements; if a checkpoint cannot be recorded, the
block includes not_recorded. When the registered target_model declares no derived
target and every changed object already has its structural item, advance_author_phase
can skip model_fields while closing scope_population; its reply lists the skipped phase
and reason. This tool is otherwise mainly for explicitly closing a phase with nothing to
register; skip_reason explains why, but never waives required registrations.
finalize_spec seals from any phase once every phase check passes on the draft, and the
seal records checkpoints for every phase, including phases not previously closed. Otherwise
it names what is outstanding. Every object registered with
expectation: "changed" still needs a structural item before the spec can seal. After the
run ends, these verbs refuse.
Repair rounds seeded by load_prior_spec have no phases: correct the seeded draft and
finalize it directly.
Grouping hints
On a registrar run, a reply fromregister_obligation or register_obligations can carry
grouping_hints: each names three or more obligations in the draft, at least one of them
just registered, that test one predicate over different tables, and suggests one grouped
obligation over them. The hint is advisory and changes nothing; each per-table check stays
registered. Obligations count as the same predicate only when every verdict-deciding field
matches once the word naming their relation is abstracted (hub_customer, hk_customer and
'CORE.customer' against hub_account, hk_account and 'CORE.account'), and each
statement reads a single relation. Fork members, checks rendered from the target_model,
and either half of a population-root pair (a key-only root beside the check comparing that
population’s values) are never hinted. The hint appears only after a Registrar verb has
confirmed the thread’s run, and never on a classic run. To act on one, register the grouped
obligation and remove the per-table ones with withdraw_obligation.
advance_author_phase
Explicitly close the current phase and open the next. This is rarely needed: a
register_model_fields call closes the phases it completes, and finalize_spec seals once
all phase checks pass. Use this when a phase has nothing to register; an incomplete phase
is refused with its missing items, and final_review has no later phase. When model_fields
has nothing to act on, the reply lists it in skipped_phases with a skipped_reason.
Cost: one run lookup, a draft copy and digest, and one run-summary read/write. No estate I/O.
reopen_author_phase
Normally correct earlier registrations in place by re-registering their ids. To explicitly
return to an earlier phase, use this tool; the draft remains, but checkpoints from that
phase onward are removed and the phases must be closed again before finalizing. This is not
available on a repair round.
Cost: one run lookup and one run-summary read/write. No estate I/O.
checkpoint_draft
Read the current phase and all saved checkpoints, including each completed phase’s digest,
counts and ids. It does not change the draft and is not available on a repair round. No
caller parameters; Genesis supplies the thread identity.
Cost: one run lookup; no write and no estate I/O.
register_model_fields
Register all derived target relations and their columns as structural items in one call.
Columns must be declared by the registered target_model, or named in an exact quote from
the ticket or one of the run’s asset documents. all_model_columns expands to all columns
declared for that derived target. The call accepts one to 25 models and at most 200 model
and field items together. It closes scope_population when that phase’s check passes and
closes model_fields once its check passes after registration. Its phase reply reports
the current phase, completed phases, next instructions, and outstanding requirements. Every
registered model and field declares
change_expectation=must_differ: the build target holds it and the source does not, so a
grade confirms it by presence and fails it when the build lacks the relation or column.
Presence is all it confirms; a field’s values need an obligation that reads it.
Each registered model that is a derived target with a
declared grain, one column or several, also gets a grain check, G-<target> (for example
G-CUSTOMER_SUMMARY; named by the qualified name, its segments joined by hyphens, such as
G-MAIN-FCT_ORDERS, when two derived targets share a name). A call registers the checks of
the targets it names: an exact qualified name selects that target; a name at another depth
selects a target only when its last segment is unique. Each check goes through ordinary
obligation registration and its gates. It is a self_consistency obligation whose target
side counts the rows beyond one per key, a NULL key included, and whose expected side is
zero, so it satisfies the seal’s grain rule for that relation. A composite grain is keyed by
DENSE_RANK() OVER (ORDER BY <grain columns>), which cannot merge two distinct keys as a
joined string could; a row with a NULL in any grain column counts as a violation. That rank
sorts the target on its grain each time the check runs. The reply’s grain_checks
names the checks registered, any refused,
and each target that got none and why: no declared grain, a declared unknown member with a
NULL key, or a name that would need quoting (including a reserved word such as order). The seat writes those grain checks itself, and the
membership and value checks every derivation needs.
Example:
register_value_checks
In the obligations phase of a fresh Registrar round, register the missing keyed comparisons
for derived outputs that must equal a reference original (must_match). Call it after
registering the output’s column items and your own checks. It finds every output column item
not already compared with that reference and registers one membership check per output,
comparing those columns row by row using the output’s row_identity. Columns whose reference
types are FLOAT or DOUBLE are grouped in a separate VALUES-<output>-FLOAT check with
relative_tolerance: 1e-09; all other columns use exact equality. This covers derived and
rendered columns as well as columns named in the ticket. Checks already comparing a column
are not duplicated. If the reference lacks a column, the response reports it in
excluded. If a relation, column, or key cannot be rendered, or there is no usable key, the
output appears in not_rendered and needs a check written by the author. A name is written
unquoted when every engine the check runs on accepts it so: on Databricks and Snowflake that is
decided by the engine’s own reserved words, so date is written bare on Databricks. The
fresh-round seal refuses while any required value comparison is missing; it reads each check
in the target engine’s dialect and names a check it counts for no column.
Cost: one run lookup; one connection-record read and the target placement’s run lookup; one
read-only single-row query per reference with a gap; one obligation bulk registration when
checks render (the estate once per check); and one run-summary write.
profile_source_relations
Answer a question about what the source holds — a column’s type, its NULL and empty-string
counts, how many distinct values it takes, which columns identify every row — by measuring it
instead of asking the owner. For each relation it reads the columns and their engine types without reading a row, then
runs one aggregate query over the whole relation: the row count and, per
column, the NULL count, the empty-string count for text columns, and the distinct count. The
profile also lists unique_identifiers, the columns with no NULL and as many distinct values
as rows (a measurement, cited as data_probe). Each profile is kept on the run, so asking about
the same relation again costs no query. A relation whose name or a column name would need
quoting, or that cannot be read, is returned in refused with the reason.
Returns
profiles, measured, reused, and refused.
Cost: one run lookup; for each relation not yet profiled, one schema read that returns no
rows (plus one single-row read, in the engine’s own syntax, when it reports no column
metadata) and one aggregate query over the whole relation (one connection-record read and
door per call); one run-summary write when anything was measured.
register_platform_checks
In the obligations phase, read and account for rules declared by the run’s supplied platform
documents and, for referenced schemas, the SQL catalog. Supported document declarations
include Foundry Pipeline Builder expectations and dbt manifest tests; catalog constraints
include PRIMARY KEY, UNIQUE, FOREIGN KEY, and CHECK. It registers a cited check only
when the spec orders the relation and neither the system diff nor an existing obligation
already covers the rule. A relation scoped same is covered by the diff. Read the response’s
accounting for each declaration’s status: registered, diff_covered, covered,
declined, not_applicable, unrenderable, or to_register (registration was refused).
Write an unrenderable rule yourself with a requirement_source citing its declaration, or
raise it as an open question. Catalog disclosures identify rules that could not be read;
the seal refuses when those rules are unknown rather than treating them as absent.
Only an owner’s clarification supplied to the run can decline a declaration. Pass its
declaration id and ruling id in declined_json; the tool rejects ids or rulings not among
those read by the run. For example:
Cost: one run lookup and one asset-document read; for referenced schemas, two read-only
catalog queries; one obligation bulk registration when checks render (the estate once per
check); and one run-summary write. Catalog constraints are read on PostgreSQL and Databricks
connections; other engines disclose that constraints were not read.
correct_rejected_obligation
Correct fields of obligations rejected by register_obligation or
register_obligations, without resending whole bodies. The obligation id and kind cannot
change, and each corrected body goes through the normal registration checks again. A list
of corrections is applied in one call, each on its own: the reply names accepted_ids and,
for each refused correction, its rejected entry, so only those need resending. A list
that corrects one obligation twice is refused whole. The call counts once against the
registration budget.
Rejected bodies are held in process memory from the first Registrar verb until the seat run
ends. Ending without sealing also releases the run’s saved rejected bodies and population
choice attempts; register the whole obligation again in a new run. If the body was rejected
before a Registrar verb or the process restarted, register the whole obligation again.
Cost: per correction, the estate resolution check and grain probe for one ordinary
register_obligation call.
withdraw_obligation
Remove obligations from the draft before the seal, for example the per-table checks a
grouped obligation now replaces. To correct an obligation instead, register it again under
the same id. On a repair round, a carried obligation can be withdrawn only by supplying the
ruling_id of an owner clarification that this run was commissioned with and that removes
the check. This records the ruling with the withdrawal and allows the seal to record that
obligation’s deletion; every other carried id stays. Leave ruling_id empty when
withdrawing obligations registered in this round. The call withdraws every named
obligation or none: it refuses when an id is not in the thread’s draft, was rendered from
the target_model, a carried id has no valid ruling, or the round has sealed. Each
withdrawal is recorded on the run row under registrar_withdrawn_obligations, with its
reason, phase, time, and (for a ruled carried obligation) the licensing ruling_id. The
terminal run summary retains these withdrawals along with the Registrar phase checkpoints.
Cost: one run lookup, one in-memory draft copy, and one run-summary read/write. No estate I/O.
prover_tools
The Prover’s action verbs — one tool per act, rather than one per API route. Assign
this group to an agent that should verify spec-driven data work end to end: register the
two estates, scan each side, prove the data work, read the findings back, and hand the
result to a person. This covers migrations and builds checked against a written
definition. It is not always-on.
Every verb answers in one of three shapes: a run handle for anything that starts
work (a run id, a status, and the run envelope with a link to poll), a read for
anything that only reads, and a refusal carrying a reason a caller can act on —
whether the agent lacked a permission, named something that does not exist, hit a
conflicting request, sent bad arguments, or asked for something only a named human may
do. Long work is asynchronous: the agent gets a handle immediately and polls it,
optionally asking the server to wait a bounded number of seconds first.
Every answer from prover_tools opens with the top-level fields audience: "agent"
and audience_note: "This is for you, the agent: use it to fix your work. Decide what, if anything, the person needs, and say it in their terms." This applies to run handles,
reads, refusals and tool faults. The answer is working guidance for the calling agent,
not a message to pass through to a person; the agent decides what the person needs and
relays it in their terms. The legacy migration_prover_tools group uses the same marker.
When a Prover run finishes, the agent reports its result. If it succeeded as part of
work the person already asked for or approved in the conversation, the agent continues
with the next step they approved without asking again, unless the person has since said
otherwise. This does not authorize unapproved work or decisions reserved for the person;
the agent asks when it is unsure a step is covered.
Each verb refuses an argument it does not offer by name instead of silently dropping
it. The refusal names the rejected fields and says that nothing was run; check the
verb’s parameter table before retrying. Runtime context fields injected by Genesis are
not caller arguments and remain handled internally.
When a turn has no person identity, its own authority covers author_spec,
register_spec, read_spec, grade, adjudicate, and consult when they require
ratify_source_contract; it also covers cancel_run. Under view_connections, an
unattended turn may run the proof loop with readiness, register_estate,
characterize, prove, get_run, and read_comparison, and call the read-only verbs
list_runs, find_proofs, list_snapshots, read_snapshot,
read_correspondence_rule, list_clarifications, read_proposal, read_bundles, and
list_packages. This lets the agent prepare both estates, submit and follow the
comparison, read its verdict, look up prior runs, proofs, scans, correspondence rules,
clarifications, proposals, bundles, and packages without granting the wider
view_connections permission to other acts such as read_finding,
record_review_decision, or update_estate. compare is not included: prove without
a spec_hash performs the same comparison. readiness still refuses when an answer
requires a person. These reads use the turn’s existing visibility: the thread owner’s
for a product-woken turn, the verified mission originator’s in an unattended mission,
and no person’s visibility otherwise; read_snapshot uses the turn’s own id, which is
narrower still. This changes visibility only, not permission or approval authority; see
unattended mission visibility
for behavior when the originator is absent or cannot be read.
cancel_run remains limited to a run commissioned by the current conversation: both the
caller’s thread and the run’s recorded thread must be present and match, or cancellation
refuses with not_found. That scope check costs one additional indexed run read. A turn
carrying a person is not bounded to one conversation; the ordinary permission check
applies. The exception does not extend to record_clarification or certify_substrate,
which record what a person said and remain refused without a person.
All three shapes carry next — {verb, args, why}, the literal call to make, not
advice. A run handle’s is its run envelope’s, read back rather than re-derived; a read’s
names the verb that consumes what it just produced; a refusal’s names the act that unblocks
it, and carries verb: null on the kinds no call from this turn unblocks (a permission the
identified person does not hold, a product-started turn with no signed-in person for an act
outside the authority exception above, an id that names nothing, an act only a person may
perform). See Prover refusal guidance
for the distinction between a permission denial and an unidentified turn. why is always
populated, so an agent can judge the suggestion rather than obey it.
Service errors classified by the HTTP layer as unavailable, including
NotAvailableHereError and a service that is still starting, return
refusal.kind: "unavailable" rather than "fault". When the service is
starting, retry in a few seconds; otherwise, use the refusal’s reason and
next guidance.
A permanently missing resource is a not_found refusal, not a retryable
service fault. This includes a dataset snapshot that was lost and has no
durable copy; refresh the dataset before trying the read again.
The four comparison verbs — prove, compare, get_run for a comparison-bearing run,
and read_comparison — also carry a top-level presented block. The chat renders that
block as one comparison card; it is null on every other answer and never belongs inside
data. A running card has no verdict, while a completed card carries the comparison
counts and the change since the previous comparison of the same pair. If an unexplained
shrink became partly undetermined, the change line says not measured this time rather
than claiming fewer unexplained; see Comparison cards in
chat for the exact
breakdown. When a prior comparison exists, presented.previous.thread_id names the
conversation that produced it and presented.previous.same_conversation is true,
false, or null when either conversation is unknown; see the same card guidance for
how the chat presents that context. When the card is present, keep the reply brief and do
not repeat its counts;
the Chat and threads guide
covers what people see.
When a completed card includes an assumptions disclosure, its after-assumptions count
and assumption list are carried in the presented.verdict block; the chat renders the
count with an asterisk when the list is non-empty. See Comparison cards in
chat for the fields
and interaction. A missing target key declaration may be included in that assumption
list only when the target does not enforce declared keys and the Prover has checked the
key’s uniqueness; otherwise it remains an unlicensed finding. See the Prover comparison
guidance for the evidence
rules.
For refusal.kind: "fault", follow next as a non-terminal re-read rather than a retry;
see How agents drive the Prover
for the recovery rule.
Every long verb follows that rule now, grade included: it claims the round, starts the
grade and hands back the handle. The synchronous whole-grade form is still what
POST /estate/spec-conformance/grade-compiled serves, for an HTTP caller that wants the
verdict in the response.
Prover reads and actions use the identity behind the tool call. See Prover result
visibility for the subject
checks shared with REST, including run adjudication, finding consultation, episodes, and
estate ruling and court records.
Verbs that screen a named estate, snapshot, comparison, run, or connection apply that
person’s visibility before reading or starting work. An item they cannot see is handled
like an unknown estate, snapshot, comparison, or run, or an unregistered connection;
the tool does not identify it as hidden. If a connection-grant check is unavailable, the
verb returns unavailable rather than claiming the connection is unreadable.
characterize and find_proofs expose this hint in data.workflow_skill; see
the data-work proving skill guide.
Approval decisions rest on a person. With authentication enabled, an agent can decide
a Prover Action Review request for the person in the conversation, or for the originator of
the goal, Blueprint, or mission it is carrying out, when the person asked or delegated that work.
decide_approval_request records the agent, person, and stated basis. It only decides
Prover requests; other Action Review requests remain for a person to decide. The
record_review_decision tool records a comparison verdict on the same basis.
request_evidence and request_test_case_approval ask for review; see their entries below
for how they behave when authentication is disabled.
readiness
Call this before choosing a migration recipe and again when the person answers checklist
items. A call with no answers, spec hashes, or spec assets resumes the current record for
the pair without writing; if there is no record, it returns the open items. Supplying
answers, spec hashes, or spec assets records a revision. The result recomputes facts held
elsewhere and returns each checklist item as answered, derived, or missing.
Genesis injects
bot_id, thread_id, and user_id; they are not caller parameters.
The tool records the injected thread_id with a new record. By default, when the pair’s
record was first recorded in another conversation, the tool withholds its answers and
documents: the checklist is returned as if nothing were recorded, readiness_id is
null, answers_withheld is true, and other_conversation_record identifies the
record, conversation, and recording time. recorded_in_thread and
conversation_note explain the mismatch. Only set include_other_conversations=true
when the person here asks you to use that record; then confirm each answer with them
before relying on or repeating it. Identical answers submitted from another conversation
keep the first record’s conversation provenance.
When spec_hashes is empty, readiness reads the pair’s latest proof once and can derive
the migration shape from its change_expectation. It does not fall back to an older proof
that the latest one did not repeat, and a named sealed spec remains the source of shape
when spec_hashes is supplied.
For example, start the checklist for a pair with:
record_clarification
Record a decision the ticket left open so a later specification can rely on it without
mistaking the agent’s conclusion for the customer’s words. estate_id, subject, and
statement are required strings. The tool assigns the record’s provenance from the
runtime identity; there is no argument for choosing or upgrading who decided it. In this
revision, every record is recorded_by_kind: "agent" and its label is
agent-certified (agent <bot_id>) (or the runtime’s unnamed-agent identity when no bot id
is available). A heading in ticket_text, including one that says “ratified by the
customer,” is not a provenance record.
The response includes clarification_id, estate_id, subject, statement,
recorded_by_kind, recorded_by, conversation_with, label, and
package_item_citation. That citation gives the clarification_id to put on a
disposition package item and states which items it can carry: a target_defect or
spec_defect over an Adjudicator question or spec_ambiguity, only when this
clarification is on an estate of the comparison’s pair, was recorded after the seat
asked, and was ratified by a signed-in person. Otherwise the citation carries no item;
propose_finding_disposition_package refuses the package rather than treating a note as
a citation. Its fields are package_item_citation.clarification_id and
package_item_citation.carries. Every response also carries already_recorded: a
call that repeats a ruling the same agent recorded on the estate, in a conversation with
the same person, that still stands — the same subject as the seal groups subjects and the
same statement up to case and spacing, or for a structured TIME statement the same
column, type and encoding — writes nothing and returns that standing record with
already_recorded: true and a message naming its id and label. For an agent record,
conversation_with identifies the signed-in person by email when available, otherwise by
display name; if neither can be resolved, it is unnamed and the label says that the
signed-in person’s name is not on record. An email identity can itself name the person when
no user record is available. With authentication disabled it is unauthenticated, and it
is absent when the turn had no person. That name does not make the ruling person-ratified:
the record remains agent-certified until a person reviews it. Pass the returned
clarification_id in
author_spec’s clarification_ids; the seat validates that every id belongs to the same
estate_id before starting. A signed-in person can later ratify or overturn the recorded
clarification through the Estate API; that review happens after reliance, never as a gate.
Ratification changes the label to person-ratified and names the reviewer. An overturned
clarification cannot be supplied to a new author_spec, and any seal or run that relies on
it reads reopened. If the owner later takes back or replaces the decision, the recording
agent can withdraw it with withdraw_clarification. The tool requires ratify_source_contract; when authentication is on
and the turn has a non-placeholder user id, it performs one user read, in addition to one
estate read, one read of the estate’s clarifications and one of their reviews, and, when
the ruling is new, one insert and one read. See the clarification review endpoints
for the review request and response fields.
list_clarifications
List the rulings recorded for a registered estate when you need a clarification id or want
to inspect who decided each ruling and where it is used. The response is ordered oldest
first and includes estate_id plus clarifications; each entry carries its
clarification_id, subject, statement, status, label, reviewed_by, cited_by
(the sealed specification hashes that cite it), and reopened after an overturn or
withdrawal. Status withdrawn means the recording agent retired it on the owner’s word;
like overturned, it cannot be cited by new specifications. An empty list means the estate
has no recorded rulings. The tool requires view_connections, performs no model call or run,
and refuses an estate that does not exist or is not visible with not_found.
withdraw_clarification
Withdraw an agent-certified clarification you recorded when the owner takes the decision
back or replaces it. Record the replacement first, then withdraw the old clarification and
include the replacement’s id in reason. Only the agent that recorded the clarification
can withdraw it, and only while it remains unreviewed. A person-ratified clarification is
the person’s decision and must be overturned by that person through the review screen;
another agent’s clarification is not yours to withdraw. An already overturned or withdrawn
clarification cannot be withdrawn again. The withdrawal is final.
The withdrawal records the owner’s words in reason. A completed withdrawal prevents the
clarification from being cited by new authoring, question resolution, or proposals. Sealed
specifications that cited it and runs measured against those seals read reopened. The
completed response returns the clarification with status withdrawn, reviewed_by set to
agent:<bot>, and reopened with the dependent snapshot captured just before withdrawal.
Its label says withdrawn by agent <bot> on the owner's word: <reason> (recorded by agent <bot>). It requires ratify_source_contract and acts with the calling user’s estate
visibility.
If the clarification has dependents, the first call records nothing and returns
data.confirmation_required: true, data.withdrawn: false, data.would_reopen, and
data.confirmation_token. Show the owner which sealed specs and runs would reopen and ask
whether to proceed. Only after their yes, call again with confirm=true and that token. If
the token does not match the current dependent set, the call records nothing and returns a
fresh preview with a new token. A withdrawal with no dependents proceeds without confirmation.
resolve_open_question
Resolve one question that a completed author_spec seat could not settle by measuring the
estate. The run-finished notification and read_spec list these questions in number order;
resolve each one before using the sealed spec for prove. This tool records either an answer
or an explicit decision to continue without one, and a later resolution of the same question
supersedes the earlier append-only record.
The response returns every question with
status (open, answered, or proceeded), its
current label and resolution metadata, plus open_count, next_open_question, and the run’s
spec_hash. owner_answered is false while a question is open or was closed without an
answer; it is null when an agent supplied a clarification. Both resolutions are recorded as
the agent’s act: a clarification is agent-certified, not the owner’s answer unless a person
ratifies it, and proceeding without an answer explicitly says the owner has not answered.
Check the clarification’s review for ratification. If someone else must decide, leave the
question open and report it rather than closing it. The tool requires
ratify_source_contract; it makes no model call and costs one run read, a clarification/review
read when an answer is supplied, one insert, and one resolution read. It refuses a non-seat or
authoring run, an unknown question number, both or neither disposition, or a missing,
overturned, or withdrawn clarification.
withdraw_assumption
Stop the Prover relying on one of its default assumptions for a comparison’s estate pair.
diff_hash and assumption_id are required; reason is optional. The id is one that
read_comparison lists in comparison.assumptions, such as a proven pair’s type
spellings. The withdrawal applies to every later comparison of the same estate pair: the
next one reports the differences the assumption covered as findings, and its summary lists
the withdrawal under withdrawn_assumptions. Stored comparisons keep their verdicts; an
approval of a comparison whose pass relied on the assumption reads reopened until the
assumption is restored.
Later proofs and comparisons keep the withdrawal ids and their bylines from the same
snapshot used to key the run; see the Prover comparison guide.
The act is recorded as the agent’s, under the bot id the runtime supplies. The target
platform’s identifier-case license (identifier_case:<platform>) and the engine’s
collation-ordering license (collation_ordering:<component_pair>) can also be withdrawn,
but only when the comparison relied on them. Withdrawing the former makes names that
previously matched by the platform fold read as missing and surplus; withdrawing the latter
makes text minimums and maximums abstain rather than compare as content. The tool requires
view_connections and performs one comparison, snapshot, run-summary, and withdrawal-log
read, one read of the pair’s comparison run ids followed by three projected summary fields
for those runs, and one insert. A person withdraws through
POST /api/estate/system-diffs/{diff_hash}/assumptions/{assumption_id}/withdraw.
The tool returns the withdrawal event and refuses a second withdrawal of the same assumption
for the pair. If a concurrent change moves the standing while the withdrawal is being written,
the tool refuses instead of appending; read the assumption’s standing again before acting. See
the Estate API response contract.
restore_assumption
Let the Prover rely again on an assumption withdrawn for the estate pair. An agent may
restore only a withdrawal an agent made; a person’s withdrawal is refused as a conflict
and must be restored by a person through
POST /api/estate/system-diffs/{diff_hash}/assumptions/{assumption_id}/restore. The tool
requires ratify_source_contract and performs one comparison read, one snapshot read,
one withdrawal-log read, and one insert.
It accepts the same diff_hash, assumption_id, and optional reason parameters. A restore
makes the assumption available to the next comparison. If a concurrent change moves the
standing while the restore is being written, the tool refuses instead of appending; read the
assumption’s standing again before acting. See the Estate API restore contract.
export_comparison
Package a finished comparison for transfer to another Genesis server. The bundle keeps
the comparison’s diff_hash, run ids, snapshots, measured objects, estates, review
events, findings, and ratified rules, so the receiving server can show the same card
without access to either database or its credentials. Connection values travel as
references only; credential-shaped fields in stored JSON are redacted. Use
read_comparison when you only need to check whether a comparison exists.
The response contains
data.bundle, including an envelope with the bundle type,
schema version, contract, export time, source-server identity, connection references,
and estate ids, plus the portable store rows. An unknown hash returns success: false
with type: "not_found". Exporting is an expensive read: about two dozen indexed
store reads and JSON decoding for the bundle’s payloads.
import_comparison
Load the document returned by export_comparison onto this server. The imported card
retains its content-addressed identity; use the returned estate_id_map when a source
link names an estate id that differs on this server.
Run dry_run=true first when the target may already contain part of the comparison. The
plan reports per-table creates and conflicts, estate adoptions, and referenced
connections without writing. A missing connection is reported but does not prevent the
card from being read; only a re-run or live replay needs that connection.
If a correspondence-rule payload reads as a rule but its content hash differs from its
bundled rule_id, the import is refused regardless of on_conflict; the importer does
not guess which id the sender intended.
An imported review event whose event_type exceeds the column’s declared width is
also refused before any rows are written. The refusal shows at most the first 80
characters of the kind and reports its full length and the column width.
For the one-to-one estate binding rule and its warning when an estate keeps its own id,
see moving a finished comparison.
The tool requires
ratify_source_contract; export_comparison requires
view_connections. For the REST request and response fields, including conflict status
codes and the transaction behavior, see the comparison transfer endpoints.
See the system diff API reference for compare retry semantics.
record_review_decision never invents authority. A run decision is optional once verified
people have accepted every item that kept the comparison off Verified; do not ask for a
separate run sign-off to reach that outcome. An explicit reset to awaiting_review is a
person’s “not approved” and keeps the comparison off Verified until a verified approval
replaces it. The reviewer identity on the record is always the one the server derives —
the authenticated person, or local operator (auth disabled) on a deployment running
with authentication disabled. The optional authority text is
recorded beside that identity, never instead of it, so a local stack’s record can still
say who actually made the call. Resetting a comparison to “awaiting review” records no
decision, so it refuses an authority note rather than accepting one it would discard.
With authentication enabled, an agent cannot record a verdict at all; it is handed back to
the person.
For the request fields, exact-one rule, byte measurements, and mismatch guidance, see the
detailed compiled-spec API reference.
Use get_run as the only source for a run’s outcome: its envelope carries the status,
refusal reason, provenance, and completion state. Use read_comparison as the only
source for a comparison result and read_finding as the only source for a finding’s
decision history; do not reconstruct these records from estate queries, logs, or report
files.
For a finished proof or grade, quote envelope.report_this word for word as the record
line. Listing rows from list_runs and find_proofs do not carry that sentence; call
get_run before reporting the run. See reporting a completed
run for the sentence’s
contents, grade-classified counts, and how to handle causes the record does not state. For
how stored grades without spec_seal_state are read, including older-engine grades, see the
compiled-grade API reference.
get_run late-ruling fields: coordinate contract.
During shutdown, newly submitted Prover work can be refused before its flow starts; see
Shutdown and scheduling refusals
for the run-row behavior.
prover_tools replaces the much larger set of Prover tools that grew one-per-route. The
older groups below — source_contract_tools, migration_prover_tools,
spec_author_tools — keep working while teams move across. For acts shared with
prover_tools, prefer the newer group; the older groups retain the source-contract,
stimulus, and migration-validator verbs that have no prover_tools equivalent.
The exact calls, arguments, return keys and refusal shapes an agent needs are in the
agent-facing reference: docs/prover/tools.md in the repository, with
docs/prover/run-envelope.md for the run envelope every verb answers with and
docs/prover/prove.md for prove itself. For the proof summary’s always-present
rounds_used_basis, see What a run reports back.
Estate registration and code assets
Useregister_estate to create an estate before characterizing it. Registration checks
that each member connection is reachable but does not scan the database. When the
transform repository is already known, attach it with code_assets; each item accepts
kind="git" and exactly one of connection_ref, url, or bot_git_repo, with optional
ref and subdir.
Registration is safe to repeat: when the requested scope is already registered and visible
to the caller, the tool returns that estate with data.reused: true and the same
estate_id; use update_estate to change its definition. A new registration returns
data.reused: false. For the exact scope identity, visibility conflict, and fields that
remain owned by the returned estate, including the same-source estates and proof-history
disclosure, see the estate registration API reference.
Before registering an estate, look up the estates already on its connection with
find_proofs(source="<connection ref>"). If the response has several candidates,
data.resolution.candidates lists their scopes. Reuse an estate that already covers the
scope you need; register a new one only when none does. Same-scope registration reuse does
not detect overlapping scopes, such as a whole-database estate alongside layer estates.
If you create a redundant estate, identify the existing estate to use in your reply so
others do not rely on an ambiguous name-based lookup.
Registering is not a readiness check. Where the server runs an automatic readiness
preflight, the answer’s data.preflight names that run and the state it is in
(run_id, status, stage, basis), and while it is unfinished the answer’s next
points at that run rather than at characterize. A stage of starting means nothing
has yet reported on the estate’s access, ETL or clonability.
Attaching a code asset records where the code is; it does not read or pin the code. If an
estate response’s next names clone_code_assets, call that verb before
characterize so each attached git repository is cloned or each Databricks notebook or
job has its revision captured. If a SOURCE estate has no attached code and is not marked
source_only, the response also suggests update_estate(estate_id=..., source_only=true);
use that only when no transform of yours produces the raw data, or attach the transform
with update_estate(code_assets=...) instead.
Use update_estate for later definition changes. Omitted fields stay unchanged; supplied
members and code_assets values replace the complete lists, and code_assets=[]
clears the attached repositories. An edit that supplies no field is refused. status
accepts draft, validated, or partial; archived is refused because archiving
requires the estate archive API. If a scope edit is refused because another live estate
already reads that exact scope and the refusal names it, use that estate rather than
registering a duplicate.
After attaching repositories, call clone_code_assets(estate_id=...) to download them or
pin a Databricks transform. It returns cloned, captured, skipped, and failed
counts plus the updated estate. A databricks_notebook has no clone: Genesis makes two
workspace REST calls and stores the notebook’s exported-source SHA-256 in revision; a
databricks_job makes one call and stores the job-settings SHA-256. The workspace is
read as the estate agent on the signed-in user’s behalf; an agent call supplies its bot
identity, while an API call uses estate_char.stimulus.agent_bot_id. If that setting is
empty and no bot identity is supplied, nothing is read and the call is refused. Set
force=true to refresh existing clone references or captured revisions. Then call
derive_code_lineage(estate_id=...) to parse cloned trees and connect transforms to the
estate’s scanned objects; set force=true to rebuild existing lineage. Cloning performs
network transfer and disk writes, while Databricks capture performs workspace reads.
If clone_code_assets faults after cloning a repository but before saving the estate’s
clone reference, its next does not recommend repeating the clone. The repository may
already exist on disk, so repeating the same call can fail with repository already exists.
reproduce_artifact
Run one artifact already present in the estate’s derived lineage into a scratch estate,
characterize what it produced, and compare that output with the live relation. This is
the only Prover check that demonstrates what the declared pipeline makes; writer
attribution identifies who last wrote a relation, and lineage coverage identifies what
an artifact claims, but neither rules out a table patched until it matches.
This operation executes customer SQL and writes to the destination. Set
utility_estate_id to an estate registered with kind="utility"; a live estate is
refused. On a metered engine, echo relation in confirm_relation or nothing runs and
no pipeline cost is incurred. The operation is expensive: it characterizes the
artifact’s inputs, runs the pipeline, characterizes the reproduced and live relations,
and performs a mediated comparison. Reproductions that overlap in one utility estate
are refused rather than queued within a Genesis server; give each deployment its own
utility estate.
The runner executes the artifact’s text as SQL statements and ships no notebook runner. A
PySpark, Python, Jupyter, Scala or R artifact can contribute declared coverage through
derive_code_lineage, but cannot run here: it is refused by name before the SQL reader
sees it and returns unmeasured with an error naming the language and saying re-asking
cannot change it.
The response returns
verdict as reproduces, does_not_reproduce, or unmeasured.
does_not_reproduce includes differences and the finding basis
artifact_does_not_reproduce; unmeasured includes error and is a statement about
the run, not a verdict on the pipeline. Every response includes what_this_proves.
characterize
Scan one estate and record what it contains right now. Prefer the estate-bound form
when the database has already been registered: it binds the scan to that estate’s
timeline, updates its latest scan, and makes the resulting snapshot discoverable with
list_snapshots(estate_id). An unknown estate_id is refused with kind: "not_found".
The estate-bound form does not accept
connection_ref, dialect, database,
schemas, excluded_objects, objects, allow_absent_scope, absent_scope_basis,
build_evidence, or role; conflicting
arguments are refused rather than ignored. Use the direct form only when no estate is
registered for the database. A direct scan binds to no estate, so its snapshot is not
added to an estate timeline and cannot be found later with list_snapshots.
When role="target" and allow_absent_scope is true, name why the target is absent:
relocation for a declared relocation whose round-0 target does not hold the relations
yet, or frozen_build_did_not_produce when the build failed before producing them. The
second cause requires all five build_evidence fields and a non-zero build return code;
an unnamed cause is refused instead of allowing an empty target to look like a clean
comparison. The cause is retained in snapshot provenance and used by proof results to
distinguish an unbuilt relation from an unread element.
Both forms return a run handle with run_id, status, and a poll link. The
estate-bound response also includes data.estate_id and the timeline data.scan_id.
Poll get_run(prover_run_id=...) until the run is terminal; a real estate can take
20–30+ minutes, so an expired wait is not a failed scan and re-running an identical
scan wastes warehouse work. If the same characterization is already queued or
running, the tool returns that run with reused: true and a reused_basis explaining
the reuse, and applies wait_seconds to the existing run when a wait was requested.
A finished characterization is not reused: it measures a later instant and a new call
starts a new scan. New submissions return reused: false and
reused_basis: null.
For Foundry, an ambiguous read whose row-cap probe is rejected may require one extra
Spark query to check that read; see Foundry SQL result caps.
For a Foundry run that used the legacy SQL route, get_run includes
summary.source_route_fallbacks on its terminal summary, including an error terminal
when the run fails after falling back. fallbacks counts reads served after the public
SQL route refused them, reads is the member’s total source-read count, reason preserves
Foundry’s refusal message, and cause is refused or not_served. In a multi-member
scan, each member’s summary has its own counts; they do not accumulate across members.
The key is omitted when no read fell back. The legacy route reads the same source data, so
this records route access rather than indicating a scan failure or a bad result. The
two routes have never been compared for latency, so it does not explain a run’s
duration either. See the
Foundry integration guide
for what each route refusal means.
For interrupted-scan isolation, this tool follows the caller-scoped behavior documented
for POST /api/estate/characterize.
Example:
list_snapshots
Call list_snapshots first when the user has an estate id but prove or compare
needs a characterization snapshot id. It returns that estate’s scan timeline newest
first. Each scan includes snapshot_id, run_id, status, whether it was the first
scan or a rescan, and started_at / finished_at. A scan that is still running has a
null snapshot_id; poll its run_id with get_run instead of passing the null to a
comparison.
Every entry carries
binding: bound means a scan event names this estate, while
inferred_from_boundary means the estate’s registered connection, database, and optional
schema scope matches a stored snapshot even though no scan event binds it. Inferred rows
keep snapshot_id and finished_at, but their scan-only fields (scan_id, run_id,
kind, ordinal, status, and started_at) are null; binding_basis explains that
the link is an inference. This fallback appears only when the estate has no bound scans.
An empty scans list is a successful read and now means that neither a bound scan nor a
scope-matched stored snapshot was found. It does not prove that the estate was never
characterized; use list_runs to look for an existing characterize run for the same
connection before starting another scan. An unknown or caller-invisible estate_id is
refused with kind: "not_found". The timeline omits scans naming snapshots the caller
cannot see; fresher-sibling results include only visible estates and snapshots, and
withhold newest-snapshot details when that snapshot is hidden. Their basis reflects the
visible sibling rows, so a filtered list does not disclose hidden siblings. The read costs
one visibility-scope load, plus one database read for a bound timeline, or three when it
must match the registered scope against stored boundaries and snapshots.
Example:
find_proofs
Call find_proofs first when someone asks whether a migration has already been checked,
what proof exists for two systems, or whether a person has signed off on the result. It
searches the proof ledger before starting another comparison, and accepts the estate id,
registered estate name, connection reference (<type>.<name>), or database / catalog name
that the user actually has. At least one of source, target, or spec_hash is required;
omit either estate side to widen that side of the search.
Estate names resolve and proof results are counted only among estates, comparisons, and
snapshots the person behind the call may see. An inaccessible estate is neither a match
nor a named candidate, and proofs with an inaccessible endpoint snapshot are excluded.
This adds one visibility-scope load per search.
Each result in
pairs includes latest_proof, earlier_proofs, proof_count, and a
links.detail URL for the latest comparison. Proof rows include the run id, comparison
hash, certification verdict and basis, stop reason, and review_decision. A reported
review_decision always carries stands: true when the live population was resolved
and the decision accounts for it, false when it no longer accounts for the comparison’s
current population, or null when the live population could not be resolved. null is a
failed measurement, not an approval; treat only stands: true as a standing run decision.
Each proof also carries person_acceptance: when non-null, verified people’s standing
approvals cover every item that kept the comparison off Verified, so report Verified
even when no run decision stands. A person’s explicit reset to awaiting_review keeps
person_acceptance null until a verified approval replaces it. See the comparison review
API contract
for its fields. A standing review_decision answers whether the run decision stands, not
whether the comparison is Verified or needs a sign-off; open read_comparison and use
data.review.nothing_to_decide for that. The
review_decision_basis explains the measured or unmeasured result. A retracted exception
that is later re-approved is evaluated by its final state, so it does not leave the
approval withdrawn. A null review_decision with a basis means either that no
settlement event was recorded or that a re-diagnosis withdrew the decision; read
review_decision_basis to distinguish those cases. It never means declined. The
response basis explains how each named side resolved and discloses a
proof in the opposite direction when no requested pair matched. find_proofs includes
both prove runs and standalone system_diff runs, and labels each pair side as
bound or inferred_from_boundary.
When several pairs match, read data.pair_index first: it names every matched pair with
the estate ids and names, active states, proof_count, and the run of record’s id, hash,
certification verdict, and review standing. data.pairs contains full details for as many
pairs as fit, starting at pair_offset; data.pairs_page reports offset, returned,
total, next_pair_offset, index_offset, and index_returned. Pass a non-null
next_pair_offset as the next call’s pair_offset. For very large results the index itself
is windowed, and index_offset / index_returned identify the entries on that page. Each
page first builds its first pair with earlier proofs; other pairs carry only their run of
record and true proof_count. If that answer leaves room for more pairs and any of them
has earlier proofs, the search builds in full up to the number of pairs that fit, capped at
five.
For a carried approval, review_decision.approval_carried_from on the new comparison
names the comparison and run where the person made the decision, its original author and
time, and the run that carried it here; review_decision.approval_carried_to on the
original comparison names the destination comparison and run. A carry preserves the
original decision and is not a new sign-off. The comparison review read also recovers the
destination from older carry records; see approval_carried_to in the API reference.
The response also includes unattributed_snapshots, which discloses snapshots that
matched more than one unbound estate’s registered scope and were therefore left out of
the asserted proof pairs. Its snapshot_count is the true total, while snapshots lists
at most 20 entries; snapshots_listed reports how many entries were returned. Each
entry includes snapshot_id and claimed_by, whose items identify the competing
estate_id and estate name. A non-zero count is a subtraction from this answer, not
evidence that the migration was never proved: scan the estate you mean so the snapshot
binds to it, then call find_proofs again. When the count is 0, basis reports that
the scope match measured no ambiguity.
Every proof row also carries source_moved_since_approval and
target_moved_since_approval, one block for each endpoint estate. These are a disclosure
beside review_decision, not another approval gate: stands says whether the reviewed
population still accounts for the decision, while these blocks say whether the estate
itself has changed since the reading this approval was recorded against.
When stands is true or false, it is the same revalidated standing reported by the
comparison’s Human Review page at review_url; when it is null, this read could not
resolve the population needed to make that comparison.
count is the number of later readings of that estate boundary whose measured content
DIFFERS from the bound one — compared per object on name, type, row count and digest-tree
root. A reading whose inventory could not be compared at all (its object rows no longer
match the count it sealed) is counted with them: “this could not be compared” is never
reported as “this is the same”. It is deliberately not the number of later readings: a snapshot id hashes the whole
sealed characterization document, scan-time facts included, so a neighbouring comparison
re-scanning an untouched estate writes a new reading that differs in nothing a reader
cares about. readings_since carries that raw number for an audit answer, and
latest_changed_snapshot_id / latest_changed_at name the newest DIFFERING reading.
Each block always includes count, readings_since, basis, approved_snapshot_id,
latest_snapshot_id, latest_at, latest_changed_snapshot_id, and latest_changed_at;
count and readings_since are integers for measured, no_newer_snapshot and
no_content_change, otherwise both are null.
basis is one of measured, no_newer_snapshot, no_content_change,
no_standing_approval, no_snapshot_bound, or approved_snapshot_absent.
no_content_change is a measured zero: the estate WAS read again and every later reading
measured the same content. The last three distinguish an
undecided comparison, a comparison with no bound snapshot, and a bound snapshot that is
no longer retained; they are not reported as zero. For measured, latest_snapshot_id
and latest_at identify the newest reading. The timestamp is normalized to UTC ISO-8601.
A name resolves to a boundary GROUP, not to one estate row: an estate an operator
registered and the estate_bf_… twin the boot backfill minted over the same
dialect:database are one boundary, and proofs bound to either are proofs of the same
pair. Each pair therefore carries source_bound_estate_id and target_bound_estate_id
naming the row its run of record is actually bound to; they equal the pair’s own estate
ids where nothing was folded. Several rows of one boundary resolve with
resolution.basis: ["unambiguous_boundary_group"] and asserted: true — that is not
ambiguity. Several estates registered over one physical database are still several
estates, and the answer still withholds.
Each proof row also carries spec_hash_resolvable and
spec_hash_resolvable_basis; use the Prover run contract
for the basis vocabulary and the pre-contract projection-seal case.
Every proof row in latest_proof and earlier_proofs also carries review_url,
review_url_basis, and review_path. review_url is the absolute Human Review page for
that proof’s comparison, where the reported decision is recorded; it is null when no
usable address is available, and the key is still present. When a public address is
unavailable, it uses the Genesis address the current conversation came from, or this
server’s local dashboard address when there is no conversation address. Use that URL in the
context its basis names; someone reaching Genesis another way may not be able to open a
conversation-addressed link, and a local link opens on the machine running Genesis.
review_path is the same page relative to the Genesis dashboard, present whenever the
row names a comparison; use it when review_url is null. review_url_basis is always
present and has one of these exact values:
addressed: this instance publishes a public base URL and the answer names a comparison, so review_url opens that comparison's Human Review page — where the decision is recorded, and where a person makes oneaddressed_conversation: this deployment publishes no public base URL, so review_url is built on the Genesis page this conversation was sent from — it opens for the person in this conversation; someone who reaches Genesis another way may not be able to open itaddressed_local: this deployment publishes no public base URL and this conversation names no Genesis page it was sent from, so review_url is built on this server's own local address — it opens on the machine running Genesisno_public_base_url: this deployment publishes no externally reachable base URL, this conversation names no Genesis page it was sent from, and this server serves no dashboard on an address of its own, so there is no address a person can be handed. The review page is still reachable same-origin from the dashboard; only an absolute link cannot be built here. An operator who wants absolute links sets FASTAPI_BASE_URL (or the GENESIS_PUBLIC_BASE_URL override, which outranks it) to this instance's external address and restarts; SPCS discovers its own ingress and needs neitherno_comparison: this row names no comparison, so there is nothing to review yet — a proof that has not reached its comparison stage has no diff hash to addressaddress_unreadable: this deployment's public base URL could not be read, so no link could be built — which is NOT the same as this deployment having no public address. The failure is logged at WARNING on the server; the rest of this answer was read normally and stands
read_comparison returns the same three keys beside its always-present review state.
Completed prove and compare answers, their get_run polls, and the run-finished
notice carry these fields too. A null URL does not change the review result; hand over
review_url exactly as returned, with the whole hash, or use review_path exactly as
returned as the dashboard handoff. Use the basis to distinguish no usable address from an
address that could not be read on that call. Building the handoff normally reads the
deployment’s cached public address once; a cold cache can rediscover the ingress through
the database adapter.
The tool asserts pairs only when every named side resolves to exactly one active
boundary — one live estate (unambiguous_active), or several rows of one registered
boundary (unambiguous_boundary_group). If a name matches estates of several different
boundaries, matches an archived estate, or matches nothing,
data.resolution.asserted is false and pairs is empty; this does not mean that
the migration was never proved. Read data.resolution.basis, which can then contain
ambiguous_name, inactive_match, and no_match, and re-run with one registered name
whose candidate has active: true. An archived candidate remains non-asserting even when
named exactly; use list_snapshots, then list_runs, then read_comparison to inspect
its history instead.
For a withholding side, data.resolution.candidates combines direct matches and near
matches, ordered as live estates first, then estates with a decided pair, then most
recently scanned, then registered name. The order is only a reading aid; it never chooses
an estate. Each candidate includes side, estate_id, name, active, pair_count,
decided_pair_count, and last_scanned_at. The list is capped at 10 candidates per
side; candidate_count is the true total. candidate_order_basis contains the same
ordering explanation returned by the tool. The response also includes
source_basis and target_basis, while pairs_returned and
candidate_pairs_considered distinguish the pairs presented from the pairs found for
the resolved estates.
Every returned pair includes source_estate_active and target_estate_active; an
inactive value means that estate is archived and its comparison is stale by construction.
Every pair also discloses source_estate_kind, target_estate_kind, provenance, and
provenance_basis. Branch on provenance, not kind alone: synthetic marks a utility
or drill-clone estate, a synthetic-flagged estate, or a curated adversarial target whose
defects were planted for a rehearsal. Synthetic pairs are exercises, not proofs of record.
When name resolution withholds an answer, the response uses proof_count: null rather
than 0; candidate_pairs_considered still says how many proved pairs were found.
read_comparison always includes review, even when no optional findings or families
are requested. Use it as the comparison’s folded review state: it reports the standing
verdict (awaiting_review, approved, or approved_with_exceptions), reviewer
identity and time, and the run and population coordinates attached to the decision.
Read this field before treating comparison counts as sign-off; a clean count is not an
approval.
When findings is requested, read each row’s settlement.settled and
settlement_basis rather than its observation fields alone; the complete row and
summary contract, including settlement_counts and settled_at_run, is documented in
the estate API reference.
Finding rows may also include family_signature_shape: persisted means the
systemic-family coordinates came from the stored finding row, while computed means
the service derived them from the evidence document during this read. When clustered
families are requested, their signature_shape is persisted only if every member
was placed from stored coordinates; otherwise it is computed. This lets an agent
distinguish a normal current read from a store still being brought up to date without
changing the family grouping or requiring a setting. New finding writes persist the
coordinates; existing rows are backfilled automatically at startup, and rows not yet
backfilled remain correct because the service derives them from evidence for that read.
The backfill’s batched write strategy is described in How a Run Works.
Each search performs about a dozen deployment-wide reads. Pair paging adds no separate
read, but each page starts with a search that builds only its first pair with earlier proofs;
all other pairs carry only their run of record. If the response leaves room for more pairs
and any later pair has earlier proofs, the tool repeats the whole search to build in full
up to the number of pairs that fit, capped at five. That second search builds the first pair
again, and details for pairs that still do not fit may be built and left out. A page with
only one pair, or whose other pairs each have one proof, needs just one search. Each search
fits the response with one serialization and, if needed, a bisection for each list that
must be shortened. The tool is read-only and does not start a comparison.
Example:
read_snapshot
Use read_snapshot to answer a row-count question from what a scan measured — how many rows
a table held, which tables a scan found — instead of counting against the live
connection. The counts are as of that scan.
Returns
snapshot_id, dialect, database, object_count, and objects: one entry per
measured object with object_name, qn, object_type, row_count (null when the scan
could not count it), and digest_root. An unknown snapshot, or one outside your estates,
is refused with kind: "not_found". The tool reads the snapshot’s identity row, its object
rows, and your estate scope; it never loads the characterization document, which the HTTP
detail route decodes in full.
Example:
list_runs
Use list_runs to discover what the Prover has already run — especially after a bounded
wait expires, when starting the same work again could create a duplicate. Results are
newest first and contain slim run rows: identity, type, status, liveness timestamps,
and summary scalars such as counts, verdicts, and hashes. The per-run evidence blob is
not included; use get_run for one run’s full detail or read_comparison for a
comparison’s result. For Databricks spec-drill admission and kept-lease summary details,
see the spec-drill API reference. Runs started in
another conversation that is hidden or that you may
not open remain listed with only run_id, run_type, status, started_at,
finished_at, and heartbeat_at; contents_withheld is true, same_conversation is
false, and conversation_note explains why. get_run refuses those runs with
kind: "not_found" instead of returning their contents. For each distinct other
conversation represented on the page, visibility adds an in-memory hidden-flag lookup
and, when it is not hidden, one thread-access check (up to two RBAC permission queries).
The caller’s estate visibility also filters runs bound to estates, connections,
comparisons, or boundaries they cannot see: those rows are omitted entirely, and are not
included in the page or runs_without_estate count. This adds one run-visibility scope
load for the instance, including a distinct read of run connections and boundary
snapshot/connection indexes. get_run answers a hidden bound run with
kind: "not_found", just like an unknown id; see Prover result
visibility for the shared rule.
For new runs submitted by characterize_estate, grade, or author_spec, the submitting
conversation is recorded even when notify=false; notify controls the terminal wake,
not this visibility check.
In SQLAlchemy metadata mode, store setup for run listing is automatic; see Prover run
listing.
shape defaults to card rather than to the listing route’s full, because a full
page measured 262,333 B for 18 rows with a single row at 156,766 B and nothing about
“what has been run” needs the evidence documents. Ask for full only when you will read
them; one run’s detail is cheaper through get_run. Every row names its own shape on
summary_shape, so “this run recorded no canvas” stays distinguishable from “this shape
did not fetch the canvas”.
The response always includes has_more and next_cursor. has_more: true means older
runs exist beyond the returned page; pass next_cursor to continue, and do not report a
run as absent just because it is outside the newest page. Rows can include
stimulus_evidence: true when the system minted the run as evidence, such as a
system_diff produced by a stimulus beat. This is classification, not a filter; the
tool has no status filter. The tool performs two database reads: the bounded run ledger
and the stimulus differential index, plus one batched compiled-spec lookup when returned
rows cite a spec_hash, and one COUNT of the runs without either a submitting or target
estate when estate_id is given. Each row carries spec_hash_resolvable and
spec_hash_resolvable_basis; use them to filter out grades whose named spec is no
longer available from this instance.
For spec_conformance rows, the summary also retains scope: a compact list with one
entry per scoped object, containing object, expectation, and status.
For the unconfirmed-item count retained in card-shaped grade rows, see the runs API
contract.
Example:
progress block and next_step sentence. For a
seat-backed run, compare progress.last_activity or its counters across calls rather
than treating phase: "working" as proof of current liveness; the shared field semantics
are in Prover run progress.
Short hashes
diff_hash, finding_key, and spec_hash are 64-character lowercase SHA-256 digests.
The read tools read_comparison, read_finding, read_spec, read_proposal, and
export_comparison accept an unambiguous prefix of at least 8 characters. An ambiguous
prefix refuses with candidates, a prefix shorter than 8 is invalid, and a well-formed
prefix naming nothing returns the tool’s normal not-found result. Write tools and
find_proofs still require the full hash.
Prefixes in comparison and finding hash spaces resolve only against records visible to
the person the agent is working for. Hidden matches are removed before candidates are
counted or named: a prefix matching only hidden records behaves like a prefix matching
nothing, and an ambiguous response lists only visible candidates. If more than 1,000
records match before visibility is applied, the prefix is refused without listing or
counting matches; provide more hash characters.
read_comparison
Read a finished comparison by the diff_hash from a proof or compare run. The
comparison itself is always returned; request findings, families, the recent
comparison-event events feed, or comparison grades through include only when you
need those extra payloads, because each one performs its own read.
When include requests families, the rollup uses only findings visible to the person
the agent is working for; see Prover result visibility.
When include requests findings, a duplicated-load finding may include bounded repeated
key examples in relied_on.sample_keys. The examples are illustrative; the counts decide
the finding. See the Prover comparison guide
for the limits and when they are read.
The response also carries the same presented comparison card returned by prove,
compare, and get_run; it is built from this comparison and replaces an earlier card
for the same comparison in chat. When this comparison was commissioned by a proof,
presented.proof_run_id names that proof run so chat can join the comparison to the
proof’s running card. Resolving this field costs one indexed run-row read.
When present, presented.spec_grade includes the grade’s blockers and
blockers_total; on a paired comparison, accounting.outside_scope and
accounting.outside_scope_total carry the spec-scope disclosure. Each list is capped at
five entries, with its total preserving the full count. See the review-population API
contract
for the grade’s accounting fields and [comparison cards in chat]
(/docs/Genesis-Prover/Agents-And-The-API#comparison-cards-in-chat) for how to interpret it.
When a grade covers only selected checks, presented.spec_grade also carries
spec_seal_state: "subset", graded_check_ids, and spec_check_count; these fields name
the graded checks and total spec check count. See [the Prover card guidance]
(/docs/Genesis-Prover/Agents-And-The-API#comparison-cards-in-chat) for how the card presents
this grade.
Resolving presented.spec_grade costs two indexed reads. When the tables paired, it also
costs a bounded indexed join of this comparison’s population runs (at most 129 run rows,
with their summaries) and a read of in-flight spec proofs. When the tables paired none,
it instead scans the uncapped spec_conformance and spec_drill run feeds and reads the
documents of runs grading this comparison, plus the in-flight proofs. The paired path is
bounded by this comparison’s population; the no-pair path grows with deployment grading
history.
The data.review.person_acceptance and presented.person_acceptance fields carry the
reviewed outcome; see the comparison review API contract
and comparison-card guidance
for their meaning and response shape. Resolving them folds the review log; when a verified
person’s exception stands on the comparison it may also resolve the population, whether or
not a run decision exists, and only when the outcome otherwise stands does it scan the
uncapped stimulus run feed and fold the scoped finding ledger. The
detailed review item list also reads the complete population and its findings ledger.
data.review.decision_approval_basis identifies the basis for the current run-level
verdict and, for an agent decision, the person, agent, conversation, goal, and server-known
turn context. It is null when no verdict stands or when the record predates this field;
see the comparison review API contract
for its structured fields.
data.review.nothing_to_decide is true when the comparison reads Verified and no
person has reset its run decision; otherwise it is false. This applies to scope too
when its card has a measurable errored count; an unknown count is not an all-clear. A true
value means nothing is left for anyone to decide, even when data.review.decision is
awaiting_review: a run decision is optional and does not make a comparison Verified.
Report Verified without asking for a sign-off or staging a package. When it is false,
the grade blockers and open differences identify what remains.
With include=["findings"], data.findings.person_acceptance carries the same outcome
without its item list, and each finding row carries person_accepted. A true row means
the person accepted that finding and the comparison reads Verified; report it as
accepted even when its machine state remains still_open (the difference is still
observed). When person_acceptance is null, every row’s person_accepted is false.
The finding_keys shape does not carry either field.
Platform-type, unique-index, rewritten-view, source-built-output, and value-proven
TIME-as-text assumptions may appear in comparison.assumptions; see Genesis Prover’s
assumption rules
and the comparison behavior.
Comparisons produced with float tolerance also include summary.float_tolerance, keyed
by object.column, with elements and max_relative_difference for each entry. Read
the Prover comparison guide
for the tolerance rule and when the comparison performs live value reads. The comparison
summary also records float_tolerance_read and time_text_read: requested columns, how
many were read on both sides, and the cause and reason for each unread side. The same
float_tolerance_read block is projected at summary.comparison_counts.float_tolerance_read
when run counts are returned; older comparisons without that block report null.
For the summary.undeclared_target_shape guidance and withheld-reading fields returned
by read_comparison, see the review population API contract.
When the guidance describes a pair with no one-to-one correspondence, use its unpaired,
observation, and target_model_example fields as instructions to declare the mapping;
shared columns are observations, not an inferred mapping. If the response has
nothing_compared: true and no verified spec_grade, do not present the comparison as
approvable. Follow the refusal’s
next: declare the mapping and reseal the spec, re-prove with a schema_map when the
comparison matched zero objects, or run the comparison again when no matched count is
recorded for it. If a reshaped build’s spec_grade is not verified, the refusal instead
names its blockers and directs the agent to read_comparison before fixing the build or
spec and grading it again.
Whether a specification was graded is a comparison-level question: the proof’s run names
only the specification it ran under, and another grade may have been submitted against the
same comparison later. Request include=["grades"] before saying whether a spec was
attached or what a grade found. data.grades lists each viable grade, newest submission
first, with its run_id, run_type, status, submitted_at, finished_at,
shown_on_review, specification_attached, spec_name, spec_hash, sealed_at,
submitted_by (principal, operator, surface), outcome, outcome_headline,
obligations, and accounted_for. shown_on_review: true identifies the grade the review
page opens. Running grades are included; crashed grades and finished grades without a view
are not viable and are omitted. A grade’s outcome describes its checks, not whether the
comparison matched any tables: when data.comparison.matched_count is 0, report both the
zero-match comparison and the grade’s own outcome. Grades started in a conversation the
reader cannot open are listed with contents_withheld: true; report only that such a grade
exists. An empty grades list means no viable grade was recorded.
When presented.spec_grade.open_clauses is greater than zero, use the grade run’s
summary.open_clauses for each clause’s reason, remedy and evidence. Follow the Prover
partial-seal reporting and remedy rules
when presenting or acting on those clauses.
This include is opt-in because it costs the uncapped grading-run feed scan: two slim feed
reads, the stimulus-feed harvest, and one batched read of surviving grade documents, plus
per distinct other conversation a hidden-flag lookup and at most one thread-access check.
For a declared-target zero count, use the Prover mapping guidance.
When read_comparison returns withheld_unlicensed or withheld_indeterminate, follow the
Prover comparison-card guidance
for presenting each withheld count beside its published headline and deciding what to do
next.
When data.comparison.unwitnessed_by_identity.sentence is present, relay it rather than
describing findings without witness rows as an evidence gap; see the Prover comparison
guide. Included finding rows
also carry rests_on_reopened_seal; follow the API field guidance
when interpreting that notice.
The completed comparison may include summary.unaccounted_sources; follow its
next_step before presenting table-level missing readings.
If summary.unassessed_sources appears, follow its statement; see the Prover mapping
guide.
The review population’s comparisons_matched field records the engine’s matched count when
one was recorded; use 0 to choose schema_map re-proving and null to choose a comparison
re-run, while a pair with no one-to-one correspondence needs a declared mapping.
Every response also carries
data.populations, which keeps the two comparison
populations separate. data.populations.elements.total is the whole recorded
outcome denominator (match + licensed + unlicensed + indeterminate + errored_reads);
differing_or_indeterminate and its legacy alias decided are the narrower
licensed + unlicensed + indeterminate subtotal. data.populations.findings.total
is the separately scoped durable-ledger count when this call read findings, and is
null when it did not. Do not add the two totals or call either one “the differences”
without naming its population; data.populations.why_they_differ explains the scopes.
Counts that this response did not measure are null, not zero. The block is projected
without another query, so reading it adds no I/O cost.
The completed comparison also carries data.comparison.object_presence and
data.comparison.not_measured. Use object_presence to say which source objects the
target holds, including exact counts and bounded lists of missing, undetermined,
absent_as_declared, present, and surplus objects; its not_built list separately names
missing derived targets. Use not_measured to report every indeterminate or errored reading
and its cause. Both blocks are null for comparisons recorded before these disclosures
existed. Do not infer presence from a table list or treat an omitted reading as a clean
result; see the [comparison API contract]
(/docs/Genesis-API/API-Reference#get-api-estate-comparisons-diff-hash-review-population)
for the field shapes and bounds.
read_comparison returns the completed comparison’s run context alongside its populations;
see the comparison API contract
and the Prover comparison guide
when presenting those additional fields. For the new endpoint-estate detail fields, see
the comparison detail API contract.
Full-shape tool answers prepend a bounded data.which_proof_applies summary ahead of the
comparison payload. It groups rewritten views by kind with counts, a shared sentence, up to
five named examples with their reasons (and, for a view whose proof run is named, its
test_case_coverage sentence), and a count of omitted views. same_text_views and
its shared reason cover unchanged definitions; next_view points to the view for the next
step. full_list locates every per-view record at
comparison.which_proof_applies.views; use it if the sample misses the view you need.
Scope reads omit this summary because they do not read views. See the [API field contract]
(/docs/Genesis-API/API-Reference#get-api-estate-system-diffs-diff_hash) for its exact shape
and Prover guidance
for what to do next.
When include names families or finding_keys, the requested rollup is the shape of
the whole comparison, so the tool reads it at comparison_shape="scope" by default.
Do not combine that rollup with comparison_shape="full" or verdict: those options
need the element document and are refused because the rollup and its elements are two
reads. Read the rollup first, then make a separate full, optionally verdict-filtered
call for the elements. Every response also carries data.comparison.value_coverage,
which says how many column values and whole-table checksums were compared, how many were
not, and why; a null block means the comparison predates this disclosure and is
unknown, not proof that all values were compared. See the [Prover comparison guide]
(/docs/Genesis-Prover/Overview#2-comparison-the-system-diff) for its counting basis.
When value_coverage.recharacterize is present, its readings count identifies refused
value readings that can become comparable after re-characterizing the snapshots named in
recharacterize.snapshots for the sides listed in recharacterize.estates, then
comparing again. recharacterize.build_version is the library version whose recipe the
new snapshots must share. When recharacterize.cause is
instrument_version_mismatch, every value reading in the pair was withheld because the
two snapshots were measured by different known library versions: name the snapshot ids
in recharacterize.snapshots for the sides in recharacterize.estates,
re-characterize those estates, and compare again. If the cause is
digest_family_mismatch, only the readings counted in the block can be repaired by that
re-scan; any remaining readings stay not_compared. When recharacterize is null for
instrument_version_mismatch, a side’s measurement library version was not recorded, so
the comparison cannot identify which side is stale; its affected element reads
unknown for that side’s source_value or target_value, and the user may
re-characterize that snapshot before comparing again.
When data.comparison.not_measured.by_cause contains
observation_skew_append_only, observation_skew_mutable, or wall_clock_dependent,
read_comparison also returns data.timing_rescan_evidence. Its timing_causes gives the
matching cause counts, and sides.source and sides.target each report the later-reading
evidence for that estate. Read the side’s basis and quote its statement; this evidence
does not change the comparison’s recorded verdict. unchanged_on_rescan means the compared
and later readings have the same content fingerprint and every abstaining object was measured
and equal on both. unchanged_fingerprint_only means the fingerprints match but the abstaining
objects were not all checked or located, so their equality is not established.
abstaining_objects_unchanged means the estate changed elsewhere while every abstaining
object was checked and held the same row count and digest; others names those other changes.
listed_abstaining_objects_unchanged makes that claim only for the listed abstaining objects
when the comparison’s listing was truncated. changed_on_rescan means the content changed;
not_comparable means a fingerprint is missing or differing fingerprints cannot be compared
across different or unrecorded measurement-library versions. no_later_reading means the
compared reading is still the newest; compared_snapshot_unplaced means the compared snapshot
cannot be found or placed on the timeline. The statement names both snapshot ids and seal
times when a later reading is available. Equal readings show no net change between those
readings, cannot rule out a reload or revert in between, and never establish a verdict. If
sides is null, unreadable gives the reason and no conclusion is established.
For large answers, data serializes timing_rescan_evidence, review, populations,
comparison_shape, and the review links before comparison; comparison.payload is last
within the comparison, followed by other returned fields such as requested projections. A
truncated preview keeps the serialized head, so check it for the decision evidence before
reading the spilled output. This ordering prioritizes those fields but does not guarantee
they all fit when the leading blocks themselves are too large.
Placement follows the compared snapshot’s estate, not its observation boundary: a later scan
of the same estate can be used even when the estate’s scope or contract changed between scans.
placed_by is estate when scan events bind the compared snapshot to an estate, and boundary
when no estate owns it and its boundary is the only identity available. cross_boundary is true
when the compared and later readings have different boundaries. In that case, a fingerprint
difference alone does not establish a content change: rely on the abstaining objects checked
one by one. A moved abstaining object supports changed_on_rescan; unchanged row counts and
digests for every abstaining object support an unchanged result. If those checks do not decide
the abstentions, the result is not_comparable. Objects present on only one side of a
cross-boundary whole-inventory comparison are described as scope changes, not content changes.
For the target side, abstaining_objects names target objects: it uses each element’s
target_object, then the comparison’s recorded pairing, and falls back to the source name when
neither supplies a target name.
This evidence is read automatically. With timing abstentions, it looks up each snapshot’s
owning estate and, when bound, that estate’s scanned snapshot ids; it also reads both estates’
snapshot timelines. If a target object name is absent from the comparison elements and its
payload is not already available, it reads the recorded object pairing. For each side with a
later reading it reads the two measurement-library versions; when abstaining objects are
listed, it also reads both snapshots’ object rows. If it does not settle the abstention, use
list_snapshots to find same-side snapshots sealed before and after the comparison’s two
reads, then use read_snapshot to compare the disputed objects’ row_count and digest_root.
Equal readings show no net change across the gap, but cannot rule out a reload or an update and
revert in between; report that conclusion as an inference, not as an engine finding. A null
reading is not evidence.
Change stamps can add evidence when their latest value predates both reads, but this only rules
out a stamped write on the source: a target stamp is usually copied from the source, and a hard
delete does not update one. Label values queried outside the recorded comparison as your own
readings. For wall_clock_dependent, only the same-side snapshot check applies to change
stamps. If the record does not settle the abstention, offer or run a narrowed re-scan of only
the disputed objects.
Compare each side’s past scan duration first; starting both scans together does not mean they
read at the same time. Re-scan each side with characterize(connection_ref=…, dialect=…, database=…, objects=[…]), adding role="target" on the target, and prove the returned snapshot
ids. These snapshots are not bound to an estate and will not appear in list_snapshots later.
Keep the comparison’s verdict as indeterminate; state separately which evidence supports or
rules out timing as the cause.
See the Estate API reference
for comparison engine provenance and retired-engine response behavior.
Request include=["license_audit"] when you need the stored evidence behind a licensing
explanation, an audit trail, or the question of what licensed a difference. This bounded
projection selects comparison_shape="audit", returns data.license_audit without
individual element payloads, and includes exact verdict totals, bounded comparison rows,
an aggregate remainder that preserves reconciliation, licensed provenance attributions,
and the used correspondence-rule ids. It must be requested alone. Check its coverage
and truncated fields before treating variable collections as complete, quote raw
provenance labels exactly, and read each returned rule dossier separately with
read_correspondence_rule rather than inferring a rule name or meaning from a label. See
the Estate API reference for the dossier’s sign-off
route and bundle-hold fields.
When include contains families, the rollup is scoped to the comparison’s own estate
pair—the two estates it compares—not only to their engine corridor. The response includes
data.families_scope with component_pair, pair_fingerprint, and status, so the
population is explicit. component_pair identifies the shared engine corridor, while
pair_fingerprint identifies the concrete estate pair whose comparisons contributed to
the families. If the comparison or its snapshots cannot resolve that estate pair, the
tool refuses instead of returning families from every migration on the same corridor.
comparison_shape is how a caller paging findings declines the element document. The
comparison does not change between pages, and the default re-sends all of it on every one:
86,682 B per call on a 177-finding comparison, 1.56 MB across the eighteen pages it takes
at limit=10. Read the comparison once at full if you need the element tallies, then
page at scope. data.comparison_shape names the shape on every response.
include=["finding_keys"] returns the same population as findings projected to
finding_key, event_role, object_name, column_name, and last_seen_diff — what
propose reads, without each row’s decoded evidence and disposition trail. Use it when
you are enumerating a comparison in order to disposition it. The limit is an upper
bound: the tool fits the keys page to tools.output_governor.inline_budget_bytes after
assembling the whole answer, including the comparison, populations, presented, and
pagination metadata. The response rewrites returned and next_offset to describe the
keys actually delivered; continue with next_offset, never by adding limit to offset,
until it is null. The page targets at least one key; if the complete answer still exceeds
the budget, delivery may shorten other lists while keeping the keys metadata honest.
settlement_basis and family_signature narrow the comparison before the page is cut, so
they filter the population rather than the page. settlement_counts continues to report
the whole comparison’s split beside a filtered page, so every count arrives with its
denominator.
Element details may carry cause="not_compared_by_design" or
cause="derived_target_not_compared" for these skipped digest readings; see declared
target mappings
for their approval meaning.
Only match means checked and equal. indeterminate means the comparison reached
the data but could not determine the result; errored means the read itself failed
before producing a measurement. Both are UNMEASURED, never clean. Count them as
unresolved rather than folding either into a match total. An invalid verdict is
refused instead of silently returning an empty payload.
source_contract_tools
Use source_contract_tools for source-contract mining, jitter qualification,
and deviation triage; it also exposes design_stimulus_campaign for those
workflows. For a rewritten-view behavior proof, activate
migration_prover_tools instead: it exposes the same design tool alongside
the proof lifecycle tools, without requiring the larger source-contract group.
For comparing estates, grading a spec, or reading a comparison or finding back,
use prover_tools instead. The group includes register_execution_profile for
one source or target estate, preflight_databricks_job_contract for reading the
canonical contract of a deployed Databricks Job, and prepare_migration_prover for the approved,
credential-free contract that validate_migration executes. It also includes
the independent Adjudicator seat for reproduce-first triage of a completed
comparison. Credentials are resolved from connection_ref; never put credentials
in a profile payload.
The stimulus submission tools consume the pair contract resolved for the run. On a
contract-governed pair, submit rows by logical table name and keep each row inside
that table’s declared island; the server maps the logical name to each side’s
physical relation and refuses a row that is missing the declared island column or
below its inclusive floor. A contract-less run uses the disclosed legacy default
instead. The REST preflight and run response describe the resolution, refusal, and
legacy-disclosure fields in the stimulus API reference.
For the administrator-facing permission labels used in tool refusals, see the
RBAC Practical Guide.
list_reconcile_episodes filters the newest limit episodes after fetching them;
limit defaults to 25 and is capped at 200, so raise it before concluding that no
visible episode exists. With the ruling overlay active, list_court_dockets returns an
empty list for an estate the caller cannot see; reading or deciding a docket there uses
the unknown-docket refusal.
Every verb in this group refuses an argument it does not offer by name instead of
silently dropping it. The refusal names the fields in unrecognised_arguments and
confirms that nothing was run; runtime context fields injected by Genesis remain
internal and are not caller arguments.
An exception that escapes a Prover-family verb is returned as a structured
refusal.kind: "fault", not as an unclassified tool error. A fault is an outage,
not a decline: do not report it as a refusal of the request. Follow its next
guidance instead. For tools whose repeat could start the operation twice, next.verb
is null; first read the durable run, status, or list record and retry only when
that read shows that nothing started. Tools that can safely re-read the same act
provide the original verb and caller-supplied identifiers in next.
For machine-checkable predictions, write mart as the contract locus (raw.<logical_name>
for an input or marts.<logical_name> for a derived relation). The checker keeps that
logical locus as the identity used for spec coverage, then renders the declared relation,
column spelling, and key predicate independently for the source and target; a locus that
does not resolve uniquely is not checkable. A physical schema.name spelling is accepted
only when it maps back to one declared locus, so prefer the logical form in authored
specs. Sealed specs also translate side-physical loci through the same contract before
coverage and silence checks; see How a Run Works
for the run-level guarantee.
Cross-run migration history classifies column_element_counts findings—the
number of elements held by an array column differs—as the value phenomenon,
grouping them with other measured-content findings.
The source-contract attribution tools report the author held by each durable row,
not a caller-supplied name. A repeat submission of identical content keeps the
first author, so callers must use attributed_to_another before describing the
result as their own. A missing signed-in user is shown as unattributed; when no
row was registered, or a row names nobody, the verdict is null.
Logic-path coverage claims
Pass the optionalmanifest_path (string, default "") to design_stimulus_campaign
to enumerate coverage points from the dbt manifest’s model SQL. Copy a point’s
claim_tag into the corresponding case’s tags array. In a
run_trajectory_campaign mutant, claimed_coverage is an optional list of strings; each
entry is a point tag in the form coverage:<statement-digest-prefix>:<point-id-prefix>,
or the same two prefixes without coverage:. Both prefixes must be at least 8 characters.
A bare point id or a tag for a different SQL text is reported as stale and credits no
point; re-affirm the claim against the current SQL text. Claims that match no point,
match multiple points, or have an unsupported shape are returned separately rather than
silently credited.
When an OR condition is listed as separate alternatives, design a case for each one. A
filter or output column made wholly of alternatives also needs a case for the outcome when
none holds, claimed with the condition’s own claim_tag; the alternative tags do not claim
that outcome. For how Prover accounts for these claims in a view approval, including CASE
rules shown through their alternatives, see
Approve test cases for a view.
For rewritten-view test cases, design_stimulus_campaign also accepts optional
view_pairs (array of objects, default null). Each pair names original and
rewritten as SCHEMA.VIEW; optionally set original_boundary_hash and
rewritten_boundary_hash when either view was scanned under another boundary. The tool
reads the newest stored snapshot for each boundary, not the live warehouse, and returns
each view’s stored text and a logic outline with a claim_tag for each listed path.
Each pair must provide non-empty original and rewritten strings; malformed pairs are
refused before the design runs. For example:
include_view_text=false (boolean, default true) to omit both text and outlines
while retaining the claims check. At most five pairs are read per call; each side includes
up to 20,000 characters of text and 30,000 characters of outline, with a combined
200,000-character limit for the call. A stored snapshot that still contains a line
comment may have an incomplete outline; the side reports this as a problem. Rescan that
boundary to refresh its stored text, because the current scanner removes line comments
before storing a view definition.
Put the outline’s claim_tag values in the corresponding cases’ tags. To check those
claims without storing the cases, call design_stimulus_campaign with view_pairs,
specs, and check_claims_only=true (boolean, default false). The response reports
credited, stale, unknown, ambiguous, and unrecognised claims with a summary and a fix
suggestion; claims never block a design run or preparation. Check-only requires at least
one pair and otherwise returns an invalid-pairs error. Use this check before passing the
cases to prepare_migration_prover, which stores them itself; do not first store those
cases in a normal design call because they stay bound to that call’s boundary. Pass the same
view_pairs to preparation to get the claims report without the view text or outlines.
Claims are checked for specs whose output_relation names a listed view, or, when it names
no listed view, whose dbt target_node ends with one of the pair’s view names.
specs_matching_no_view_pair counts submitted specs that none of the listed pairs checked.
Attribution fields on source-contract tools
Contract-addressed tools act in the visibility scope of the person the agent is working
for.
get_source_contract, verify_source_contract, run_jitter_campaign,
run_clone_jitter_campaign, export_attestation, and anchor_evidence_ledger answer a
hidden contract exactly as an unknown one (Unknown source contract: <contract_id>);
they check before reading details or starting work. Each check costs one visibility-scope
load beside one contract read. get_jitter_campaign treats a campaign on a hidden
contract as unknown after reading the campaign, while list_estate_deviations returns an
empty list for a hidden contract; each adds one scope load and one contract read.
verify_attestation_signature
Check the signature and content claim of an exported attestation without changing it.
The tool returns its signature verdict and lifecycle status, and re-derives the bundle
when the original snapshot is still stored. It requires a signing key and a signed
attestation; use export_attestation to create the evidence package.
An attestation the person you are working for cannot see is answered as unknown before
verification, just like an id the store does not hold. This check costs one visibility
scope load and one attestation-subject read before verification.
prove
Use prove after both sides have been characterized. It is the agent-facing
entry point for the Prover’s one-trigger flow; the API reference
defines the proof lifecycle and envelope. Omit spec_hash for a comparison-only
run, or provide a sealed hash to include grading in the same proof.
The comparison-only compare tool takes the same required title; grade also
requires one when grading an existing comparison.
When a sealed spec declares a target model, attaching spec_hash makes the comparison
run under that model before grading. If you instead grade a compare result made without
the model, the grade may recompute the pair under the spec; see when a grade names a
comparison made without its spec
for how the recomputation carries the comparison’s column_map and row_identity, and
reports a key that does not pair rows under the model.
For a no-spec prove or compare, change_expectation="must_match" declares a
lift-and-shift premise: a clean comparison is answered with next.verb: "propose"
for a human decision. must_differ records that the target should change but still
leaves the caller to author a specification; see how the Prover handles declared
no-spec shapes.
When a bot calls prove for a user, estate reads use the authenticated user’s
identity for connection access while the bot remains the acting principal. A
personal connection therefore must belong to the submitting user; see the
proof endpoint reference
for the identity distinction.
Retries reuse a proof only for the same acting bot and authenticated user. Repeating
the same estate question from another identity starts a separate proof; it does not
return a result created for the other identity.
See comparison cards in chat
for title handling on reuse.
The tool returns a run handle immediately by default. With notify (the default) the
thread that started the proof is told when it reaches a terminal status — on its next
tool result if it is mid-turn, or as a new turn once idle — with the same handle a poll
would return, so there is nothing to poll; poll
get_run(prover_run_id=run_id) only when you set notify=false. Set wait_seconds to
wait inline before the tool returns; the proof continues in the background if the wait
expires. With spec_hash, either connection id may be omitted; prove resolves available
defaults from the sealed spec’s seat. If the seat record does not supply a needed id, pass
that connection explicitly. When a connection is omitted, default resolution reads the
spec’s provenance and, if it names a thread, looks up that seat run. Attaching a
specification requires the ratify_source_contract permission. A comparison-only proof
requires only the source and target snapshots.
The related compare tool uses the same notify behavior and default. Its terminal
wake carries the comparison’s run handle, and notify=false leaves get_run as the
polling path.
A wake delivered as a new turn goes through the thread’s mailbox, which caps a message
body. When the full handle does not fit, the wake keeps the envelope and every scalar of
its summary and replaces the summary’s nested blocks with summary.omitted_from_wake,
which names the keys left out and the get_run call that returns them. A record that
does not fit even in that form arrives as the notice alone, saying so and naming the
call that reads it; no mailed wake is ever cut by the mailbox. A wake that arrives on a
tool result carries the whole handle.
The proof owns its comparison and grade child runs for notification as well as for the
result: while the proof is still running, a child completion rides the proof’s terminal
wake instead of creating a second thread notice. If the proof has already ended or gone
away, the child can still announce its own terminal state.
Submit-time artifact, field, and connection preconditions—including the terminal
refused response for an unregistered connection—are documented in the proof endpoint
reference.
A graded proof can also be refused before submission when the sealed scope cannot be
paired to the complete snapshot pair. Correct an unresolved scope name and reseal, or
declare the missing schema_map (and an object_map when object names differ); see the
proof endpoint reference.
For the pre-comparison grade_reads_no_comparison refusal when tiers omits
"structural", including its remedy and response fields, see the proof endpoint
reference.
To localize witnesses by a caller-known business key, pass row_identity as a
source-coordinate object map, for example {"PUBLIC.ORDERS": ["ORDER_ID"]}.
Each key position may also be a {"coalesce": ["col_a", "col_b", ...]} term
when the first non-NULL value across those columns is the business key; use the
API reference for the complete grammar and per-side form. See that reference for
concat row-identity terms.
The proof admits the run first; its comparison probes each declared key on both sides.
An unusable key refuses the pair during that comparison rather than returning a
submit-time 400. Omit row_identity to use only the engine-declared basis; see the
proof endpoint reference
for validation and evidence fields.
prove has no separate target_model argument: its behavior comes from the sealed
spec_hash. See Declared Data Vault target shapes
for the comparison rules and the proof API reference
for the sealed-artifact contract. A version-2 model can declare computed derived targets;
the comparison checks their presence and declared columns without comparing their rows to
one source table. A legacy source used only to build a derived target is expected to be
absent under its own name on the target side; see the target-model rules
for the same-name layer exception. If the target is vault-shaped, or objects are unpaired
on both sides, but the sealed spec omitted the model, the run summary instead carries
undeclared_target_shape guidance. Read the guidance, complete the model from the mapping
document, reseal the spec, and run prove again; when nothing paired, the resulting review
population is not approvable.
When comparison_counts.comparisons_matched is the integer 0 (not absent, null, boolean,
or negative), the proof report says that no objects matched before it presents the grade.
The grade may still contain an obligation tally; that tally does not mean values were compared.
For late-completion and terminal-attribution details, use get_run(prover_run_id=run_id)
and read How a Run Works
alongside the run API reference.
The Prover workflow guide
explains how addressing is recorded when proofs are repeated.
Catalog resolution and grade idempotency are defined in the compiled-grade API
reference.
Example:
schema_map and object_map — the mappings above —
not with a declared-relations premise. The prove VERB does not accept one: it refuses an
unrecognised argument by name rather than ignoring it, so a call passing
declared_relations gets refusal.kind: "invalid" and nothing runs. The same is true of
tiers: the verb always grades every gradeable tier, because a tier subset is a different
measurement and narrowing it silently on an agent path is not a default worth having. Both
are properties of the proof ENDPOINT’s request model; see the
proof endpoint reference for them
and for the premise lookup window.
For a cross-engine relocation whose engines spell object names in different
cases, pass case_insensitive_object_names=true as well, or objects whose names
differ only in case pair with nothing and the whole target reads missing.
The response includes run_id, status, the common run envelope, and wait.
The envelope links to get_run; its summary names comparison_run_id and,
when a spec was attached, grade_run_id, and preserves the proof’s
source_snapshot_id and target_snapshot_id. Terminal refused means the system
declined the request (for example, a seal did not verify or a connection was not
registered), not that the run crashed. See the proof endpoint reference
for the full REST request and response contract.
For graded-proof regression fields and the effect of an unmeasured tier, see the
proof endpoint reference and
what certifies.
propose_correspondence_rules
Seed and edge-qualify the default platform-correspondence (Π) rule pack for an
engine pair. A pack is available only for supported pairs; use
propose_rename_correspondence for renamed objects or schemas, and
triage_unlicensed_findings for residuals discovered by a comparison. Seeding and
qualification make the rules eligible but do not ratify or license them. Pass the
characterization snapshot ids when available so qualification is bound to the pair’s
environment.
Use
availability_only=true to find out whether a pair ships a pack: a plain call
seeds the whole pack into the human ratification worklist. The counts are the same ones
GET /api/estate/correspondence-rules/pack-availability returns.
For legacy copies, Genesis also reseeds the pinned pack edition at backend startup; see
Genesis Prover for how that affects the rule worklist.
The response returns the qualified rules and any ratification_url, actionable, and
blocked_by hand-off fields. Each rule includes proposed_by, the author recorded on
its content-addressed row, and the response includes attributed_to_another: true
when any rule names another person, false when all rules name the caller, and null
when a rule names nobody. Re-seeding an existing pack returns its first recorded
authors rather than attributing the rules to the caller; an unnamed author is shown as
"unattributed". The operation writes and qualifies the pack, but takes no extra
author read because the workflow returns the recorded authors with the rules.
grade
Re-grade a new sealed specification against an existing comparison without taking new
estate characterizations. This also covers a migration whose tables were already landed
and compared before anyone wrote down its specification: author and seal the migration’s
requirements, then use grade to measure those obligations against the live estates.
Use it for a repair round when the characterized estate and comparison are unchanged.
Before a comparison exists, you can grade the spec’s obligations alone against the two
live connections with tiers=["derivational"]; this needs no snapshot pair. When you
also need the estates compared and the structural tier graded, use prove(spec_hash=...)
for the first comparison, or re-characterize and prove again after target configuration
changes. See how grading rounds stay
repeatable.
Every grade call also requires title, the business name shown for the comparison in
Human Review and on the Prover landing. As with prove, a missing or blank title is
refused with a suggested value; the prove parameter table describes its format.
When the sealed spec declares a target model but the named comparison was made without
it, this tool compares the pair again under the model before grading and records that
replacement in the run provenance; the operation therefore performs a second full
comparison. It carries the comparison’s recorded row_identity_declared; a key that
does not pair rows under the model is reported as indeterminate, not guessed. See when a
grade names a comparison made without its spec
for the reason recorded on the grade and the rule that controls whether the replacement
comparison inherits its title.
If a failing grade read no comparison, follow its returned next call: it points to
prove for a single spec or to a SET re-grade with spec_hashes and the structural tier;
see how the Prover routes comparison-less grade failures.
Omit source_connection_id and target_connection_id to use the source and target
connections resolved from the seals when every member agrees. For a reseal with no recorded
connection, resolution follows its parent seals to the nearest recorded connection; see the
load_prior_spec repair binding rules. If a seal still does not resolve
a connection, provide its registered connection explicitly. A named source that differs from
a member’s sealed source is refused; a named target is refused only when that member’s seat recorded a
commissioned target connection. A target inferred from catalog placement on the source is
not a recorded target, so it does not prevent grading a migration on another connection.
If a set’s seals record different connections, no single call can grade all its members;
grade each separately with spec_hash on its own sealed connections. The refusal names
the conflicting connections and directs you to the applicable retry. For a single
connection mismatch, the proposed grade call preserves the other non-default grade
arguments you supplied and substitutes the seal-recorded connection; use it rather than
rebuilding the request.
The tool claims the round and returns a run handle immediately. Poll
get_run(prover_run_id=run_id) until the status is terminal, or set wait_seconds to
wait inline first. An expired wait never stops the grade. While the grade is running,
data includes request_key, tiers_graded, and pending_basis, but does not include
findings or obligations because those results do not exist until measurement finishes.
Read the verdict summary, obligation results, and durable #N finding ids from the
finished run. An identical finished request returns its complete verdict with
data.reused: true; a round already in progress is refused with kind: "conflict".
The request identity includes the running grading-code version, so repeating a request
after the grader changes grades it again instead of returning the retired grader’s
verdict. On a reused response, data.reused_from_grade_version identifies the grading
code recorded by the run that supplied the answer; it is null when the grade ran or
the reused run recorded no version.
If the seal cites a retired clarification (overturned by a person or withdrawn by its
recording agent), the tool refuses admission; see how a run handles reopened
seals for the
required reseal path.
When an unlicensed obligation fails, the completed verdict also carries
failed_checks, with the obligation id, available mismatch and row counts, up to three
sample keys, and a rendered sentence. For a failure over a column missing from the
target, the entry instead has a null mismatched_key_count, plus
missing_target_columns and unchecked_source_rows; see how failed checks are
surfaced
for how that unlocalized failure is reported.
The overview also explains how a membership difference with keys on both sides is
worded and when its examples identify the side for each key.
For a keyed obligation left unmeasured because its key is duplicated only on the target,
the grade records a decided fail rather than unverified. It does not make that
conversion when the degeneracy probe measured the expected side empty; an empty expected
population has no key to duplicate. For how refused key comparisons are sized in the
failed-check headline, see failed checks in the grade overview.
For how report_this points to failures beyond its named-check limit, see
reporting a completed run.
The Prover turns the same failures into Human Review blockers. If the grade read no
comparison, those blockers appear on the grade’s own proofless review; that review can
take rulings and exceptions but cannot be approved. Use its returned next call to
run prove or the required SET re-grade so a comparison-backed review can be approved.
For a finished grade that read no comparison, both the grade result and a get_run
poll carry data.review_url, data.review_url_basis, and data.review_path for that
grade’s review, with review_path present in every case. review_url_basis begins with
addressed_grade when the deployment’s public address is available; it can also begin with
addressed_conversation or addressed_local when a fallback address is used. If neither
fallback is available, it begins with no_public_base_url or address_unreadable; use
review_path to open the page in the Genesis dashboard when review_url is null. The
basis values are described above.
Use the grade response reference
for returned fork fields.
For the declared coordinate on conformance drift findings, see Drift findings declare
their coordinate.
When this production grade becomes the comparison’s review over a previously approved
review population, the finished response includes data.approval_superseded. It names
the recorded decision, approver, approval run, superseding grade run, and a sentence that
the approval no longer binds and the comparison is awaiting review again. A null value
means this grade superseded no approval. The same disclosure is promoted on the run
envelope and review surfaces; see when a re-grade changes approval truth.
A finished grade returns not_compared_by_design, derived_checked,
derived_unchecked, derived_unchecked_reasons, and row_checked alongside its verdict counts.
row_checked names same scope objects verified by passing row checks because their
whole-table digest cannot be compared across engines; the grade headline says they were
verified by row checks, not by digest.
The first is the number of design-skipped split-image digests; the two lists identify
derived targets whose skipped digest is cleared by sealed coverage or remains in the
blocking indeterminate results, respectively. A covering check that passes but measures
degenerate expected-side data (empty, all-NULL, or all-zero) confirms nothing, but does
not undo confirmation from another passing, non-degenerate check. A failed or unverified
covering check prevents confirmation. derived_unchecked_reasons maps each unchecked
target read by a check to the reason: a covering check did not pass, or its only covering
checks passed but measured degenerate. Targets with no covering check have no reason entry.
See declared target mappings
for the comparison rule. The report_this line also counts derived_checked tables as not
compared cell by cell; see reporting a completed run.
The grade summary also returns scope_unaccounted_columns, scope_unaccounted_limits, and
scope_unaccounted_readings; the first names new target columns awaiting a person’s
decision, the second discloses limits on the source columns used to make that reading, and
the third lists the exact unlicensed readings held for that decision.
See [scope verdicts]
(/docs/Genesis-Prover/Agents-And-The-API#scope-verdicts) for how these affect the grade and
Human Review.
When a carried scope entry is unpaired for want of a schema_map, the summary’s
schema_map_unpaired block groups the source and target objects attributed to that cause;
the grade and review population state the missing map once rather than counting each entry
and target object again. See [scope verdicts]
(/docs/Genesis-Prover/Agents-And-The-API#scope-verdicts) for the fields and grading semantics.
For the grade’s explicit distinction between failed and unmeasured items, and the
nullable derived-split fields, see the grade response reference.
For how the grade treats target objects outside the declared scope, see
scope verdicts.
A finished grade, including one returned by prove with a spec, can also end a check as
nothing_to_check, rendered Nothing to check (0 rows). Report it as a measured empty
population, not a pass, failure, error, or skipped check; use the grade headline to say
whether the other checks verify the claim. See how a grade reports an empty check.
For example, grade obligations before a comparison exists:
check_ids to grade; the API reference
defines the partial-result contract and refusal conditions.
summary.obligation_counts,
including on a derivational-only grade. Its top-level items are structural spec items,
not the obligations measured, so an empty list does not mean the grade checked nothing;
see the grade response reference
for the count fields and obligation-record paths.
If a declared key is read but rejected as non-unique, inspect the refusal’s remedial
arguments before dropping it. A different usable form may add columns that distinguish
repeated rows, use a first-non-NULL key such as
{"coalesce": ["adjusted_number", "original_number"]}, or declare different key
columns for each side with {"source": [<key terms>], "target": [<key terms>]}.
The backward comparison re-keys those per-side probes to its own source and target
roles; flat keys remain unchanged.
Example:
ratify_source_contract. The minutes of warehouse work run behind
the handle whether or not anyone continues polling.
Finished grades expose the structural and live-read intervals plus vintage_basis,
and on a blended grade vintage_between_reads, which says whether either estate’s
write history shows a write between the two reads. Relay the envelope’s vintage_caveat
beside the verdict; its wording and the limits of not_confirmable are described in
how a run reports observation vintage
and the grade response reference
for how to interpret them. For a set grade, every member’s obligations run, the response
returns the set identity in spec_hash plus sorted spec_hashes, and the completed run
view carries spec_set ownership, overlaps, and conflicts. When the structural tier was
graded, data.summary.spec_set_reading also relays those members, their seals, conflicts,
overlaps, and uncovered differences in the review card’s wording; see the API response
reference
for its fields.
Adjudication proceedings use the packaged constitution only when its content
matches the build’s integrity pin. For the current v4 constitution, the
expected SHA-256 is
7464dc71d2c0d65f8c6abbcde42b6dc2eba4d241cea415afe76776d0f98763fc. A digest
mismatch raises ConstitutionPinError and fails closed before the proceeding is
opened, rather than recording an unverified constitution as provenance. Open
proceedings continue to resolve the immutable constitution version and digest
recorded when they started, even after a newer constitution is pinned.
request_consult_ruling
Ask the built-in Prover Consult agent to measure one reason not to fix an open
finding rather than arguing about it. The caller supplies the finding number, one
dispute shape, and the implementer’s position; Consult hydrates the finding’s
rationale, compiled readings, computed values, check SQL, two databases, and ticket
from the ledger. The tool is available to agents carrying source_contract_tools.
Consult returns ACCEPTED_SUPPORTING, REJECTED, ESCALATE, or
INVALID_DOCKET, together with its read-only probes and any mechanical guard. It
uses one full bot turn and read-only SELECT probes, so call it deliberately and
only once per dispute at a time. A second call on the same finding is an appeal;
the service continues the same thread and allows at most three rounds for the same
measurement. This tool opens no review item and does not itself close or license the
finding. For an ACCEPTED_SUPPORTING ruling, a person asks for approval from the finding;
the decision is made through Action Review. See Prover roles and approvals
for which rulings use that route and what approval changes. The decision must use the
ruling’s exact ruling_digest_id, so a ruling made obsolete by a later Consult round
cannot be applied accidentally.
Consult performs the provider readiness check before creating its thread, so a
provider failure spends no round; follow the returned cause and remedy rather
than retrying in a loop. The check uses the shared
llm.provider_preflight_ttl_seconds
window.
When a finding is one leg of a declared fork, the docket includes the fork axis and
the compiled readings for that axis. If the same leg’s grade changes between the
earliest and latest graded sightings while the finding remains open, the docket marks
the axis as moved and lists the direction of each measured change. In that case no
probe against the current build can establish which reading the ticket requires: the
build now embodies one of the readings, so re-running either leg only reproduces its
current state. An ACCEPTED_SUPPORTING ruling is therefore escalated rather than
licensed, with the implementer’s values standing for human review. The docket tells
the agent to use the ticket wording to identify the required reading, or record a
specification flag when the ticket does not decide the fork.
The response includes
rounds_remaining, the number of consult rounds the same
finding revision can still use. It reflects the durable ruling history rather than
the returned round_number: INVALID_DOCKET and an ACCEPTED_SUPPORTING result
without a valid probe do not spend a round. If the finding changes, is resolved, or
cannot be read while Consult is working, the ruling is returned but not recorded
against that obsolete revision; rounds_remaining then describes the current
revision (or is null when its budget cannot be read).
Example:
estate_char.consult.apply_mode configuration, and the Estate
API reference for the
read, approve, and decline endpoints.
Builder-facing fix brief
Each reconciliation round renders a builder-facing fix brief from the product’s episode records. It includes the ticket text, open findings with their rationale, readings, evidence, computed expected-versus-stored values, and the source/target SQL behind the check when available. It also includes perimeter questions for estate changes that are not claimed by the ticket. The brief keeps operator-provided ticket text and product-generated finding fields verbatim, including ordinary words such asscore or score-bearing column names;
those inputs are not oracle disclosures. Verdict language composed by the gate is
still refused, and the refusal identifies the bounded offending line so the source
can be repaired without guessing which finding triggered it.
When an item comes from one leg of a fork, the brief labels it as a fork leg instead
of presenting that reading as a settled expected value. It shows the fork axis, the
reading bound to the item, and every other compiled reading for the same sentence
with that check’s recorded standing: satisfied, not satisfied, or not measured. This
context is included so a builder does not change a check that currently satisfies a
rival reading without knowing that the specification has not settled the choice.
For a finding whose record carries several readings but cannot identify its bound
leg, the source SQL is likewise described as the result of one reading rather than
as the expected value.
For persisted conformance re-grades, an issue is closed by absence only when the
round’s tiers_graded coverage includes its category: structural covers both
structural and drift, while derivational covers derivational. Issues in
ungraded categories remain open for a later round; see the episode rounds API
reference.
Findings are grouped by their recorded state. open findings ask the builder to
make a change; findings closed by an independent ruling are delivered for context
but marked [NO ACTION REQUIRED — information, not a fix request]; and
escalated disagreements are delivered with the builder’s stored values standing
while they wait for a human ruling. The brief uses the durable finding reference
(for example, #42) for replies; compiled obligation IDs are supporting detail,
not reply IDs.
The brief states what the round asks separately from how many findings it contains.
On the ordinary finding level, the durable finding references are the requested
work. On the ticket level, the ticket’s opening words state the work because the
product could not attribute any observed item to the build; those items appear under
an unowned disclosure section with their location, observation, and reason no durable
item ID exists. They are not dismissed as acceptable, and they do not receive reply
IDs. Perimeter questions remain separately answerable with their PQ-n references.
The brief ends with the reply protocol. Reply on its own line for each open item:
FIX after rebuilding the artifact, EXPLAIN when the artifact is correct as
built, or CHECK-DEFECT when the check itself is malformed. Unanswered open items
remain open. Items marked as requiring no action do not need a reply. The brief is
oracle-blind: it does not tell the builder whether the build passed or failed.
For a sealed-spec conformance run, use get_conformance_fix_brief after the
Adjudicator completes instead. That variant hands the builder only the cited
rules for target_defect verdicts, without suite grading numbers or adjudication
receipts.
triage_unlicensed_findings
Analyze the unlicensed residual from a stored system comparison and draft
proposals for differences that may be safe platform representation quirks. This
tool is read-only by default and never approves or ratifies anything. Set
register_proposals to true only when the human operator asks to file the
proposals; they remain unlicensed until they pass the qualification and human
ratification workflow.
For column_null_count findings, the tool can propose a null_form_equivalence
rule only for a text column whose measured categorical value-count map
corroborates that one engine writes absent values as SQL NULL and the other as
the empty string over the same rows. A difference where both sides have
different non-zero null counts, a non-text column, or a column without the
required map is left for review or unclassified rather than proposed. The
proposal includes the affected columns as null_form_columns and edge fixtures;
the comparison still keeps each column’s content digest, distinct-count, and
categorical-map verdicts separate.
The response includes exact counts, proposed_pi_rules, needs_review, and
unclassified buckets. Each
bucket is returned with at most sample_limit example entries (default 25);
counts remain exact, and a truncated bucket is marked with its corresponding
*_truncated field. Use this before ratification to turn a raw residual into a
reasoned proposal, then use the ratification tools for the human approval step.
When register_proposals=true, each returned item in proposed_pi_rules also has
proposed_by, the author recorded on that rule’s durable row, and the response has
attributed_to_another. The latter is true if any registered rule names someone
else, false if all name the current caller, and null when no rule was registered
or a rule names nobody; an unnamed author is returned as "unattributed". A
content-addressed rule keeps its first recorded author when another caller registers
the same proposal. Draft mode writes no rule and therefore returns no attribution
verdict. Before registration, every proposal’s rule_id must match the content hash
of its definition; if any id does not match or a definition cannot be read as a rule,
the call refuses the registration before storing any proposal.
list_finding_dispositions
Read the per-finding diagnosis state before proposing or correcting a package.
Use it to see which findings are undiagnosed, what verdict was recorded, the
grounds for that verdict, and who recorded or proposed it. The response includes
one row per matching finding, total, by_disposition counts for the filtered
set, and paging metadata. This call changes nothing.
Call this before
propose_finding_disposition_package or
propose_finding_disposition_correction. A named diagnosis can be inspected
through disposition_note, dispositioned_by, and
disposition_proposed_by; the model-scoped ruling field is documented in the Estate
API reference.
No evidence document is returned by this focused read. Results are scoped to the
person the agent is working for: findings from comparisons they cannot see are removed
before findings, total, and by_disposition are calculated. A diff_hash they
cannot open is answered as unknown. The visibility check costs one scope load (four
index reads) before the ledger read.
disposition_system_diff_finding
Send one system-diff finding back to be fixed by recording target_defect
directly. A send-back needs no approval and leaves the finding open until a fresh
comparison shows the fix; the tool does not file a remediation request or hand
work to a builder. It refuses a finding already diagnosed with another disposition,
and it refuses findings the Adjudicator left as question or spec_ambiguity until
the owner answers. Other diagnoses settle a difference without a fix and require a
human-approved package; use
propose_finding_disposition_package (or
propose_finding_disposition_correction to replace a recorded diagnosis). On
success, the response includes success, finding_key, disposition,
dispositioned_by, already_sent_back, and open_package_items. The actor is the
signed-in user when present, otherwise agent:<bot_id> when the turn has an acting
bot, or the repository’s non-human marker when neither identity is available.
open_package_items identifies open packages made stale by the send-back; notify
their proposers. A refusal writes no disposition and returns no actor. Legacy
send-backs staged in open initial packages are also handled at startup; see the
Prover package approval guidance.
list_comparison_events
List completed comparisons, newest first, when the user refers to earlier
comparison work without a diff_hash or when you need to find the hash for
another comparison tool. Each returned event identifies the engine pair and
comparison time, includes verdict and finding counts, and carries the
systemic-family rollup. It deliberately returns one row per comparison rather
than per finding, so use list_system_diff_findings for one event’s findings
or read_comparison for the full classified element payload. The family samples
use the listing shape: coordinates, disposition, and only the source and target
values needed to render a list; full finding history remains available per event.
The per-event rows expose column, detail, source_value, and target_value beside
each evidence document; see the Estate API reference
for the complete row contract.
The result is a bounded page. Check
truncated before assuming the feed is
complete; total_row_count is exact when the page is complete and null when
more events remain.
Only comparisons the person you are working for can open are returned.
Visibility filtering can leave fewer rows than limit; hidden comparisons are
not counted. This adds one visibility-scope load to the event read.
An empty comparison_events list means no visible comparison has been run on
the deployment; characterize both sides and call run_system_diff first.
read_finding_ledger
Read the findings that remain open across all comparison runs. Each result is
folded from the append-only lifecycle log and includes its durable #N, current
ledger state (new, still_open, or reopened), consecutive-run count,
originating run, and lineage. Results also include last_seen_run_id and
rests_on_reopened_seal; see the ledger response fields.
Resolved findings are omitted. Use
list_system_diff_findings for one comparison, read_finding for one
finding’s complete case history, or list_finding_dispositions for recorded
diagnoses.
Only findings on comparisons the person you are working for can open are
returned; hidden findings are omitted and not counted. This tool has no
parameters. An empty findings list means nothing visible is open. The check
adds one visibility-scope load beside the ledger read.
For one comparison, list_system_diff_findings uses the same visibility boundary;
its count is computed after hidden findings are removed.
For an individual finding, read evidence.detail as its own detail. family_pattern
names the family template, with each number replaced by #; it is not the finding’s
detail.
read_finding
Read one finding in depth: its history, the reconciliation episodes it belongs to,
or the rows that evidence it. Use read_comparison first to get the finding’s
numeric id or durable key. The response combines the requested records with the
current folded state and the tamper-evident history from the append-only event log.
History requires
finding_id; episodes and witnesses require finding_key.
If the identifier is unknown, the tool returns success: false with an actionable
error. When include requests history, its result includes rests_on_reopened_seal (a
reopen notice or null); see the API ledger response fields
for how to interpret the notice and the additional reads it requires.
History is available only when the person you are working for can open the comparison
that minted the finding; otherwise it is answered as unknown. Episode sightings are
filtered individually by their comparison or estate visibility. A finding not minted
by a comparison is answered as unknown when none of its episode sightings are visible.
Witnesses are also limited to findings on comparisons the person can open. For the
obligation-ledger fields withheld when an episode sighting is hidden, see the finding
episodes API contract. One visibility scope is loaded
per call and shared by its requested history, episode, and witness reads.
request_evidence
Ask for the facts behind one finding before anyone decides it. Read the finding with
read_comparison or read_finding first, then pass its finding key, comparison class,
and source- and target-side summaries; do not guess what caused the difference. This
files the same evidence request the Human Review finding pane’s former Request the
evidence button filed. It does not change either estate or record a disposition on the
finding.
For example, replace each placeholder with the corresponding value from the finding:
data.created and data.request
with request_id, kind, status, and server-written instructions. The request is
attributed to local operator (auth disabled). created is false when the same ask
for the finding—with the same comparison, objects, pair fingerprint, and family
signature—is already on file; the existing request is the answer, not a second request.
With authentication enabled, the tool does not file the request. It proposes it in Action
Review and returns data.proposed: true, proposal_id, the Action Review status, url,
opened, and remediation_request_id. A person may decide it there, or an agent may use
decide_approval_request on the person’s behalf when asked or working on a goal they set.
Only a person who can read the finding may decide the request. A newly opened request is announced
with a card in the agent’s thread. A repeated ask that is
already waiting returns opened: false and does not open another request; if the first
call could not send the card, a later ask can send it once. If the same ask is already
filed, the tool returns the existing data.request with created: false instead. Relay
data.request.instructions as written and tell the person the finding’s decision now
waits on that evidence. Sending the request to whoever gathers it is a person’s act, not
a tool call.
If the request was inserted but its read-back failed, the response has
request_exists: true, unavailable: true, status: null, and card_sent: false;
proposal_id is included when known. An unavailable or fault refusal that includes
proposal_id and url means the request exists but confirming it failed. For
unavailable, repeat the same ask to read the existing request; for fault, do not
retry, and give the person the url. Without proposal_id, no request was proposed.
The tool requires ratify_source_contract. A person who already declined the same ask
gets a conflict refusal; do not retry it. If the deployment’s Action Review policy does
not admit the request, it returns policy_denied with the policy’s reason. A caller
without ratify_source_contract is refused with permission. Invalid keys and prefixes
matching no finding are refused with invalid; a full key absent from the findings
ledger is refused with not_found. Genesis supplies bot_id, thread_id, and user_id
from the tool-call context; they are not caller parameters. Cost: one indexed
findings-ledger read to confirm the finding exists (without reading its evidence); a
short finding key needs one additional indexed lookup. A direct filing then costs one
remediation-ledger read and at most one insert. An authenticated proposal also costs one
remediation-ledger read and two Action Review ledger reads; opening a new request adds
one policy load, a second findings-ledger read, and one ledger transaction. A pending
request’s card check adds two narrow ledger reads; the one call that sends its card also
adds one guarded update, one sealed event, and the card delivery.
request_test_case_approval
Ask a person to approve the test cases currently in effect for one view, without changing
either database. Pass the boundary_hash the cases are stored under and a target_node
from those cases. Which call stores them depends on the run that will use them. For a
rewritten view’s proof (validate_migration), check the cases with
design_stimulus_campaign and check_claims_only=true, which stores nothing, then store
them with prepare_migration_prover and pass the boundary_hash it returns. For a
trajectory or qualification campaign, design_stimulus_campaign stores them under the
boundary_hash you pass it; pass that same one here. A run groups cases into a
view by the last dot-separated part of target_node, so groups with the same final part
belong to the same view even if their preceding names differ.
bot_id, thread_id, and user_id from tool context; they are not
caller parameters. With authentication enabled, the tool proposes the request in Action
Review. A signed-in person may approve or decline there; an agent may also use
decide_approval_request for the person when asked or when it is part of their goal. The
result includes proposed, view, case and request counts, requests, not_asked, and
approval_status. Each request includes its Action Review url, status, opened,
case_set_id, part number and total parts, and case count. Give the user each returned
URL. opened: false means the same cases are already waiting; that existing request is
the one to review. If the set needs multiple requests, each contains whole cases and
approving one approves only its cases; all requests must be approved for the view to be
fully approved. not_asked gives the parts that could not be proposed and why.
Approval is bound to the stored test cases: it remains in effect for later runs until a
case changes. A changed case set needs a new request. An unchanged set declined in Action
Review is not asked about twice; revise the cases to address the person’s reason before
asking again. The reviewer-facing contents and what the approval means are described in
Approve test cases for a view.
That page also explains the requester and decider attribution in the approval and decline
receipts, including when an approval is marked self_approved.
The Action Review brief also summarizes the situations Prover can list from stored view
SQL and which situations the test cases claim; the approval guide explains that summary.
With authentication disabled, there is no person to ask: the tool records the cases as
approved under local operator (auth disabled) and returns approved: true,
approved_by, reviewed_by_a_person: false, and review_note. It does not accept a
reviewer’s name as attribution. This path runs only on a person-started turn; a product-
started turn such as a wake or mailbox notice is refused without approving anything.
Asking needs view_connections and a signed-in person. With authentication enabled,
if no signed-in person started the turn, it refuses with unidentified and tells the
caller that a person must ask; otherwise a missing view_connections permission is
reported as permission. Any signed-in person who can see the request’s full review
scope can open and decide it in Action Review, without ratify_source_contract. For a
boundary with snapshots, that scope is every snapshot behind the view’s test cases. For
a boundary prepared with prepare_migration_prover and no snapshots, it is every
connection sealed into the request: the source, target, and any warehouse connections.
An older request that sealed no connections uses every connection in the pair recorded
for its boundary. For the legacy-request visibility rule, see Approve test cases for a
view. When every
case for the view is already
approved and unchanged, it asks nothing and succeeds with
approval_status: "fully approved", approved_by and
approved_at. It refuses with not_found when no cases
are stored for the view and boundary; with conflict when they are
declined without changes, inconsistent about the output or condition, repeated across
groups, or cannot be shown whole and exactly; and with invalid for an empty final
target_node part. A request withdrawn because cases changed must be made again for the
current cases. A policy that does not admit the request returns policy_denied.
When called from outside Genesis over MCP or /api/tool_call, the response points
next to action_review_request_status for the first pending request. Use that
tool with each returned proposal_id, and share the returned
data.requests[].url with the user in the meantime. Do not call
request_test_case_approval again to check the result. See
action_review_request_status for its response fields
and states.
Cost: the tool reads the view’s stored test-case versions and up to 200 recent declined
or withdrawn requests to find earlier decisions. For each request still needing approval
it reads the Action Review ledger twice; opening a request also reads the view’s stored
text from the newest scan of the request boundary, or else searches the 50 newest scans,
and parses its SQL and conditions to list situations. It reads the boundary’s target
profiles to find a mapped rewrite; when that rewrite can be read, its text and conditions
are parsed too. A new request also loads policy and writes a ledger transaction. Sending
a card adds two ledger reads and a write. With authentication disabled, it reads the cases
and performs a status read and update in one transaction.
adjudicate_findings
Send the findings from a completed system comparison—whether it came from a graded
proof, a comparison-only proof, or a compare run—to the independent
Adjudicator for read-only reproduction and routing. The Adjudicator records a
typed verdict for each finding as stands, spec_defect, target_defect,
platform, question, spec_ambiguity, candidate_improvement, or
no_deviation or instrument_defect, with rationale and query receipts. See the
False alarm (Prover) guidance
for the latter outcome. no_deviation records that
the Adjudicator examined the finding and found nothing to route; it requires a
one-line reason, is neither stands nor an abstention, and routes to nobody.
candidate_improvement records a deliberate build deviation that may be better
than the declared behavior; it is queued for human review and is not a license.
The tool returns a running adjudication_id; with notify (the default) this
thread is told when the Adjudicator has submitted its verdicts, with the record
get_adjudication_run returns, so there is nothing to poll. An unknown
comparison or a comparison with no findings is refused before a proceeding is
started. The spawned proceeding is visible on the Prover Adjudicator agent
page and is titled Adjudication <first 12 characters of diff_hash>, so a
reviewer can open the thread and read the Adjudicator’s reasoning.
The Adjudicator checks the model provider before opening the proceeding. If it cannot
answer, the tool returns an unavailable refusal with cause and creates no
proceeding; follow that remedy before retrying. The check uses the shared
llm.provider_preflight_ttl_seconds
window.
The configured mode is fail-closed: an unset, uninitialized, or unrecognized
value is treated as
silent. The kickoff message is a table of contents, not a
copy of the materials: it names the proceeding’s sections, their counts and
serialized sizes, and the constitution pin. Read every section through the
Adjudicator-only fetch_adjudication_materials tool, starting with doctrine
and continuing each page until next_offset is null. Each citable register
entry has an entry_id; IDs use the forms
disposition:<finding_key>, ruling:<ruling_id>, rule:<rule_id>,
fork:<axis_id>, or reference:<basis_id>. A reference: entry is available
for a migration comparison without a sealed spec and means the target carries
the source’s content; it does not license content drift. The briefing must fit
the thread message-size limit; an oversized briefing is refused before the
proceeding or Adjudicator instance is created.
Reusing the same (run_id, round_n) returns the existing proceeding; it does not
re-mode it. The response’s requested_mode records the mode this call named, and
mode_basis is non-null only when that requested mode was dropped because the
existing proceeding uses another mode. A proceeding’s mode is fixed when it opens,
so choose silent or active on the call that creates the round.
With notify (boolean, default true), the thread that opened the proceeding is
told when it completes or fails, on its next tool result or in a new turn after it goes
idle. The wake carries the same record get_adjudication_run returns — verdicts
projected, progress beside them — so there is no need to poll; the response’s
next_step says so while the wake is armed. When that record is too large for the
mailbox, the new-turn form carries it without its verdicts and says so under
verdicts_omitted_from_wake, naming the get_adjudication_run call that reads them.
Set notify=false to poll get_adjudication_run yourself. A caller without a Genesis
thread is not armed.
adjudicate_conformance_run
Send a parsed conformance suite result to the independent Adjudicator after the
suite grades a build against a sealed specification and before the builder sees
the raw output. The Adjudicator reproduces every non-PASS check read-only
against the target and routes it as stands, spec_defect, target_defect,
platform, question, or spec_ambiguity. The run is identified by the
canonical digest of the supplied result document, and the proceeding verifies
that spec_hash matches the run’s recorded spec_sha256 before it opens.
This intake runs only in silent mode: verdicts are persisted to the
adjudication log and do not stage a disposition package. Partial clause
coverage is accepted, and findings whose cited clause was not supplied are
listed as sealed_spec.findings_without_clause; supplying clauses for none of
the non-PASS findings is refused. A run without durable findings returns
without opening a proceeding; the API response includes the reason beside
no_findings. With notify (the default) this thread is told when the proceeding
completes or fails, with the record get_adjudication_run returns, so there is
nothing to poll; with notify=false, poll get_adjudication_run with the
adjudication_id. adjudication_id is not a generic run id. Use
get_conformance_fix_brief after completion.
The run document preserves each finding’s durable_id (the persisted #N,
when one exists) beside its finding key, and includes as_of, the time the
grading run observed the estate. When a clause declares candidate_readings,
the materials also include its passing rival checks when another reading on the
same fork failed; those checks are marked role: "fork_context" and provide
measurement context rather than additional findings to route. The kickoff is a
table of contents; read the pinned doctrine, identity, cited clauses, findings,
and any other listed sections through fetch_adjudication_materials, continuing
pages until next_offset is null.
The materials identify the build under test in conformance_run.target using
the resolved target endpoint’s catalog and optional dialect. When no target
endpoint resolved a database, conformance_run.target is null and the
materials do not name the estate. Completed grading runs can also resolve their
source and target read-only endpoints from summary.provenance when the pair
was recorded there, as well as from the top-level snapshot fields. Findings
carry the measurements available from the grading run: mismatched_key_count,
a bounded mismatched_keys_sample (up to 20 keys),
mismatched_keys_truncated, and the sealed source_sql and target_sql. For
a finding covering multiple obligations, measurements stay with each
obligations entry; each entry also preserves its declared fork axis and reading
when available, so a fork leg remains identifiable in the downstream finding and
fix brief. A top-level measurements block is included only when the finding has
one obligation.
The run document also includes the open findings from the type_family durable
ledger, not only obligation findings. Those results carry tier: "type_family",
the durable durable_id when present, and the finding’s locus; when the family
grader recorded both halves of the comparison they also carry expected and
observed. Their cited clauses use the same type_family tier, so the
Adjudicator can distinguish a declared-type finding from an obligation that uses
the same sealed item identifier.
Each failing check is matched to a durable finding by its exact locus first. If
the run has no matching locus, the item’s declared spec_item_id can supply the
match only when exactly one open durable finding belongs to that item. This lets
runs without a recorded locus proceed while keeping one proceeding rule per
durable finding. An item with multiple open findings, or a check that resolves to
none of the item’s open findings, is refused rather than emitted with a composite
<spec_item_id>:<obligation> key that the caller cannot reconcile. Findings that
are already closed are not part of this open-finding match.
Example:
get_adjudication_run
Read a proceeding’s status, mode, constitution pin, materials manifest, and
submitted verdicts for either a completed comparison or a conformance run. If
its handoff instance ended without submitting, the run is reconciled to
failed, and a replacement can be started with the tool that opened that
proceeding.
A running status means only that the Adjudicator has not submitted; it does
not say whether the seat is still working. run.progress is the best EVIDENCE
about that, and it is evidence rather than proof — read it as such.
phase: "working" says only that the thread has been written to at some point;
the message count is cumulative, so it is not a liveness verdict.
last_activity is the seat’s own freshest write and it does not advance while
the seat is inside one model completion — five to ten minutes is normal at this
seat’s timescale — so a still last_activity is not on its own a stall.
streaming is three-valued: true with a recent last_chunk_at means the
completion is still delivering and the seat IS working however still
last_activity looks; false means the window passed with no chunk; null
means this response could not DECIDE stream liveness, which is not the same as
the stream having stopped. null has three causes: no chunk reading exists in
the process that served you, no staleness window was available to compare
against, or last_chunk_at did not parse. The last two still publish
last_chunk_at and stream_chunk_count, so streaming: null beside a non-null
last_chunk_at means a reading was held and could not be judged — not that
nothing measured it. A null last_activity is a third case again — read
unavailable_reason, which says which silence it is.
So: stale counters WITH streaming: true is a working seat. Stale counters with
streaming: false is the stall. Stale counters with streaming: null is
liveness UNKNOWN, and the honest report is that this response did not settle it —
not that the seat is dead, and not that it is fine. Quote what you read and say
which of those three it is, rather than converting any of them into a verdict.
A terminal proceeding reports its own end word as the phase with the counters
null — nothing read them, and null is not zero — and finished_at says when it
ended. A status this reader does not recognise reports phase: "unknown" with
the status named in phase_basis: it is neither classified as running nor
treated as finished.
Each returned verdict also carries its measured subject as object and column.
The briefed finding supplies those coordinates when materials are present; on a
terminal re-read without materials, Genesis resolves them from the durable finding
identified by finding_key. If neither source names a coordinate, the fields remain
present with null values rather than being omitted.
Narrow before paging: verdict_ids and outcome filter the proceeding’s verdicts,
then verdict_offset and verdict_limit page that narrowed set. An empty
verdict_ids list or an outcome outside the recorded vocabulary is refused.
verdict_page.total is the narrowed set’s size, returned is this page’s size,
and next_offset is the next offset or null when the set is complete. Advance
using next_offset, not the requested limit. verdict_selection echoes the
filters and page coordinates so the response identifies which rows it contains.
For example, get_adjudication_run(adjudication_id="...", outcome="question", verdict_limit=25) reads the first page of question verdicts.
Reading progress for a running proceeding costs a thread read per call (and,
where a handoff is recorded, the orphan probe beside it), so poll deliberately
rather than in a tight loop.
Narrowed or paged reads also count the matching verdict set; if an orphaned
proceeding is reconciled during one of those reads, the selected verdicts are
read again afterward.
fetch_adjudication_materials
Read one section of the Adjudicator’s kickoff table of contents. This is a
private tool for the pinned Adjudicator identity and only serves the
proceeding in the caller’s current thread; it does not perform a live estate
read. The kickoff carries no materials, so use this tool for everything the
Adjudicator must read: start with doctrine, then read each listed section to
completion before submitting a verdict.
The available sections are doctrine (the pinned constitution and proceeding
addenda), identity (what is being compared and the read-only connections),
advisories (tier-0 flags), license_register, cited_clauses (for a
conformance run), prior_verdicts (earlier rulings on the same pair-scoped
findings), and findings. A section is listed only when that proceeding holds
it. prior_verdicts contains the newest earlier verdict for each finding, with
finding_key, verdict_id, adjudication_id, outcome, confidence,
rationale, and recorded_at. Comparison and grading-run proceedings include
this section, even when its list is empty. A grading-run proceeding includes
prior verdicts only for pair-scoped durable findings. The direct
adjudicate_conformance_run tool includes an empty prior_verdicts list because
the supplied suite’s test IDs do not identify an estate pair. Read the section
before deciding whether your verdict differs. When a prior verdict is found under
the same finding’s key from another compared scope, its entry also includes
aliased_from, the key on which that verdict was recorded. The Prover’s scope and
finding guidance
defines which pair keys belong to the same finding identity class.
Register pages list entry metadata without the rationale and qualification; request
those fields by naming the corresponding entry_ids.
Pages default to 20 entries and accept at most 50, but the transport byte
cap can return fewer than requested. Use the response’s next_offset as the
next offset until it is null. The response reports unknown named IDs rather
than silently dropping them. The read loads the proceeding’s stored materials
snapshot, then slices it; it does not query either comparison endpoint. A
doctrine read also reloads and verifies the pinned constitution before serving
it.
Example:
get_conformance_fix_brief
Read the builder-facing brief after a conformance adjudication completes. The
brief contains the run ID, target, specification hash, and one item for each
target_defect verdict. This conformance intake runs only in silent mode, so
candidate_improvement verdicts do not produce a builder order here. Each item
includes the finding key, clause ID, and the charged rule with its citation, but
omits grading numbers, the Adjudicator’s rationale and confidence, and query
receipts. An empty items list means the run’s failures were assigned to the
specification, platform, or an escalation; the builder has no rule-based fix
request.
This tool refuses an unknown or incomplete proceeding, a comparison proceeding,
or a proceeding whose stored materials cannot be read.
submit_adjudication_verdicts
This is the Adjudicator’s private submission tool, not a general estate-agent
tool. Submit one typed document containing the verdicts reached so far. Each
verdict requires finding_key, outcome, confidence (high, medium, or
low), rationale, and at least one receipt with query and observed. A
no_deviation verdict additionally requires a non-empty one-line reason
saying what was examined and why there was nothing to route; it cites nothing.
A stands verdict must also include a non-empty
license_refs array containing the entry_id of a covering entry in the
proceeding’s license_register; citations that do not resolve to that register
are refused. A disposition:<finding_key> entry covers only its own finding,
while ruling:, rule:, fork:, and reference: entries identify broader
classes whose
coverage must be supported by the verdict’s receipts. A fork: entry identifies
an axis declared by the sealed spec, and the receipts must establish that its
measurements settled the fork. A reference: entry is valid only for a
migration without a sealed spec; its receipts must show the same content on the
source and target endpoints, and a content difference remains drift rather than
a covered representation difference. If no register entry covers a deviation,
route it on its merits instead, such as question with a provisional_position when
the data owner must settle it. Use provisional_position for question and
spec_ambiguity escalations; those outcomes do not stage dispositions. A
candidate_improvement verdict must include an improvement object with
non-empty build_behaviour, declared_behaviour, clause_ref, value, and
risk strings. Its optional mode is pocket by default or blocking; it
cannot include license_refs. The object may also include waiver_expires_at
(optional string, default null; a future ISO-8601 date-time) and waiver_owner
(optional string, default null, naming who answers for the waiver if accepted). If the proposed expiry is unreadable
or has passed, only those terms are dropped; the improvement is still filed, and the
response’s waiver_terms_dropped explains why. See Prover docket review
for how a person reviews the proposed terms. For comparison proceedings, earlier verdicts on the
same findings are included in prior_verdicts. If your outcome differs from that
ruling, include departs_from with exactly its verdict_id and a non-empty why
explaining what you measured that it did not. Submission is refused if a changed
outcome omits this field, names another verdict, or supplies it when there is no
prior ruling or your outcome agrees. Your confidence must reflect your own receipts,
not the earlier seat’s confidence.
For example, include the optional waiver terms inside the improvement object:
Only the pinned
Adjudicator identity may submit. A finding without a verdict
does not count as no_deviation: submit an explicit no_deviation row when it
was examined and nothing needed routing. If a document covers only some
findings, the accepted verdicts are persisted and the refusal returns
proceeding: "awaiting_coverage" plus unruled_finding_ids; send an additional
document for those IDs rather than resending accepted verdicts. The proceeding
completes only after every finding carries a verdict. In silent mode, accepted
verdicts are persisted to the adjudication log and nothing else changes. In
active mode, each target_defect verdict and pocket candidate_improvement
verdict is sent back immediately under the Adjudicator’s name; the finding stays
open until a fresh comparison shows the fix, and nobody approves the send-back.
blocking candidate improvements write a docket entry but send no builder item
back. spec_defect, platform, and instrument_defect settle a difference
without a fix, so they are staged together as one disposition package for human
approval. No package is staged when there is nothing requiring approval. The
candidate-improvement docket entry is written for human review and is never a
license. no_deviation, stands, question, and spec_ambiguity do not stage.
The response also reports
docket_entry_ids, held_for_review, staging_skipped, docket_discarded, and
waiver_terms_dropped. Each dropped-terms item explains why an improvement’s proposed
waiver terms were omitted; the improvement remains filed. Filing an improvement also attempts to open its Action Review
request automatically. docket_requests returns one result per finding, with
finding_key, proposal_id, status, url, and opened (true only when this
submission created the request), for entries that remain open. An entry already
accepted or rejected is named in docket_discarded instead and has no
docket_requests row. An error means this filing opened no new request, not
always that no request exists: with a proposal_id, the row identifies the
finding’s current request; with no ID, refused means no request is asking for
the finding, while unavailable or fault means its request state is unknown.
The docket entry remains filed in each case; do not file it again to ask for
approval. Candidate-improvement docket entries can be filed on Snowflake ledgers
as well as the other supported substrates. On completion,
verdict_count and these proceeding-wide fields describe the union of verdicts
accepted across all documents, not only
the latest submission. In active mode, sendbacks_applied lists finding keys
sent back by this proceeding, including keys already applied on an earlier retry;
sendbacks_made_stale maps each send-back to open-package items it made stale.
A send-back naming a finding the ledger does not hold closes the proceeding as
blocked; a finding diagnosed by a person after the proceeding opened keeps that
diagnosis and is returned in staging_skipped. Failed writes or findings that
moved during a send-back leave the proceeding open for retry with the same
document. Other routable verdicts stage on the
comparison named by the proceeding manifest’s diff_hash; this is the
comparison ledger the proceeding holds, not the subject document’s hash. If
that comparison is absent from the instance, the verdicts remain recorded but
the proceeding closes as failed with proceeding: "blocked", because retrying
cannot make the named ledger appear. If the ledger refuses the disposition
package, the proceeding also closes as failed with proceeding: "blocked"; the
same document will meet the same refusal, so report it and open a new proceeding
rather than retrying. A failed package write or linkage refusal leaves the
proceeding open for retry with the same document. Every refusal includes
proceeding and next_step: awaiting_coverage means send
an additional document for exactly the returned unruled_finding_ids; open
means correct and retry as directed, closed means the terminal record stands,
blocked also covers a stored finding inventory that cannot be read: that proceeding
closes as failed, returns inventory_error, and records
error_type: "inventory_unreadable". Report it and open a replacement proceeding rather
than retrying. In all cases, blocked means the stored materials cannot support any
submission, and
unknown means the call did not establish the state, so read the run with
get_adjudication_run before deciding what to do next.
For how human reviewers accept or reject these entries, including the Action
Review path for agent-filed candidates, see the Estate improvement docket
API. The reviewer-facing
statement of what an accepted finding’s licence covers is described in
Prover roles and approvals.
propose_finding_disposition_package
Stage an agent’s diagnoses for multiple findings from one system comparison for
human review. Staging writes no dispositions. By default, the returned
approval_url opens the package’s own Prover approval page, where a reviewer sees
each proposal beside the finding’s current source and target evidence. Reviewers can
approve or decline the package exactly as staged, but cannot edit, drop, or re-diagnose
an item. If an item is wrong, decline the package and ask for a corrected one.
Unless for_bundle is true, the tool also creates one Action Review item with
action type prover.approve_disposition_package.v1 for this package generation.
For a package with its own request, give the person the returned approval_url
and action_review_proposal_id. The same package generation reuses its Action
Review item on replay, and a declined or policy-denied item is not replaced by
another approval request.
When for_bundle is true, the package is staged without its own Action Review
item or approval request so a later propose_approval_bundle can make the bundle
the person’s single request. In that case, use the bundle’s link instead of this
package’s approval_url.
Any signed-in person can approve the package, including the person who asked the agent
to stage it; no special approval permission is required. When asked or acting on a goal
the person set, the agent can also use decide_approval_request to approve or reject the
package request for them. See Prover roles and approvals
for the approval record and workflow.
A correspondence rule already claimed by a live bundle request prevents a new
package request: if detected during staging, the package is not staged; if the
claim wins during request minting, the package remains staged and
action_review reports claim_refused without a request. See the disposition
package API reference for the
refusal codes. A replay checks the existing request against a fresh rule claim.
If the request pins a rule its claim did not hold, it is ended and reported as
drift; if another live request now holds a claimed rule, it is ended and
reported as claim_refused. If rule holds cannot be read and no unclaimed
pinned rule was found, the request remains standing and the response reports
unavailable. After drift or
claim_refused, ask again to mint a request for the package as it now stands.
If an agent’s composite bundle adopts the package request, that bundle request
holds the package: an approval mint for the same package will not create a
competing Action Review item. Decide the bundle request first; after it is
declined or policy-denied, stage a new package to ask for approval again.
The package’s native approval and unsign surfaces refuse while that Action Review item owns the
decision; a person decides it from the package approval page, which uses Action Review
behind the scenes, or an agent uses decide_approval_request on the person’s behalf.
For the approval flow, including an inconclusive
result when post-approval read-back fails and the one-time card behavior on replay,
see Prover roles and approvals. For how an
Action Review approval affects a promoted rule’s review record, see
Action Review also reviews promoted rules.
For Snowflake storage options for the estatechar review-event and findings records,
see Estatechar store settings.
Packages refuse target_defect, whether it is listed directly, selected by family,
or included in a corrective package: a send-back is applied directly with
disposition_system_diff_finding(disposition="target_defect"), never staged for
approval. Active Adjudicator target_defect verdicts are also applied directly.
If a difference requires a fix, do not propose a package for it.
Write plain_summary
for the person signing in ordinary business English, and note for an engineer
reading the technical record. The justification, each plain_summary, and each note
are shown to the reviewer. Do not ask the reviewer to change, edit, correct, or amend an
item; if an item might be wrong, explain what would make it wrong and ask the reviewer
to decline the package so you can stage a corrected one.
Package staging, including packages with staged rules, works on a Snowflake ledger.
Before writing the package event or any staged rule, staging checks whether a minted
rule can pass durable qualification; a refused rule therefore leaves neither the
package nor that rule written. The package retry identity is claimed with an
insert-if-absent MERGE, so a repeated request returns the winning proposal instead
of creating another one. Open package claims use a guarded update; if another event
holds the claim, the request is refused. That guard is not a serialization guarantee
for two truly concurrent claimers; the approval service’s door check is the
concurrency boundary. Approval that promotes a rule also works on Snowflake. It
checks each promotion before writing its rule; a refused promotion writes nothing,
and an Action Review approval still applies every item or none. If the store changes
between a check and its write, or a statement fails, the Snowflake transaction rolls
back as a whole. If ledger read-back cannot account for a package result — for
example, no row or more than one row exists at the claimed address — staging fails
closed and returns the audit reference for the recorded derivation failure; it does
not silently treat an ambiguous package as successful.
For the Snowflake batch-write performance of approvals that create standing rules,
see Prover roles and approvals.
Each approved diagnosis stays attributed to the agent as its proposer, with the human
reviewer recorded as the person who approved it. When the reviewer approves a
package, each licensed
disposition other than target_defect also resolves matching
unexpected_change blockers in the selected Human Review population when the
package covers them completely. Retracting that approval re-opens the
package-bound blockers it resolved; see the disposition package endpoints
for response counts and API details. The review-population API reports these
package-resolved members as resolution="exception"; a person’s separate
recorded ruling is reported as resolution="ruling".
A proposed disposition is a recommendation, not a decision. The reviewer approves
or declines the package exactly as staged, as a whole; no row can be changed on the
package. Propose your best reading rather than withholding one: declining to choose
leaves the reviewer to sort through the findings one at a time. When the choice
depends on something only the reviewer can answer — such as whether the difference is
expected for this pair of systems from now on or accepted only for this run — say
exactly that in plain_summary and propose anyway. The review surface shows
plain_summary on the row and uses it to group the package, while note appears
behind a collapsed technical-note disclosure.
Do not propose target_defect or spec_defect for a finding whose latest
Adjudicator verdict is question or spec_ambiguity unless the owner has
answered it. Ask the owner in chat, then record their answer with
record_clarification on an estate of the comparison’s pair, after the seat
asked. Have the owner ratify it on the review page while signed in; then cite its
clarification_id on that finding’s item. The citation carries the defect only
when a signed-in person ratified the clarification after the seat asked. An
agent-certified clarification, or one ratified with authentication disabled,
does not carry it; on a stack with authentication disabled, the owner records
the diagnosis themselves on the review page. A promote_delta or waived item
can instead cite the owner’s ruling behind it: the clarification must be
recorded on an estate of this comparison’s pair and not overturned;
ratification is not required, and the item shows its provenance label. A
citation on any other item is refused. The other route is to seal the owner’s
answer into the spec and re-open adjudication so the seat can rule on it.
Dispositions that charge no defect can still be proposed.
For agent-versus-caller attribution when Genesis invokes this tool, see the
disposition package API reference.
An item proposed as waived grants a time-limited exception and must carry a
future waiver_expires_at and a waiver_owner. Set the terms on each item, or
use the package-level defaults; an item’s own values take precedence, and an
omitted owner defaults to on_behalf_of. Waiver terms are part of the retry
identity, so changing only a term does not replay the earlier proposal.
disposition must be one of target_defect, source_drift, promote_pi,
promote_delta, spec_defect, instrument_defect, or waived. note is optional rationale
shown beside the evidence and is limited to 2000 characters. plain_summary
is optional, limited to 600 characters, and should be one sentence explaining
what approving the diagnosis actually means without schema or migration jargon.
Each item accepts only finding_key, disposition, plain_summary, note,
rule_id, and clarification_id; the optional clarification_id is the
recorded owner answer or ruling described above. See the API
reference
for how unknown request fields are reported.
The package must contain at least one item and at most 2000 items; each finding
must be an open finding on the comparison and must not already carry a diagnosis.
The response includes package_id, diff_hash, mode: "initial", item_count,
subject_fingerprint, approval_url, action_review_proposal_id, and an
action_review object with the Action Review proposal status, digest, whether
the card was sent, and whether the item was renewed. When for_bundle is
true, action_review and action_review_proposal_id are null; the bundle
creates the approval request. Otherwise, a mint failure is reported
inside action_review beside the staged package; it does not discard the
package. A ledger failure sets unavailable: true, gives a safe message, and
can be retried. If insertion succeeded but read-back failed, action_review still
names the request with proposal_id when known and status: null; retry to read its
state. During replay checks, a ledger failure remains unavailable, while a defect
checking an existing request sets fault: true; its detail is in the server log and
retry will not cure it. An audited derivation refusal sets
refused: true and includes audit_reference; only typed
ProjectionDriftError or ValueError causes are shown, while other causes are
logged and replaced with a generic refusal. SQL and driver error text is not
returned to the agent. The response also includes a coverage block containing
proposed_here,
exhibited, dispositioned, and undispositioned counts. The coverage is
measured when the package is staged and is returned unchanged on an idempotent
Prover replay, so its denominator is the original comparison state.
The optional open_package_conflicts response array lists each conflicting package’s
package_id, diff_hash, and item_count; see the linked API reference for the
staging behavior and package-item details.
Staging conflicts involving a claimed correspondence rule are described in the
disposition package API reference,
which also defines the HTTP response’s expansion metadata and corrective-selector refusal.
If the comparison or any item is
invalid, the tool returns success: false and an error without staging the
package. If the finding changes before approval, the reviewer must stage a fresh
package. Use disposition_system_diff_finding for a single finding you are
certain about; use the package tool when a human should review several proposed
diagnoses, including waivers.
Only one open initial package can stand for a comparison in the public review
lifecycle. A second proposal returns success: false with open_package_ids and
standing_package; read or finish the named package, or withdraw it with
retract_finding_disposition_package, before proposing again. corrective packages
are not blocked by this rule.
For a package containing promote_pi, staging runs the approval preflight before
writing the package. If any lasting rule cannot be approved — for example, its
fixtures fail, its approval for this pair was revoked, its evidence does not survive
the pair’s configurations, or it does not license the finding — the whole proposal
is refused. The tool returns success: false, an error, and refused_items with
each finding_key, its finding locus, the approval reason, and plain_reason;
unbound promotions may also include unbound_promotions with qualified-rule advice.
Nothing is staged, so remove or correct the named items before proposing again.
The promotion preview used by Human Review applies the same preflight and reports
unapprovable items in unavailable with reason and plain_reason, rather than
showing them as licences. A previewed rule also includes
plain_reusability_refusal when the reviewer cannot approve it, including when its
approval on this estate pair was revoked. Qualification that requires running
against the comparison pair’s environment remains checked during approval. If
approval derives and registers a rule, retries and repeated clicks reuse the
content-addressed rule and do not append a duplicate review-log audit event.
For reviewer-derived value-rendering and type-correspondence rules, the
applicability boundary must name the same object and column as the finding’s
evidence using exact identifier text. Differences in case or whitespace are
not treated as the same element; re-propose the rule from the finding so both
fields are generated from the same rendering.
In a Prover finding or issue-group chat, input_metadata.prover_context is the
authoritative captured subject. The package must include exactly the captured
members, use instrument_defect, and match the current comparison ledger and
review population; malformed, stale, incomplete, or changed evidence is refused
without staging. A successful Prover-bound response also includes
evidence_fingerprint, evidence_summary, evidence_scope,
evidence_member_count, idempotent_replay, and remeasurement: "not_enqueued".
The same source message returns the existing package with idempotent_replay: true; changed package content requires a new message. Human approval remains
required, and only a fresh comparison can discharge the Prover finding.
For an existing diagnosis that needs replacement, use
propose_finding_disposition_correction instead; its approval page shows the
recorded and proposed verdicts.
propose_finding_disposition_correction
Stage an agent’s proposed replacements for diagnoses that are already recorded.
This is the corrective counterpart to propose_finding_disposition_package:
staging writes no findings, and the returned approval_url opens a Human Review
package that a reviewer approves or declines exactly as staged, as a whole; if any
replacement is wrong, they decline it and ask for a corrected package. Read
list_finding_dispositions first so every item has an existing diagnosis and the
new diagnosis is different. The package records the prior verdict for audit, and
approval returns the old-to-new corrections.
The new
disposition must be one of target_defect, source_drift,
promote_pi, promote_delta, spec_defect, instrument_defect, or waived, and must differ
from the finding’s current diagnosis. The package must contain at least one and
at most 2000 items, each most recently exhibited by diff_hash. The tool
refuses an undiagnosed finding, an unchanged proposed diagnosis, duplicate or
unknown findings, and invalid comparisons without staging anything. Nothing
changes until the request is approved, by a person or by an agent using
decide_approval_request for that person. A corrective package cannot be
unsigned; correct it again with another corrective package instead.
In a Prover finding or issue-group chat, authoritative prover_context binds the
correction to the captured comparison and member set. The tool accepts only the
instrument_defect replacement, refuses malformed or stale evidence and changed
membership, and returns the same evidence and idempotent-replay fields as the
initial package tool. It never enqueues remeasurement; a fresh comparison is
required after approval to discharge the Prover finding.
retract_finding_disposition_package
Withdraw a disposition package you staged when nobody has ruled on it yet. This
removes the request from the reviewer’s waiting list without changing any finding
disposition. You can withdraw only a package proposed under your own bot identity;
packages with an existing approval or rejection cannot be withdrawn, and an
already-withdrawn package cannot be withdrawn again. A reason is required and
must explain in one sentence what you got wrong or what changed; a blank reason is
rejected. Read the returned error for the reason instead of retrying. See the
disposition package API reference
for the corresponding HTTP endpoint and response details.
The tool returns
success, package_id, diff_hash, status: "retracted",
retracted_by, retracted_as: "proposer", reason, and item_count. A missing
bot identity fails closed rather than allowing an unattributed caller to withdraw
another package. This tool records proposer withdrawals only; when a person
declines or policy denies the package’s linked Action Review request, the review
workflow closes the package as retracted with retracted_as set to
"declined_in_action_review" or "policy_denied_in_action_review", respectively.
list_finding_disposition_packages
List the disposition packages already staged for one comparison, newest first.
Use this before staging another package to find work already handed to a human
or to recover a package whose approval link was lost. Each row is a summary with
package_id, title, status, and item count; use
read_proposal to read its proposals and evidence.
The comparison is checked against the visibility of the person the agent is working
for before packages are read. A comparison they cannot open is answered as unknown,
without exposing its packages. The visibility check costs one scope load (four index
reads) before the package read.
The response reports
viewer_can_sign: false and
viewer_cannot_sign_reason: "no_signing_identity" for every row because agents
do not hold a signing identity. Each row also includes approval_url,
approval_generation, and the current action_review head when an Action
Review item owns that package generation. Give a person the package URL, not
the generic Action Review tab; the Prover page is where this package is
decided. A package closed after a person declines or policy denies its Action
Review request appears with status: "retracted" and the matching
retracted_as value; the comparison is then available for a new package. An
unrecognized status returns success: false instead of an empty
list. An empty packages list means nothing has been staged for that
comparison; use propose_finding_disposition_package to stage a diagnosis
batch.
list_packages
List every disposition package staged for a comparison and the counts by status.
Use this to find package IDs and check whether anything is still open before
proposing another package. Unlike list_finding_disposition_packages, this read
always includes every status so counts.open is a complete count; use
read_proposal to inspect one package’s proposals and evidence.
The response includes
packages newest first, counts (open, closed,
retracted, and total), and open_package_ids. Each package row includes
viewer_can_sign and viewer_cannot_sign_reason; these describe the signed-in
caller, not the agent’s borrowed visibility. Open package rows include their
approval URL. The comparison is checked against the visibility of the person the
agent is working for before packages are read. A hidden comparison is answered as
unknown. This read includes approval-item state and page links for every package;
it reads no per-item finding evidence, which is loaded by read_proposal one
package at a time. It reads the comparison’s review log, folds each package’s
status, reads the Action Review link and status for each request, and loads the
page-address cache; it does not query per-item evidence.
read_proposal
Read one staged disposition package and its decision status, including its
proposals and the finding evidence currently held by the ledger. Use this to
inspect what a package contains before reporting it as ready for review; use
list_finding_disposition_packages to find package IDs.
If the comparison has no package with that ID, the tool returns
success: false; the package may belong to another comparison or may have
been retracted. A successful response includes approval_url,
approval_generation, and action_review when an Action Review request owns
the package’s current generation. The approval URL opens the package’s own
Prover page, and the conversation also renders its decision card when the
package is open. A package staged with for_bundle: true has no individual
request; carry it with propose_approval_bundle to create the one request, or
use the package page’s Ask for approval action if it should be reviewed alone.
read_bundles
List the approval bundles still waiting on a comparison, or read one waiting
bundle with its full rationale and members. Use the list before reporting what
needs sign-off; pass a bundle ID to inspect its rule IDs, package finding keys,
and evidence-gap members. Only waiting bundles appear. Reading does not approve
anything; give the person the returned action_review.url, or approval_url
when the bundle has no Action Review request.
For example, list waiting bundles with
read_bundles(diff_hash="a1b2c3d4").
The list includes each bundle’s brief, proposer, timestamp, carried-member counts,
and Action Review request details. The comparison is checked against the visibility
of the person the agent is working for before bundles are read; a hidden comparison
is answered as unknown. The read costs one review-log read and may also plan
evidence-gap populations when a waiting bundle carries gaps. Each returned bundle
also reads its Action Review link and current request status.
record_review_decision
Record a run-level verdict on a comparison when the person in the conversation asks you
to sign it off or reset it, or when the verdict is part of a goal, Blueprint, or mission
they set. The record identifies the agent and person and carries the approval basis. This
is not needed when the comparison is already Verified with nothing left to decide;
read data.review.nothing_to_decide from read_comparison first.
The person must be able to see the comparison. A missing or unknown
approval_basis
refuses with invalid; when there is no person to act for, the tool refuses with
unidentified. awaiting_review records that the comparison is not approved. With
authentication disabled, the local operator remains the recorded identity. Resolving
the person requires up to two thread reads, one project read, and one users-table read;
recording the verdict reads and appends to the comparison review log. The returned
folded review state includes decision_approval_basis.
decide_approval_request
Approve or reject a Prover approval request on a person’s behalf when they ask in this
conversation, or when deciding it is part of a goal, Blueprint, or mission they set. It
covers Prover requests for disposition packages, bundles, proposed rules and mappings,
seat rulings, evidence requests, and test cases. Other Action Review requests are not
eligible. An approval applies its requested change immediately; a rejection records the
decision and applies nothing.
The person must be able to see the request’s subject. With authentication disabled,
approval_basis is still required and the decision is recorded as
local operator (auth disabled). A request that is not a Prover request is refused with
human_authority; a request outside the person’s visibility is
reported as not found. A missing or unknown approval_basis refuses with invalid, and
a turn with no person to act for refuses with unidentified. An agent may decide its own
request; the record names the agent as both requester and decider.
For example, to approve a package the person asked you to accept:
decided, success, final_status, refusal_reason,
execution_refusal_reason, and the proposal status, including decided_by_label.
Resolving the person costs up to two thread reads, one project read, and one users-table
read. The decision also reads the proposal and its subject’s visibility, loads policy,
and records the decision; approval runs the request’s application work.
propose_approval_bundle
Stage a single approval bundle for a comparison. The bundle can carry
the three review-queue populations together: correspondence-rule proposals,
disposition packages staged earlier with propose_finding_disposition_package
(prefer for_bundle: true when staging them for this request), and evidence-gap
exception packages. Staging changes none of them. When the
response includes action_review, send its url to the person; otherwise use
approval_url or, when it is null, approval_path. The agent that proposed
the bundle may decide its request for the person when asked or when it is part of a goal
they set, using decide_approval_request.
Use rule_ids or all_proposed_rules for correspondence rules, and use
evidence_gap_package_ids or all_open_evidence_gaps for evidence gaps, never
both forms for the same kind. package_ids names already-open disposition
packages and does not amend them. A bundle must contain at least one member.
For partial-seal open-clause packages, use the bundle API contract
for the bulk-selection exception and explicit package-id behavior.
The response includes
bundle_id, approval_route, approval_url, and carries,
which reports counts against their source populations: proposed rules,
undispositioned findings, and open evidence-gap members. See the
Estate API reference for
route meanings and when action_review is returned. Relay carries.excluded_rules too.
When supplied, brief is also returned with the bundle and shown before its full
rationale on the Action Review request. Keep the brief in plain language and
write proposal and why in at most three sentences each, as requested by the
tool; write weigh as the uncertainties a person should consider. For example:
brief={"title":"Approve the customer ID mapping","proposal":"Record the matching ID on the customer table.","why":"The comparison found a consistent mapping.","weigh":["The sample may not cover every customer.","The source key may not be unique."]}.
A missing part, a part over its limit, or an extra field is refused rather than
shortened. Re-proposing the same standing bundle does not replace its brief. See
Prover review guidance
for what the person sees and what the decision attests to.
The defaults eligibility predicate excludes rules whose subject is a statistic
derived from measured values; each excluded row gives the rule and its reason.
all_proposed_rules never sweeps in a data-derived or unclassified rule. An agent
may carry one only by naming it in rule_ids and proposing a rules-only bundle;
the human’s Action Review request shows the rule’s sealed evidence. See the
Prover review guidance
for what the reviewer sees.
The bundle records the comparison run and population scope at proposal time.
If the same proposer retries with the same membership and scope, the tool
replays the standing bundle instead of creating a duplicate. If a package or
evidence-gap membership changes before approval, the human must receive a fresh
bundle. For details, see the Prover review guidance.
The human signs through the linked Action Review request when it is
present, or the bundle’s API review surface otherwise; no Prover tool can sign
it. On an authentication-disabled deployment, the human review doors
accept an optional X-Genesis-Signed-As header and disclose that self-reported
name in the stored signer label; see the Estate API reference
for the shared signer rule. For ratified rules without attached evidence, the request
names the component pair and licensed object or column; see Prover roles and approvals
for the full reviewer explanation. While that request is live, the carried rules cannot
be signed off separately; the same page explains how a live request on another
bundle blocks approval of a shared rule.
When a person rejects that request, eligible carried agent- or service-proposed
rules are withdrawn from the comparison; see the Prover guidance for the
comparison scope, reversibility, and exceptions.
An agent may name at most one data-derived or unclassified rule in a rules-only
bundle, which uses Action Review. Do not include disposition packages or evidence-gap
packages with it, and do not use all_proposed_rules to select it. Naming more than
one is refused with one_data_derived_rule_per_bundle; combining one with other
members is refused with data_derived_rule_needs_a_rules_only_bundle. A person
naming such a rule is refused; the rule’s own Action Review request is its approval
path.
Other agent bundles that combine Action Review-only correspondence rules with
evidence-gap packages but no disposition package are refused with
agent_rules_need_their_own_bundle; submit those rules and evidence gaps separately.
When an agent bundles a disposition package it staged earlier with
propose_finding_disposition_package, the bundle adopts that package’s pending
Action Review request if the same agent asked for it on behalf of the same
human. The earlier request is withdrawn and the composite bundle request
replaces it; data.action_review.adopted_package_requests lists the withdrawn
proposal IDs. If a member request belongs to someone else, was already decided,
is carried by another bundle, has no conversation-thread origin, or is denied
by package policy, the whole bundle is refused before staging. A request made
without a conversation thread—for example, when a person selects Ask for
approval again on the package page—cannot be taken over by the bundle and is
reviewed on its own. Check
refusal.detail.rule: package_approval_owned, package_approval_decided,
package_in_other_bundle, package_policy_denied, or
package_request_not_adoptable; leave that package out and propose again. If
creating the composite request fails before it exists after adoption, the freshly staged
bundle is withdrawn and the error reports withdrawn_package_requests and
bundle_retracted; the member packages can then be asked for again or included in a new
bundle. If insertion succeeds but reading the composite back fails, the bundle remains
staged (bundle_retracted: false), and the unavailable result names its proposal_id
when known and lists the adopted IDs in withdrawn_package_requests. Repeat the same
proposal to read the existing request; do not stage a duplicate.
evaluate_estate_correspondence_rule
Report whether a proposed estate correspondence rule passes its own accept
and reject fixtures before handing it to a human. This is a report-only check:
it records no qualification evidence, advances no provenance tier, and cannot
ratify the rule. For transition-contract artifacts, use
qualify_transition_contract_rule instead.
The response includes
fixtures_pass, fixture_count, failed,
untested_claims, per-fixture results, the rule’s current provenance, and
qualification_recorded: false. fixtures_pass is true only when every
fixture passes and every claim has a boundary fixture; failed counts fixtures
that did not hold, while untested_claims names claims that have no boundary of
their own. This distinguishes a rule with a failing fixture from one whose
fixtures pass but do not exercise all of its claims. It also returns
ratification_url and actionable; when diff_hash is omitted, actionable
is false and blocked_by explains that the worklist controls are disabled
until a comparison is pinned. This tool evaluates only estate rules; an
artifact hash from the transition-contract registry is refused as the wrong
identifier family.
Stimulus design and compile run summaries disclose the schema-gate evidence in
schema_validated, schema_validation, and measurement_incomplete_objects.
The gate runs only when the boundary snapshot has complete catalog enumeration.
An indeterminate object still contributes its catalog column names when the
snapshot was produced by measurement library version 7 or later; older
indeterminate snapshots require re-characterization and report
skipped_legacy_indeterminate_snapshot. Other possible schema_validation
values are validated, validated_incomplete_measurements,
skipped_incomplete_enumeration, and skipped_no_schema. When the gate is
skipped, structural validation remains active, but table or column absence is
not mechanically validated.
register_execution_profile
On success, the tool returns
success, profile_id, and created_by. The
created_by value is the identity recorded on the profile, which stays the first
registrant’s. The response also includes attributed_to_another: false when the stored
creator is the caller, and null when the record names nobody. A missing caller or a
record with no named creator is returned as created_by: "unattributed"; do not describe
that profile as belonging to the caller.
A profile recorded under a registrant is registered over by that registrant only. A call
by anyone else for the same profile_id returns success: false with
error_kind: "profile_registered_by_another" (or
"prepared_profile_registered_by_another" for a profile prepare_migration_prover
registered), names the registrant, and stores nothing, whatever the call would change.
Register the profile under a new profile_id instead. A profile whose record names nobody
can be registered over by any caller, unless prepare_migration_prover registered it.
During validation, an island table name may be bare, schema-qualified
(schema.table), or database-qualified (database.schema.table). Qualified
names retain every segment for both island-row counting and cleanup. Names with
more than three segments are not addressed.
For postgres_dbt, payload.dbt_env maps environment variable names to literal
values or templates using {host}, {port}, {user}, {password}, and
{dbname}. Genesis fills those placeholders from the source connection and
sandbox database. Profile setup refuses any other placeholder before saving;
the adapter also checks persisted profiles before a run. Write other values
literally, and double braces ({{ and }}) when the value needs literal
braces. During stimulus replay, a row that supplies a value for a
GENERATED ALWAYS identity column is inserted with that value. Genesis advances
the identity sequence to that value when it is at or beyond the next sequence
value and within the sequence maximum; otherwise the sequence is unchanged.
Rows that omit the identity value continue to use the generated value.
For csv_sql, the payload requires repo_id, csv_files (a non-empty string
map), and transform_sql (a non-empty string map). For
databricks_repo_sql, it requires catalog, sandbox_catalog, repo_id,
source_tables (a non-empty string-array map), and model_sql_files (a map of
non-empty strings or non-empty string arrays). Optional table_map values must
be schema.table names declared in source_tables. The optional
managed_location payload value is an explicit mission override; when it is
omitted, the guarded adapter can use the target Databricks connection’s
non-secret prover_managed_location_root for the sandbox catalog.
For databricks_job, the payload is target-only and requires job_id (a
positive integer), job_hash_contract_version (currently
estatechar.databricks_job.settings.v1), job_settings_sha256, run_as,
deployed_assets (an absolute Workspace notebook path to SHA-256 map),
landing, input_files, parameter_bindings, task_dependencies, and
task_outputs. run_as names exactly one service_principal_name or
user_name. The landing scheme must be databricks_volume.
The optional mode is selective or monolithic; an omitted mode remains
selective for compatibility with existing profiles. Selective mode is the
purpose-built harness contract. It also requires output_catalog and
output_schema, which must match the landing catalog and schema, and requires
exactly five distinct parameter bindings: landing_path, output_catalog,
output_schema, campaign_token, and requested_models. The adapter sends
requested_models as a compact JSON array encoded in a Job parameter string,
for example ["dim_customer","fct_order"], and reads token-prefixed output
tables.
Monolithic mode runs the customer’s complete existing Job DAG with normal fixed
output names. It requires exactly the three generic bindings landing_path,
output_catalog, and output_schema; Genesis never sends campaign_token or
requested_models to the Job. The shipped Job must already expose those generic
locations. A Job with hard-coded input or output locations, including a Job with
no parameters, is not supported. The pipeline must rebuild its outputs from the
staged input; pipelines requiring pre-existing target state need a different
execution contract. fixed_output_tables must map every logical
model in the union of task_outputs to a unique, safe, unqualified physical
table name. Monolithic profiles must not provide the selective-only
output_catalog or output_schema fields. The output catalog comes from
landing.catalog; landing.schema must match <base>_(stim|eval) with an
optional _<suffix> so Genesis can derive and guard a unique campaign-owned
schema.
The profile runs an already-deployed multi-task Job rather than uploading or
rewriting it. Before provisioning and again before submission, Genesis verifies
the pinned execution-affecting Job definition, the declared Workspace notebook
hashes, the static %run dependency graph, the task DAG, and the required Job
parameter bindings. Selective mode retains its existing rule that every task and
task notebook consumes every binding. In monolithic mode, root tasks must consume
landing_path, tasks owning declared outputs must consume output_catalog and
output_schema, and the task and asset unions must cover all three roles. Other
tasks, such as downstream quality or notification tasks, need not reference
parameters they do not use. Every target model must appear in exactly one
task_outputs entry, and task dependencies must form an acyclic graph.
Monolithic v1 accepts only one consolidated stimulus group and no ordered
groups. Genesis refuses any other plan before provisioning because a complete
rebuild applies cumulative landing rows to every candidate output while the
selective source oracle’s terminal per-output baselines come from different
steps. Comparing those states under terminal collapse would create false
failures. Each accepted run executes the full declared DAG, regardless of the
logical models named by the planner, and records planned_models with
execution_scope: all_declared_outputs.
For monolithic isolation, Genesis acquires a unique schema with CREATE SCHEMA
without IF NOT EXISTS, records ownership only after creation succeeds, and
passes the campaign landing path, catalog, and owned schema through the generic
bindings. A collision therefore fails rather than assuming ownership of an
existing schema. Successful teardown drops only the recorded owned schema with
CASCADE; a failed submitted campaign retains that schema and its landing for
diagnosis. Teardown never drops a schema whose acquisition was not recorded. If
submission never occurred, an acquired empty schema can be removed safely.
A run is accepted only when the pinned Job and every task finish successfully
with complete output evidence; failed, incomplete, or unverified runs are not
accepted as migration proof. Observations remain keyed by logical model and
record both the logical relation and the physical isolated
execution_relation. Models without a stimulus specification are listed in
unobserved_declared_outputs rather than presented as validated.
A monolithic verdict proves the approved shipped Job settings, identity, and
Workspace assets ran unchanged over redirected generic locations. It does not
cover production table instances, production storage permissions, undeclared
outputs or side effects, hard-coded checkpoints or locations, external-system
writes, shared filesystem paths, schedules or overlapping non-Prover runs,
unsupported task types, or dynamic notebook launches. Every planner execution
runs the complete DAG, so this mode can cost substantially more than selective
execution. The connection principal also needs Job execution, Workspace export,
Volume access, SQL read, USE CATALOG, CREATE SCHEMA, and schema-drop
privileges in the sandbox catalog. Failed campaign schemas may contain all
pipeline outputs and can therefore have material retention cost. Jobs whose
definition or run-evidence arrays exceed the Databricks 100-element response page
are not supported until Genesis aggregates Jobs API 2.2 pagination for both Get
Job and Get Run.
To author a databricks_job profile without guessing the pinned values, call
preflight_databricks_job_contract with the deployed job_id and its stored
connection_ref first. Copy its job_settings_sha256,
job_hash_contract_version, canonical run_as, and parameter_formats into the
profile. The returned parameter formats describe the five required semantic roles:
landing_path is the staged Databricks Volume URI, output_catalog and
output_schema identify campaign-owned outputs, campaign_token qualifies the
campaign’s outputs, and requested_models must receive a compact JSON-encoded
array string such as ["model_a","model_b"], not comma-separated values. If the
Job has no explicit run_as, the response returns run_as_absent and an instruction
to set one before preflighting again. If its live identity cannot be represented by
the profile’s single service_principal_name or user_name, the response returns
run_as_unpinnable and explains the required correction. Set
include_projection to true only when the full canonical settings projection is
needed for review; its default is false.
The failed-campaign retention record reports what teardown verifies, not only
what the campaign intended to create. The landing record includes
status: "retained" when the campaign-owned Volume path contains a staged
file, or status: "absent" when it does not; nested landing directories are
checked as needed. The output record includes a relations map whose values
are "retained" or "absent" for each targeted output relation. If a landing
or output verification probe fails, the record includes verification_error
instead of claiming that the resource is absent. Output verification checks
the expected relations together in one catalog query: targeted token-prefixed
relations in selective mode, and every declared fixed output in monolithic mode.
For snowflake_sql, a repository-backed target can replace deployed_sql with
repo_id, model_sql_files, table_map, and target_grains. The four fields
are required together, and the payload must not include deployed_sql. Each
target model must name exactly one repository-relative UTF-8 SQL file containing
one self-contained Snowflake SELECT query; paths must remain inside the Mission
repository. table_map maps each onboarding stimulus input to a
schema.table base table, and target_grains declares the ordered key columns
for each target model.
For repository-backed Snowflake targets, table_map values and
target_grains columns resolve against Snowflake’s stored relation and column
names: an exact spelling wins; otherwise the plan name must match exactly one
stored name after folding ASCII letters only. Missing or ambiguous matches
refuse validation. This lets a PostgreSQL plan’s lowercase unquoted names
resolve to Snowflake’s uppercase unquoted names without treating non-ASCII
look-alikes as the same identifier. In dbt-backed Snowflake execution, the same
rule applies to stimulus column names.
Before cloning the target, Genesis reads the live target columns and primary-key
metadata and checks that every declared grain exists, matches an existing
primary key when one is present, and is unique and non-null in the live data.
During execution, the adapter loads stimulus rows into the declared source
tables, retargets the reviewed repository SQL into the campaign sandbox, and
records the SHA-256 of each SQL file actually executed. The adapter also returns
the observed live target metadata in execution evidence; onboarding validation
rejects a run when required execution evidence is empty.
For mssql_sql, the payload requires database and sandbox_prefix. This
source-only adapter supports SQL Server 2022 (major version 16) on Linux and
requires a sysadmin connection using the ODBC driver (pyodbc). SQL Server
connections made inside a Databricks App use pymssql and cannot run this
sandbox adapter. During each validation run it takes an
on-instance COPY_ONLY backup and restores it into a generated sandbox database
whose name starts with sandbox_prefix; the live database is not used for
writes. The adapter tears down the generated database and backup resources when
the run finishes.
For bigquery_sql, the payload requires project, dataset, and
sandbox_prefix; it optionally accepts deployed_sql, a string map of model
names to deployed query text for materialized targets. The
connection_ref must resolve a BigQuery connection whose project matches
project. This source-only adapter preflights the configured dataset, creates
an owned per-run sandbox dataset whose name starts with sandbox_prefix, and
clones its tables while recreating logical views with references retargeted to
the sandbox. Materialized targets use their deployed_sql in the sandbox;
logical views re-derive from the cloned source objects. Stimulus rows are
inserted only into tables declared by the source descriptor’s schema_columns
(using dataset.table names). Use bigquery_sql only as source_profile, not
as target_profile. The live dataset is not written, and the owned sandbox
dataset is deleted when the run finishes.
For snowflake_sql, the payload uses database for the live database and an
optional sandbox_database as the guarded sandbox base. When omitted,
sandbox_database defaults to a derived base such as <database>_STIM; each
validation run appends an uppercase random hexadecimal suffix to create its own
throwaway zero-copy clone. Target views and their upstream view dependencies are
recreated from immediate GET_DDL metadata with fully qualified live-database
references rebound to the clone, so injected stimulus is visible to the views.
Cloned SQL UDFs that qualify the live database are likewise recreated with the
sandbox qualifier; their bodies are edited in place, so escaped literals in the
body are preserved. When a target view or dynamic table calls a cloned SQL or
JavaScript UDF, the purity check follows scalar UDF calls transitively; every
called UDF must be provably sandbox-local before validation proceeds.
The live database remains read-only. Provisioning fails closed for degraded view
definitions, external or dynamic object references, stage references, and other
dependencies whose sandbox locality cannot be proven.
For a view target, table_map can map the relation named in the stimulus spec
to its deployed Snowflake relation in the live database. For example,
{"OLD_SCHEMA.V": "NEW_SCHEMA.V"} lets a rewritten view sit beside the
original; the adapter validates and recreates NEW_SCHEMA.V in the sandbox.
When a Prover estate comparison uses this run to license the rewritten view, the
proof must match the compared source and target view pair; matching database sides
alone does not let a proof of another rewrite license it. See fresh licensing
evidence.
For repository-backed targets, table_map retains its separate role of mapping
stimulus inputs to declared base tables, as described above.
When both sides resolve a tested view to the same live object on the same
connection and database, preparation and validation runs refuse the pair and
name the view. Non-rehearsal trajectory campaigns refuse it too; rehearsals
intentionally skip this check because they run the source against a second copy
of itself. Map the rewritten view in the target’s table_map, or point its
database at the one that holds the rewrite. A view is always rebuilt from its
own live definition, so a profile that gives a view deployed_sql is refused
when the run finds the object is a view; deployed_sql is for base tables only.
A view target may also read ordinary base tables from other databases when each
profile declares the needed tables in source_tables or copied_tables. Both
fields are optional maps of DATABASE.SCHEMA to non-empty arrays of table names,
using plain identifiers; the same table cannot be declared twice. These fields
are for view targets only and cannot be combined in that profile with
deployed_sql or model_sql_files. Only listed tables are provisioned. The
adapter creates a <DATABASE>__<SCHEMA> schema inside the sandbox database and
rewrites the view reference to that schema. It zero-copy clones source_tables;
use copied_tables for a base table that must be read and copied in full on each
run, such as a table exposed through a share. This full read and copy adds
per-run work proportional to the listed tables’ data.
Only ordinary base tables are accepted under either field. Views, streams,
dynamic tables, Iceberg tables, and hybrid tables are refused. A view reference
to an undeclared external table, or a function call into another database, is
also refused. For stimulus cases that write one of these tables, name it by its
live three-part relation (DATABASE.SCHEMA.TABLE); each participating Snowflake
profile must declare the tables its rows use. A row must supply any column whose
default cannot be proven sandbox-safe, including a default that names a sequence
outside the sandbox. View definitions, dynamic tables, verified functions, and
deployed_sql queries that use NEXTVAL or GETNEXTVAL are refused, because
evaluating them would advance a sequence.
The optional model_invocations payload value is an object mapping each model
name to one non-empty T-SQL batch or an array of non-empty T-SQL batches. A
mutable base-table model must declare an invocation; a view model must not.
Each invocation must call a schema-qualified stored procedure copied from the
source database and is limited to orchestration SQL. It cannot use data-change
statements, dynamic SQL, transaction or session control, GO, external
cross-database references, or global temporary objects. In
prepare_migration_prover, the
source descriptor still requires schema_columns as described below, and
mssql_sql can only be supplied as source_profile, not target_profile.
preflight_databricks_job_contract
Read the profile-ready execution contract from one deployed Databricks Job before
authoring a databricks_job target profile. This performs one or more Databricks
REST calls, depending on the number of Job response pages, and does not modify the
Job. The read follows the Jobs API 2.2 next_page_token until the complete Job is
available; an incomplete response is refused rather than hashed or pinned.
The response includes
job_settings_sha256, job_hash_contract_version, and the
runtime parameter_formats. It returns a canonical run_as when the live Job
identity can be pinned by the profile contract. Otherwise it returns either
run_as_absent or run_as_unpinnable, together with an instruction for correcting
the Job and running the preflight again. Use the returned values when filling the
databricks_job payload described in register_execution_profile.
Example:
prepare_migration_prover
Each profile uses the tagged shape
{adapter_kind: {connection_ref, payload}}.
Source payloads also require schema_columns, a non-empty map from logical
table names to non-empty arrays of non-empty column names. Each stimulus spec
requires schema_version: "1", spec_kind: "estatechar.stimulus_spec.v1",
target_node, output_relation, stim_predicate, and cases; each case
requires case_id, rationale, tags, and rows. A row’s table must match
a declared schema_columns key. For a csv_sql source paired with a
databricks_repo_sql target, the target-node suffix must also exist in both the
source transform_sql map and target model_sql_files map. In that pairing,
each output_relation must be a schema.table string; the model keys in both
maps must remain the bare target_node suffix rather than a physical table name.
Case ids define stimulus-spec ownership. A spec’s identity is its target_node
plus the set of its case ids, so multiple specs may target one node when they
cover different case sets. Case ids must be unique within a spec and cannot be
claimed by two different specs for the same target. Within one submission,
combine cases into one spec instead of submitting the same identity twice. To
re-author an existing spec, submit the same target and case ids; the new version
supersedes the previous one. Distinct identities remain stored and are all kept
in the effective boundary set.
If a stimulus batch includes machine-checkable expected_target_deltas, each
vector needs mart, key, column, and a scalar target_expected; use
source_expected: null for a target-only check. A vector defaults to
value_basis: "absolute" under a resolved contract only when the key columns
exactly match one declared input table’s entity_key and every value is at or above
that table’s inclusive island floor. Otherwise set value_basis explicitly to
"absolute" or "delta"; the vector is not checkable without it. Contract-less
shopbench behavior remains the legacy id-shaped-key rule with the reserved range
(>= 900000).
File-fed pipelines (file_python_oracle)
A pipeline driven by a batch of landing files, rather than by rows in a table,
uses the file_python_oracle source kind. Its payload declares landing (the
scratch location a batch is staged into), input_files and declared_outputs
(each a map of logical name to {path, format, columns}, with types also
required on outputs), and oracle — the reviewed program that executes the
transform, pinned by sha256 so approval binds to an exact artifact rather
than to a repository path. oracle.modules pins every other repository file the
program may import, each by digest. Only the entrypoint and those modules are
staged into the campaign’s own directory, and the subprocess runs from that copy
with PYTHONPATH pointing at it — so the approval covers the whole executable,
and importing an undeclared repository file fails rather than silently widening
what runs.
Two guarantees are structural rather than advisory. The landing.prefix must
carry a stim or eval marker, so a batch can never be staged into the
standing prefix a live pipeline already reads; and each run stages beneath its
own campaign-token directory. validate_migration then binds the target to the
sequence of landing manifests the source recorded, so a target whose staging is
not byte-identical fails before its transform runs.
Preparation also checks the PAIR, not only each profile: a file-fed source needs a target
kind that can bind a landing manifest, such as databricks_job, so pairing one with a
row-injecting target is answered unsupported rather than failing mid-campaign.
oracle.assurance is either direct_runtime or reviewed_clone. A reviewed
clone must also declare stands_in_for, naming the original system it stands
in for; the run record then carries an explicit limitation saying the campaign
does not cover that runtime. Only a local_scratch landing is stageable today.
A profile naming an object-storage or Unity Catalog volume landing is answered
with status: "unsupported" and the exact missing capability.
The preparation call fails closed for unsupported fields, invalid adapter
values, credential-like payload keys, missing metadata, mismatched CSV schema
keys, or missing models. It returns status: "ready" only when both profiles
pass the capability preflight; otherwise it returns status: "unsupported"
with missing_capabilities and persists nothing. On success, ask for the test
cases to be approved with request_test_case_approval, then pass the returned
profile ids to validate_migration; do not call it after a failed preparation
response.
Readiness also requires every submitted stimulus spec to be verified in storage
for the returned boundary. If the store contains fewer specs than were submitted,
the tool returns success: false, ready_for_validation: false, the boundary_hash,
and the specs_registered list instead of claiming readiness. A spec whose identical
content is already stored under a different boundary is rejected during the
submission check; change its content or reuse the boundary it belongs to. A ready
response includes stored_spec_count alongside specs_registered.
When pipeline_validation is supplied, preparation binds the reviewed pipeline
contract into the reusable source/target boundary. See Pipeline migration
proofs for the
state-check semantics and verdict rules.
When preparation is ready, the response also includes created_by, mapping
source_profile and target_profile to the identities stored on those profiles, and
attributed_to_another. The latter is true if either profile names somebody else,
false if both name the caller, and null when neither names another person or a
profile creator could not be read back. A profile with no named creator is shown as
"unattributed"; use these fields when reporting who registered the profiles rather
than echoing the current caller.
When view_pairs is supplied, a ready response also includes each pair’s claims summary
and fix suggestion, without view text or outlines. Claims are informational and do not
change preparation readiness; see logic-path coverage claims
for the design and check-only workflow. A malformed pair is refused before preparation
stores any profiles or specs.
validate_migration
Run the prepared behavioral migration proof with the same designed stimulus
cases against the source and target profiles. Both live estates remain
read-only; proof writes use throwaway sandboxes.
A run uses only test cases a person approved in Action Review.
validate_migration, run_trajectory_campaign and qualify_stimulus_campaign
check this once, when the run starts: if a view’s test cases are not all approved
and unchanged, the run injects nothing and returns success: false with a
refusal that names the view and says what to do. A person with
ratify_source_contract approves them; with sign-in off they are approved at once
when the agent asks, and marked as not reviewed by a person.
The check compares the cases the run will fold with the complete current set for
that view and boundary. It also refuses when those cases disagree on their stored
output relation or condition, or when the run would mix boundaries or use cases
stored without one. A reused baseline that pins only some of a view’s current cases
is refused too; approve the current set and run without baseline_trace_hash to
record a new baseline. The refusal has kind test_cases_not_approved and a reason:
not_approved, outputs_disagree, not_current, other_boundary,
view_gained_test_cases, stored_without_boundary, approved_for_other_profiles,
approval_record_unreadable, or approval_not_finished (an approval of the test cases
was started and is not recorded as finished; have it reconciled in Action Review).
Test cases prepared with prepare_migration_prover are approved for the source and
target profiles it registered. A run must use that source profile as its source and that
target profile as its target, each unchanged since the approval; any other profile is
refused with approved_for_other_profiles, even one on the same connection. After
preparing the same pair again with other settings, ask for approval of the same test
cases again with request_test_case_approval: the new request covers every prepared
profile standing for the pair and lists them.
Text stimulus values use the registered dialect’s quoting rules for the engine
that runs the insert. If an engine has no registered dialect, a text value with
a backslash is rejected rather than rendered using an assumed escaping rule.
When this tool is called from a mission, its Prover progress is recorded with
the mission and is available live or through the mission replay. For the live
panel and phase proof cards in Document Flow, see Prover progress in
missions.
Before starting validation, the tool checks that the caller can see both execution
profiles and, when supplied, the baseline trace. For a caller-scoped request, every
connection named by a profile must be visible; a profile with no connection references is
visible only to someone who administers every connection. A hidden or missing profile
returns
unknown execution profile: <profile_id>, and a hidden or missing trace returns
unknown baseline trace: <trace_hash>. Neither case starts a validation run.
When a Prover estate comparison uses this run to license a rewritten view, each profile must
identify the same database side as its comparison snapshot; matching connections alone is
not enough. See Genesis Prover for the side-matching rules.
The response includes the validation result, run_id, stage, reproducibility,
validated-model and case counts, findings, and source/target trace hashes. When
run_id is present, it also includes run_detail_url, which opens the exact
run’s verdict and per-case evidence in the validations view. This link is
provided for both clean and finding-bearing runs, including a failed run that
records the stage where it stopped.
Verdict rules and withheld-output semantics are covered in Pipeline migration
proofs.
For a prepared pipeline contract, the result includes the pipeline execution
evidence and state_checks described in Pipeline migration
proofs.
When the target executes a remote job, the response also includes
execution_runs: one entry for the bootstrap run and one for each plan step.
Each entry contains step, databricks_run_id, job_id, result_state, and a
tasks list. Each task contains task_key, run_id, and result_state, so a
finding can be traced to the Databricks job and task that produced its output.
Adapters that do not submit a remote job do not add execution_runs.
Databricks run evidence follows every Jobs API 2.2 Get Run page before building
the task list. If the response still carries next_page_token after pagination
cannot complete, validation returns success: false and does not write an
evidence report whose task count could understate the run.
If the validation fails after submitting a remote job, the response includes
execution_run_ids when available. It maps source and/or target to the
last Databricks run id submitted for that side, including when the active run
has already been released.
When run_id is present, the response also includes human_review_url, which
opens Human Review for this exact validation run with
?view=review&validation=<run_id>. It is present for both clean and
finding-bearing runs, so show both run_detail_url and human_review_url to
the user. Do not construct the address or substitute a diff-shaped link:
migration validation compares two transforms against the same designed
stimulus, rather than two characterized estates, and ?view=review&diff=<hash>
opens the wrong comparison route.
Findings returned by a run that was recorded before durable finding keys were
introduced can still be read in the run detail and Human Review views, but
those findings do not include finding_key and cannot receive a recorded
diagnosis. Do not report a ruling as saved for such a finding.
get_migration_findings
Fetch the finished summary and localized findings for one run returned by
validate_migration.
For a migration-validation run, the response returns
success: true, the
persisted summary in run, and the same run_detail_url and
human_review_url handoff fields described above. An unknown id or an id for
another run type returns success: false with an error and no link.
The returned terminal run record also exposes outcome beside status: read
PASS, FAIL, INDETERMINATE, not_verified, no_findings, or sealed rather
than inferring the decision from lifecycle status.
Behavioral validation findings expose structured row selectors and measured
source/target values; see the estate findings API reference
for the evidence fields and missing-row semantics.
migration_intake_tools
Use this group to start a migration plan from chat. ask_migration_connection
presents the person’s connections as a card when the source or destination is
still open; find_migration_pipelines reads lineage metadata for the source
database and presents a card of candidate pipelines; propose_migration_plan
binds the selected scope and presents an approval card;
get_approved_migration_plan reads the full approved boundary.
The intake and plan-reading calls do not run or modify a pipeline. After approval,
start_migration starts eligible plans as a Mission in the approving chat. These
tools require a signed-in person; plan approval is carried by the card’s Approve
and start action, not by a typed confirmation. For the wizard flow and migration
stages, see Database migration blueprints.
start_migration launches in goal mode from Plan, and start_onboarding launches
in goal mode from its first phase. For mode behavior, see
Blueprint Library and Missions.
When a user chooses Not sure? Continue with Eve in the Launchpad migration
wizard, the handoff includes the choices already made and the remaining questions.
Keep those choices, resolve each name (Platform) to its registered connection
id, and continue with the first unanswered question; do not ask for a choice
again. If the handoff includes a [BEGIN MIGRATION PIPELINE CHOICE] block, use
its exact pipeline_ids in propose_migration_plan and do not present the
pipelines card again. Pipelines the user points out manually cannot be bound from
chat; explain that and offer the pipelines found through lineage instead. For
the user-facing wizard and card behavior, see Migrate data and
pipelines.
ask_migration_connection
The response always includes
connections (connection_id, name, type).
With card=true, it also includes a presented card of those connections
grouped by platform, with search and a way to add a new connection; with
card=false, presented is omitted. A source request includes database connections the
person can see and pipeline-service connections the person and selected agent
may use; the source card offers up to 40 of those additional pipeline-service
connections. Foundry is already listed as a data source. Destinations remain
database connections, and the destination card offers a plan-only choice. A
destination response also includes presented.new_container: terms maps each
listed data-connection type to its container word (catalog for Databricks,
dataset for BigQuery, and database for other types), while default_term is
database. The destination card uses this offer to let the person name a new
container inside a listed connection. Ask for the source first; when asking for
the destination, pass the chosen source’s connection_id as
source_connection_id so it is omitted from the choices. A connection click sends
one line naming the pick, such as “Migrate from etf_vignette (PostgreSQL).” for the source or
“Migrate to lakehouse (Databricks).” for the destination; a new-container click
names the listed connection and the container to create, for example “Migrate to
lakehouse (Databricks), into a new catalog foundry_migration.” A typed answer
works too. A plan-only destination sends “Plan only, for Snowflake — there’s no
connection yet.” and continues with target_platform: "snowflake". Each call
reads the registered connections; the source lookup also checks which additional
pipeline-service connections the person and agent may use. The response’s next.activate names
manage_context(action='ADD_CONTEXT', active_skills='plan-data-work'); when the
skill is not active yet, make that activation in the same turn so the chat route
and its pipelines and plan cards are available.
When the destination is a new catalog or schema in a listed connection, pass
the chosen connection as target_connection_id and the requested catalog and
schema as target_database and target_schema to
propose_migration_plan. These fields select the namespace but do not create
it; create the catalog or schema before the data moves. For the user-facing
answer behavior, see
Migrate data and pipelines.
find_migration_pipelines
For a database source, the response includes grouped pipelines, their
read/write tables and code locations,
unproduced_tables, lineage_available,
notes, and a presented pipelines card. Pass the kept pipeline_id values to
propose_migration_plan. If lineage is unavailable or finds no pipeline, a
data-only plan is still possible. The lookup reads the Context Graph and is
bounded to 45 seconds; an older graph can require table-by-table reads.
For a pipeline-service source, the tool does not query database lineage or
return a pipelines card. It checks that the person and agent may use the
connection and returns a next.why handoff instead. For Foundry, activate
palantir_foundry_tools,palantir_foundry_migration_tools and follow the Foundry
migration tools’ next_step instructions; that workflow writes to Databricks.
For Airflow, Astronomer, or MWAA, activate airflow_tools; for dbt Cloud,
Matillion, Airbyte, or Fivetran, activate dbt_cloud_tools, matillion_tools,
airbyte_tools, or fivetran_tools, respectively. Inspect the pipelines, then
continue the migration intake with the database warehouse they load. If Genesis
has no tools for the selected pipeline service, ask which warehouse its
pipelines load and continue with that database connection.
propose_migration_plan
The plan response includes the selected objects and their roles, destination,
pipeline list, candidate row keys and their basis, Prover checks, applied
defaults, notes, and the checksummed bound scope. Proposing performs bounded
Context Graph and source-catalog reads and writes the scope record. Only the
approval action on the presented plan card approves it. Use
get_approved_migration_plan with the approved server_scope_id to read the
complete bound object and pipeline lists.
get_approved_migration_plan
Returns the checksummed source and target boundary, selected objects and
pipelines, pinned code revisions, target namespace, naming and runtime. Only the
person who approved the plan can read it, while they retain access to its
connections.
start_migration
Call with no arguments on the turn carrying the plan card’s Approve and
start action or a Launchpad hand-off. A typed “yes” is not approval and starts
nothing. The response includes the Plan phase instructions; follow them. See
Approved chat migration blueprint
for the phases and supported-plan rules.
The tool reads the approved scope record, checks visibility for each bound
connection, and checks the
ratify_source_contract permission. On success, it
creates the Mission project, Git repository, and thread properties, then enters
the Plan phase. A typed approval or a second plan cannot restart an existing
migration; start a new chat to run another plan.
Example: on the approval turn, call start_migration() with no arguments. The
response includes the Mission details, Plan phase instructions, and the approved
plan’s server_scope_id.
onboarding_intake_tools
Use this group when Eve is onboarding raw or bronze tables into an existing
silver table with the bronze_to_silver_onboarding blueprint. The tools present
the connection, raw tables, target table, and approval plan as chat cards; they
do not map or load data themselves. All database lookups run as the signed-in
person and read their visible connections or live catalog. For the chat flow,
see Onboard raw tables.
ask_onboarding_connection
The response includes every database connection visible to the person and a
card grouped by platform, with search and a way to add a connection. Each call
reads the registered database connections. Once the connection is known, use
find_onboarding_tables.
find_onboarding_tables
The call reads the live catalog: it may read the database list, reads schemas,
and reads each listed schema (up to four). The response includes table names as
catalog.schema.table (up to 200), schemas, connection details, and a card with
checkboxes for source tables or a single target-table choice. After both picks,
call propose_onboarding.
propose_onboarding
This call validates the picks against the live catalog, querying each named
schema. Its response includes the plan and a card with the workflow steps and
approval controls. Only Approve and start approves; typed confirmation does
not. The card’s load option is enabled by default. Use this tool again when the
person changes picks or supplies the documents folder.
Example:
start_onboarding
Call with no arguments on the turn the person presses Approve and start on
the plan card. It reads the approved picks from that turn, confirms the person
still has access to the source connection, and starts the blueprint as a
Mission in the current thread. A typed “yes” or “go” does not start it. If the
thread already has an onboarding Mission, another approval does not replace its
original picks.
migration_prover_tools
Use migration_prover_tools when a migration validator needs to design, prepare,
run, and inspect a behavioral data-migration proof with approved stimulus cases,
including the behavior proof of a rewritten view. For proving a migration by
comparing two estates and grading a spec, use prover_tools instead. This group
contains design_stimulus_campaign, prepare_migration_prover,
preflight_databricks_job_contract, validate_migration, and
get_migration_findings; it is not always-on. See
the detailed tool definitions above for the required credential-free profiles,
approval flow, and validation findings. Its answers carry the same agent-audience
marker described under prover_tools.
measurement_tools
Freeze portable records of database estates, read them back, declare how two
frozen estates relate, and compare them — without opening live database
connections for the compare step. This group is not always-on; agents
receive it when a migration or measurement workflow needs it.
Permission gate: every tool in this group requires manage_all_connections,
including reads. Frozen records and qualification reports can disclose per-column
value evidence from customer estates. The in-app measurement tabs under
Migration verification use the same gate via
/api/transition_contract/measure/*.
Relationship to transition_contract_tools: transition-contract tools
compile and execute governed verification runs against live estates with a rule
registry and human ratification. Measurement tools work on frozen records
already stored in the registry. For ad-hoc keyed spot checks without the
transition-contract registry, use verify_against_contract from
system_diff_tools instead.
characterize_and_freeze_estate also closes a run when its background hand-off is
refused. The response carries success: false, the run_id, and status: "error";
if terminalization fails, it adds terminalization_failed: true and reports that the
row may remain running until startup reconciliation.
characterize_and_freeze_estate
Returns immediately with
run_id and status running. Poll get_measurement_run until terminal. A succeeded run includes frozen_contract_hash for render_frozen_contract and diff_frozen_contracts. The frozen record’s created_by is the signed-in user, or unattributed when the turn has no signed-in user; attested_by remains the separate claim about who asserted quiescence. Read the author from render_frozen_contract rather than treating attested_by as the record author.
declare_measure_correspondence
The caller does not provide
declared_by. Genesis records the declaration on
the signed-in user’s identity and, on a bot turn, includes the acting agent in
that recorded principal. A scheduled or bot-only turn without a signed-in user
is refused with refusal_code: "NO_HUMAN_PRINCIPAL" and stores nothing.
Successful responses include correspondence_hash, declared_by, and
declared.
diff_frozen_contracts
Read
object_pairing before the counts in the response. An unverified declaration licenses no comparison — covered regions come back indeterminate.
See Data Explorer — Measurement tabs and measurement endpoints for the operator UI and REST equivalents.
user_memory_action_tools
Manage durable per-agent user memory and one-on-one checklist progress during
onboarding and weekly check-ins. Genesis auto-admits this tool group (via the
access-onboarding and one-on-one-checkins guidance skills) whenever an
onboarding or one-on-one session is active, so the lead agent can persist
checklist updates with SET_ONE_ON_ONE_CHECKLIST instead of stalling on
invented topic keys.
user_memory_action
SET_ONE_ON_ONE_CHECKLIST rejects unknown topic_key values. The error lists
the valid required or optional keys for the workspace so the agent can retry
with an exact match. Legacy aliases such as preferred_name and
language_preference are normalized to name_and_language in the required
section only.
Example:
snowflake_ai_tools
Access Snowflake Cortex AI capabilities from Genesis. In practice, this maps
most directly to Cortex Agent Tools,
Cortex Search Tools, and Cortex
Code workflows.
When an administrator has hidden the virtual System
Snowflake connection,
agent-facing Snowflake SQL helpers (_run_query_sqlapi, _run_query_async),
Cortex tools (_cortex_search, _cortex_agent), and Snowpark entry points
that default to connection_id="Snowflake" return success: false with
type: connection_disabled if the call targets that connection. Use a
user-created saved Snowflake connection id instead. Internal non-agent callers
are unaffected._cortex_code
Delegate repo-scoped coding and Snowflake-connected tasks to Cortex Code
(Coco) from inside a Genesis thread. The preferred flow is async:
action="submit" to start work, then check_status, get_results, or
send_message using the returned session_handle.
When the task text or failure output mentions
boto3, AWS SDK work,
EKS/Kubernetes, Helm, kubectl, AWS CLI, cloud deployment, or cloud
monitoring, _cortex_code can return agent_reminders,
sandbox_tools_recommended, and sandbox_tools_reference instead of
retrying blindly in the Genesis application container. Use sandbox_action
with backend="eks" or backend="k8s" and the
aws-eks-sandbox-operations skill for those workflows._cortex_code now applies prompt and response safety guards. Risky prompt
text or returned content that appears to expose host data or secrets can be
blocked with success: false, error: "Request blocked by safety policy.",
and coding_agent_safety_rejected: true. The same safety layer sanitizes
streamed session events before they are broadcast, and Cortex Code strips
ambient secret env vars such as AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN from the sandboxed process
environment._run_query_sqlapi and _run_query_async
These Snowflake SQL helpers execute SQL through the Snowflake SQL API.
_run_query_sqlapi runs the statement immediately, while _run_query_async
uses action="submit" and later polling with check_status or get_results.
If either tool returns
requires_confirmation: true, review the returned
classification and sql before retrying. confirm does not authorize
CATASTROPHIC operations, and multi-statement catastrophic work must be
split into single-statement calls so user_override applies to exactly one
operation.When the optional SQL intent-match guard is enabled, these Snowflake SQL
helpers can also return requires_confirmation: true with
severity: intent_mismatch when the planned SQL does not clearly match the
user’s latest request. In that case, wait for a fresh chat reply that
explicitly names the exact operation and target before retrying. confirm
or user_override can still be required afterward by the normal SQL safety
gate.org_health_tools
The org_health_tools group is the private, read-side loadout for the
customer-facing GenesisAuditor agent. It audits the deployment’s AgentSkills
packages, blueprints, and live agent activations against the pinned Genesis
Organization Model, then reports structural findings with source coordinates.
Only the GenesisAuditor identity can invoke this group; it is not discoverable
by other agents. Its separate org_health_fix_tools group proposes the auditor’s
fixes for a person to apply in Action Review; this read group has no configuration,
data-connector, or handoff tool.
The audit reads the deployment’s files and metadata. Run it once for a review and
use the returned summary for complete counts and rankings. By default, the audit
returns findings from organization content: content the customer authored or
imported. Use platform for Genesis-shipped content, or all for both content
universes plus findings whose provenance is unknown. Findings against a live agent’s
own configuration (agent:<agent_id>) are always organization findings because the
deployed configuration is administered by this organization, regardless of who
seeded the agent. The summary always reports all, organization, platform, unknown,
and hidden totals for findings and unclassified references, so you never claim more
than the requested scope shows. Do not present findings or unclassified references
from another scope unless the user asks about that content. The findings,
unclassified references, and co-load index can be paged when the response exceeds the
inline tool-output budget.
Every page re-runs the audit and uses audit_id plus the same scope to refuse a
continuation when the organization or visible audit lists changed between calls.
Skill activation findings use the runtime’s identity resolution order rather than
matching pins to package directories by name alone. A package’s SKILL.md
frontmatter name and supported compatibility aliases can resolve to that package;
when a package directory has the same name as a requested identity, the directory
identity takes precedence. Repository-backed skill specs are also checked by reading
their names from the existing skills/skills_repository.json file without creating
or seeding a repository. This prevents a valid frontmatter name, compatibility
alias, or repository-backed spec from being reported as a missing skill. If the
repository file exists but cannot be read or parsed, the audit reports a read gap
instead of claiming that no spec resolves the pin.
When the audit reads a Git-backed skill’s full document, it uses the package
already admitted for that read. With features.skill_revision_tracking off (the
default), it reads from that package’s checkout; when revision tracking governs
the skill, it reads from the pinned revision.
run_organization_audit
Run the organization audit for a requested content scope. No business data is queried
or changed, and this read-side operation does not modify audited artifacts.
The response includes the pinned doctrine name and hash, deployment and corpus
metadata, findings with
provenance, unclassified_references with each reference’s
file and line coordinates plus provenance, counts, summary, co-load totals, and
read_gaps when part of the deployment could not be read. Unclassified references
could not meet the analyzer’s evidence gate, so inspect them under the audit response’s
“could not classify — check these” heading rather than treating them as dead references
or defects. A finding that spans owners can appear in both organization and
platform scopes because each owner has a copy to act on. Use
get_organization_finding for the source behind a finding,
get_organization_co_load_set for one co-load breakdown, and
get_organization_skill for a complete skill document.
get_organization_audit_page
Continue one list from a response whose corresponding page reports
complete: false. This tool is also read-only, but it re-runs the full audit on
each call. Pass the same scope as the page being continued; the audit reference
and scope together identify the visible findings list.
If the inline budget cannot fit even one entry at the requested offset, the tool
returns an error rather than a cursor that cannot advance. The budget is controlled
by
tools.output_governor.inline_budget_bytes.
org_health_fix_tools
The org_health_fix_tools group holds GenesisAuditor’s fix proposals. Only the
GenesisAuditor identity can invoke it, and it never changes anything itself: each
tool files an org_health.fix.v1 proposal in Action Review, which always waits for a
person, even when admission policy would allow the action. The fix is applied only when
a person who may manage the target approves and applies it. The group is silent by
default (org_health.fix_mode), and only organization-owned content can be fixed. The
user must explicitly ask GenesisAuditor for a fix; an earlier audit finding is not
authority to propose one.
When a person applies a fix, Genesis re-checks the fix mode, the person’s right to
manage the target, and the target itself. It writes only if the target still holds
exactly the state the approved proposal expected. The execution receipt records the
state the fix replaced, so the fix can be reversed.
For fixes that edit a whole blueprint manifest or skill document, Genesis measures
the handler-known serialized proposal content before admission. If it exceeds the
org_health.proposal_payload_max_bytes ceiling, the fix is refused before an Action
Review proposal is stored. See Advanced Settings
for the 750000-byte default and fallback behavior.
remove_dead_skill_pin
Propose removing one skill pin from a target bot’s active_skills context default.
The proposal re-checks the current policy, skill corpus, aliases, specs, and the
agent’s live pin list, and keeps every other stored pin unchanged. Nothing changes
until a person applies it; applying repeats the proof and refuses if the agent’s pins
or skill access policy changed since the proposal. The response reports
pending_review and the action_review.proposal_id.
Proposing refuses when the identity is missing or incorrect, the fix mode is not
active, the requesting user may not manage the agent, the target cannot be
canonicalized, the doctrine or gate cannot be read, or the pin is not inert. See
Advanced Settings for the
configuration key and default.
admit_blocked_skill
Propose admitting one skill that an agent activates but its own skill access policy
excludes. Use this for an OH-AGENT-SAT finding after asking the user which of the
two honest resolutions they want: admit the skill with this tool, or remove the
activation with remove_dead_skill_pin. This tool changes only that skill’s
treatment in the access list; it never changes skill_access_mode or widens the
agent to all skills. Nothing changes until a person who may manage the agent applies
the proposal in Action Review. The response reports pending_review and the
action_review.proposal_id while it is waiting.
The proposal re-proves that the agent still activates the skill, that its policy
still excludes it, and that the skill would load after admission. It refuses for a
system seat such as
GenesisAuditor or Eve, an already-permitted skill, a skill the
agent no longer activates, or a name that resolves to no skill package. It also
refuses a repository-backed skill spec because that spec loads without a
SKILL.md body; author a skill package for the name or retire the spec instead.
For an allowlist, the proposal adds the skill name; for a denylist, it removes the
name. See Advanced Settings
for the configuration key and default.
repair_blueprint_skill_requests
Propose repairing every selected phase in one organization blueprint that requests
a skill which does not exist. Pass one entry in repairs for each missing skill:
omit replacement to remove the missing name, or provide an existing skill only
when the user explicitly chose that replacement. Omit phases to repair every
phase that requests the missing skill. The proposal re-checks the missing names,
replacement packages, blueprint source, and manifest before filing the edited
manifest for Action Review. Nothing changes until a person with permission to
manage the blueprint applies it.
The tool refuses a replacement that is not an existing skill package, a blueprint
whose source is remote or cannot be established as local, or a second proposal for
the same blueprint after the first has been applied. Applying the proposal rewrites
the manifest, so YAML comments in that manifest are not preserved; the prior text
is recorded so the fix can be reversed. Whether a replacement is admitted by the
agent’s skill policy is not checked. See Advanced Settings
for the configuration key and default.
repair_dead_skill_reference
Propose repairing every selected dead skill reference in one organization’s SKILL.md.
Pass one entry in repairs for each dead reference in that document: omit replacement
to remove the reference wherever it occurs, or provide an existing skill only when the
user explicitly chose that replacement. Put every dead reference in the document in one
call; the proposal is compared against the whole document, so a second proposal is
refused after the first is applied. Nothing changes until a person with permission to
manage skills applies the proposal in Action Review.
The tool re-checks each dead reference at its exact lines, verifies each replacement is
an existing skill, and proves the edited document still loads without the finding or new
findings. Removal is supported only when the reference occupies a whole list item, table
row, or line; a reference inside a sentence is refused and must be repointed or rewritten
by a person. References that could not be classified, skills published by managed
repositories, and skills Genesis ships are refused. See Advanced Settings
for the configuration key and default.
cut_routing_cycle
Propose cutting one user-selected edge from an OH-CYCLE routing cycle. Pass the skill
whose routing row should be deleted and the skill that row points to; this tool never
chooses the edge for the user. One call proposes one edge, and nothing changes until a
person who may manage the skill applies the proposal in Action Review. The proposal
re-checks that the skills are still in a routing cycle and that deleting the selected row
breaks their remaining paths. If another path still connects them, the proposal is
refused and names the skills that continue to cycle so the user can choose another edge.
The proposal deletes only a whole routing row whose only backticked content is the
routed cell. Rows containing another skill, another backticked token, or the routed
skill repeated in prose are refused and left for a person; rows in the frontmatter block
are never deleted. Skills published by managed repositories and platform skills Genesis
ships are also refused. Any other cycles remain listed on the Action Review card, and the
user is told about them before approval. The response reports
pending_review and
action_review.proposal_id while the proposal waits. See Advanced Settings
for the configuration key and default.
retire_broken_blueprint
Propose hiding one organization blueprint whose manifest has an OH-PARSE finding.
The proposal re-checks that the manifest still fails to parse and files removal of
the blueprint’s registration from the live listing. The manifest is not deleted,
and a person can reverse the applied fix through reverse_org_health_fix.
Retiring a managed-source blueprint also requires repository-management permission
from the person applying it. A blueprint synced from a remote repository is not
edited by this tool; change it in the source repository instead. See Advanced Settings
for the configuration key and default.
reverse_org_health_fix
Propose undoing one applied organization fix by restoring exactly the state the fix
recorded before it changed anything. Like a fix, the reversal waits in Action Review
for a person who may manage the target. A reversal proves only that nothing about the
target’s recorded state changed since the fix: for a dead skill pin, the agent’s pins
and its skill access policy; for a blueprint skill repair, the manifest text; and for
a retired blueprint, its registration. It does not repeat the fix’s own check. It is
refused if the fix was never applied, if it is itself a reversal, or if any recorded
field changed after the fix, when proposed and again when applied.
get_organization_finding
Read the evidence at a finding’s exact coordinate before describing it to a user.
For a corpus file, the response returns surrounding source lines. For a live-agent
coordinate such as agent:<agent_id>, it returns the agent’s activation evidence.
The default scope is organization; pass platform or all only when the user asks
about that content. The response includes provenance counts for that coordinate.
get_organization_co_load_set
Open one co-load set to see each member’s character contribution, provenance, missing
members, blocked members, source coordinate, and total size.
get_organization_skill
Read one complete SKILL.md, including frontmatter. The response includes the
document text, character count, path, and whether the result is complete.
audit_organization_health
This entry point is in system_manager_tools, which Eve holds. It starts a hidden,
background GenesisAuditor thread and returns its thread_id and handoff_id.
The background run reads the organization’s skills, blueprints, and agent records;
it can spend model budget and creates a thread and messages, but the auditor’s own
loadout cannot modify the audited organization.

