You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add a Databricks Genie Code agent-skills host - #111
Stacked on #48 (base: igutierrez/agent-skills-generic-host). Review that first; this PR shows only the Genie changes on top of it.
Summary
This adds a third host for the kumo-data-science skill: Databricks Genie Code, inside a Databricks workspace. It also fixes two gaps in the shared batch-inference intake that the Genie eval found on every host.
The host: agent-skills/skills/hosts/databricks-genie/
adapter.md (intake):
The source is a Unity Catalog catalog and schema.
Genie reads it with its own SQL, as the signed-in user.
Preflight reads information_schema and resolves the SQL warehouse, which the user confirms with the graph.
Destinations are Unity Catalog tables only.
A metric view is this host's semantic view. Its YAML maps onto semantic_view.md, and its primary keys come from the base tables' Unity Catalog constraints.
runtime.md (Step 2):
One new notebook for a GPU cluster.
DatabricksIdentity() takes the notebook's own credentials; a service principal is used only on request.
Output tables are named '<schema>__kumo__<table>'.
A run_sql helper on the statement API (wait_timeout='50s', polling) stages the population, cast to TIMESTAMP, and reads the destination back.
Model registry: Unity Catalog registered models. Versions are integers that Unity Catalog assigns; Kumo refuses a named one when publishing.
Retained run files go to a Unity Catalog volume.
job.md, the counterpart of ml_job.md:
A one-off runs/submit on an existing GPU cluster; it never creates a cluster.
Polling, and reading a failed run's error.
Schedules are created paused, and only on confirmation.
Cost.
Packaging: package_skill.py gains a genie target. --deploy uploads to /Users/<user>/.assistant/skills/kumo-data-science/ and reads every file back byte for byte. --prune deletes, inside that folder only, the files the package does not ship.
Core fix in accept/batch_inference.md, which changes CoCo and generic too:
Source of a saved model: a source that isn't in the conversation is not missing. The agent restates Source: recorded with <model> [inferred] and reads the record at 1c.
Scoring options by task type are now available at intake:
binary classification: a threshold, and no result count;
link prediction and ranking: 1–500 results per entity, independent of RANK TOP K; above 500, offer up to 500 or embeddings;
The router names "a Databricks job" next to "a Snowflake ML Job".
Test plan
pytest agent-skills/tests: 176 pass. New tests check that:
every adapter covers preflight and runtime column constraints;
every host ships a runtime.md;
genie ships only its own host and names no secret;
every Snowflake mechanism is mapped in the Genie adapter;
deploy reads files back, fails on a mismatch, and prunes only inside the folder.
package_skill.py --check: coco, generic and genie resolve.
Deployed to a Genie Code skills folder and read back byte for byte.
Intake, all 187 eval cases, Genie against CoCo on the same build, judged by nemotron: Genie 106/187 meet the rubric, CoCo 103/187. Batch export rose from 3/18 to 12/18 for Genie and 11/18 for CoCo after the core fix.
Codegen: 38/38 first-try match for Genie, generic and CoCo.
GPU: the 38 Genie notebooks on Databricks T4 clusters (kumo-engine[databricks]==1.0.0): 37/38 first try, 38/38 after repair. The one first-try failure was in a Databricks platform cell, not the notebook.
Live Genie Code runs (a Jobs task of type Genie Code), pending.
Not run with this skill yet: Unity Catalog publish/load, volume retention, scheduled jobs, real metric views. They are marked not verified in the files.
The kumo-data-science skill shipped only to Snowflake CoCo, and its "portable" core assumed
Snowflake throughout. This adds a `generic` host for coding agents beside the user (Claude
Code, Codex) that generates code for any of the six kumo.engine connectors.
- Preflight §0: before inferring structure, the agent proves it can read source_scope with a
read-only tool it already has. If not, it says what it checked and asks for access or for the
structure, never for a credential.
- hosts/generic/: adapter (source forms, access checks per system, destinations) and runtime
(config cell with placeholders, connect step, destinations and read-back per connector).
- Core no longer names a host; source and destination forms are host-defined. The SDK reference
gains §3.4 (non-Snowflake connectors) and §9.2 (destinations by connector).
- package_skill.py builds `generic`; tests check that the core names no host, that each package
ships only its own host, and that every adapter covers what the core defers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found by the generic-host codegen eval (kumo-ai/kumo_skill_dev, eval/generic/): 32 of 38 files
notebooks and 19 of 38 S3 notebooks named tables `x.parquet`, which carries the suffix into the
graph and the PQL; 19 and 18 rooted the output connector at the confirmed directory and wrote
`table_name='predictions'` one level below it.
- adapter §3: name file and object-store tables without their suffix.
- runtime §2: the same at the connect step.
- runtime §3: root the output connector at the destination's parent and name the last segment
in output_paths, so predictions land at exactly the confirmed path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rectory
GPU runs of the generic files notebooks (kumo_skill_dev eval/generic/run_gpu.py) failed every
static task with a staged population: pyarrow does not create the population directory, and
kumo-engine 1.0.0 rejects a population without TIMESTAMP when the entity table is timestamped
(kumo_finetuning_sdk.md §7.1 already says so; runtime §3.1 staged ENTITY1 only).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rerun's nov-sales-regression notebooks still staged ENTITY1 only: the example's 'drop if
there is none' read as optional. Decide from the entity Table's time_column.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Databricks GPU runs of the generic notebooks staged the static population with a
wait_timeout above Databricks' 50 s limit and without TIMESTAMP. §3.1 now covers Databricks:
CREATE TABLE AS through the confirmed SQL warehouse, wait <= 50 s, poll to completion.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GPU reruns staged TIMESTAMP from a DATE column (booked_date); kumo-engine 1.0.0 reads only a
timestamp or int64 anchor and rejects date32. Cast it, in pyarrow and in the Databricks SQL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SageMaker runs of the generic S3 notebooks: 5 of 38 added an AWS_REGION or AWS_PROFILE
placeholder, which stops the run at the config guard; on a job role there is no profile to fill.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SageMaker runs: 3 of 38 generic S3 notebooks still invented an AWS_REGION placeholder after
feefa6d, which stops them at the config guard. The SDK reference listed region= in the
signature with no word that it is normally left out; say so there and at the connect step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codegen evals (CoCo and generic alike) lost 1-5 of 38 notebook-only cases to the 'add a
destination later' example written as a python code block, which is a code cell that writes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A third host for the kumo-data-science skill: Databricks Genie Code, inside the workspace.
adapter.md covers source scope (a Unity Catalog catalog and schema), access through Genie's own
SQL as the signed-in user, the SQL warehouse resolved at preflight, information_schema
preflight, Unity Catalog destinations and runtime column constraints. runtime.md generates one
new notebook for a GPU cluster: DatabricksIdentity() with the notebook's ambient credentials (no
service principal unless asked), '<schema>__kumo__<table>' output names, a run_sql helper on the
statement API (wait_timeout 50s, polling) for population staging and read-back, and a
TIMESTAMP-cast population.
package_skill.py gains the genie target and --deploy, which uploads to
/Users/<user>/.assistant/skills/kumo-data-science/ and reads every file back byte for byte.
Tests: every adapter covers preflight and column constraints too, every host ships a runtime,
genie ships only its own host and names no secret, deploy round-trips and fails on a mismatch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ot ship
An older build left in the Genie skills folder keeps its own hosts/ directory beside the new one,
and the router assumes exactly one. --prune deletes the files the package does not ship, and the
directories they leave empty, never recursively and only inside kumo-data-science/.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bs, metric views
The capability skills and batch inference were written against Snowflake mechanisms the Genie
host left as "not covered". Each now has its Databricks counterpart:
- model registry: Unity Catalog registered models through a DatabricksConnector. UC assigns
integer versions (Kumo refuses a named one on publish), so a "publish as V1" request is
restated, not honoured; version=None loads the newest ready Kumo version, so loads stay
explicit; versions are listed with model_versions.list (runtime.md §5)
- retention: archives copied to a Unity Catalog volume, never over an existing object, digest
checked (runtime.md §6)
- supplied populations: read through a connector on the population's schema (runtime.md §4.1)
- jobs: job.md mirrors ml_job.md for Databricks — a job notebook run with runs/submit on an
existing GPU cluster, polling, run output, a paused cron job for schedules, cost
- semantic views: Unity Catalog metric views, read from information_schema.views and mapped
onto semantic_view.md's TABLE and RELATIONSHIP records (adapter.md §1.1)
The router's description and job routing name a Databricks job beside a Snowflake ML Job. Metric
views, the registry, volume retention and scheduled jobs are marked not verified.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y Catalog constraints
So semantic_view.md's key rules (composite keys, a reference to a non-primary column) apply to a
metric view as written, instead of every referenced column silently becoming a key.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tionOutputConfig
Generic Databricks notebooks put binary_classification_threshold on PredictionOutputConfig in
6 of 42 cases (S3 2 of 112; files and CoCo 0), a TypeError at predict time. The reference gave
the signature but never said the config takes neither argument.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s at intake
Two gaps the batch-export eval found on both hosts, CoCo and Genie alike:
- The source rule read "ask only if none of the three exists", and an agent at intake cannot see
the source recorded with the model, so it asked. The record is read at 1c: restate
"Source: recorded with <model> [inferred]" and ask only if 1c finds none.
- The scoring options lived only in kumoai-reference, which intake does not load: agents tied the
result count to RANK TOP K, proposed retraining for more results, missed the 500 cap, offered a
count for binary and regression, and claimed a threshold cannot be applied at scoring time. A
short table by task type now sits in batch_inference.md, and the 1d restatement carries a
"Scoring options" line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Access: an S3/GCS listing proves access, not structure; keep looking
for a column reader, else ask for the structure.
- Path destinations end in '/', '.parquet' or '.csv'. File, S3 and GCS
sinks all add '.parquet' to any other path (object_store_sink,
connector.file), so the SDK reference's "FileConnector does not
append" was wrong. Read back in the format the suffix names.
- Population staging reads the entity source in its own format (CSV or
Parquet) and still writes Parquet.
- Binary threshold: 0.5 [default] at Node 1d unless the user gives one;
predict requires it and has no default.
- batch_inference: a connector named alone is a source only on a host
that accepts connector names.
- CoCo: a semantic view's connector scope is its base tables' schema.
- graph_construction: connector-specific naming and sql(); non-ISO time
strings take timestamp_format with Dtype.date (Dtype.time is time of day).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One conflict, in accept/batch_inference.md, resolved by keeping both sides:
- source_scope: #48's "a connector named alone is a source only on a host that accepts connector
names" and this branch's "never ask for a saved model's source; restate it as recorded with the
model".
- Node 1d: #48's binary threshold line (0.5 [default]) folded into this branch's "Scoring options"
line; the scoring-options table takes the same default.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
Walkthrough
The change expands the skill system from Snowflake CoCo to generic coding agents and Databricks Genie. Host adapters and runtimes now define source access, connectors, destinations, preflight, population staging, and execution. Genie adds notebook and job guidance. The package script builds isolated host packages and can deploy Genie packages with pruning and read-back verification. Core workflows and SDK references now support host-specific locations, connectors, scoring options, and output forms. Tests cover package isolation and deployment safety.
Sequence Diagram(s)
sequenceDiagram
participant User
participant HostAdapter
participant Runtime
participant SourceOrWorkspace
User->>HostAdapter: provide source and execution request
HostAdapter->>SourceOrWorkspace: read metadata and run access checks
HostAdapter->>Runtime: pass confirmed host-specific configuration
Runtime->>SourceOrWorkspace: execute queries, stage data, or submit a job
SourceOrWorkspace-->>Runtime: return results, status, or errors
Runtime-->>User: report output location and verification
Loading
Priority: Normal
Merge Risk: Moderate · previous review 12a10
The change adds Databricks Genie and generic host support, but several instructions can send agents down the wrong path. Examples are Snowflake-only guidance for other notebooks, an APPEND request that overwrites a table, BigQuery datasets outside the US failing, and a deploy token sent over plain http. Fix these before merging.
Pre-merge checks: 2 · 1
Failed checks: 1 inconclusive
Check name
Status
Explanation
Resolution
Change Map Design Review
The required PR conversation comment beginning <!-- kumo-pr-change-map --> is not available. The supplied review context reports no returned review threads, and the repository contains only the temp…
Provide the single authorized PR conversation comment containing the complete current Change map, or make the linked-repository/PR conversation data available, then rerun this check.
Passed checks: 2 passed
Check name
Status
Explanation
Pr Size
The pull request changes 25 files, based on the authoritative review-scoped diff. The limit is 40 files.
Public Resource Access
No added or modified fixed external resource reference requires public access. The only existing URL (https://example.com/x.md) is an unchanged test fixture. The new https://{host} value construct…
Full details: Public Resource Access
Explanation
No added or modified fixed external resource reference requires public access. The only existing URL (https://example.com/x.md) is an unchanged test fixture. The new https://{host} value constructs the user-supplied Databricks workspace API endpoint; it does not reference a fixed external resource. New package and repository paths resolve to shipped or repository-local sources.
Full details: Change Map Design Review
Explanation
The required PR conversation comment beginning <!-- kumo-pr-change-map --> is not available. The supplied review context reports no returned review threads, and the repository contains only the template/checker, not the PR's authored change map. Without that map, I cannot assess necessity, abstraction layer, observed failure, smallest sufficient change, focused verification, or stopping condition for each change.
Resolution
Provide the single authorized PR conversation comment containing the complete current Change map, or make the linked-repository/PR conversation data available, then rerun this check.
Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
- generic runtime §3.1: stage the population's TIMESTAMP only when the
entity table has a time column, in both the pyarrow and Databricks paths.
- batch_inference: the field summary applies the same host condition on
connector names as the table below it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each §3.1 recipe reads the entity table and writes the population in one
system, but the rule picked the recipe by the destination, so a source and
destination in different systems had no working branch. Stage in the
source's system instead; Node 1d asks for a location there when the
destination is elsewhere. CoCo is unchanged: its source and destination
are both Snowflake.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y client
runtime.md §3.1 said BigQuery population staging was not covered on the generic host. Stage it
like Databricks: CREATE OR REPLACE TABLE ... AS SELECT with ENTITY1 and, when the entity has a time
column, CAST(<time> AS TIMESTAMP) AS TIMESTAMP, waiting on the job, then a BigQueryConnector scoped
to the population's dataset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One conflict in accept/batch_inference.md's source_scope bullet, resolved by keeping #48's
connector-name qualifier and this branch's "a source not in the conversation is not missing".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New: source scope (Unity Catalog catalog and schema; metric views read as semantic views, keys from table constraints), access through Genie's own SQL, warehouse resolution, information_schema preflight, Unity Catalog destinations, column constraints, mapping of every Snowflake mechanism the capability skills use
The core defers source, access, preflight and destinations to the host; Genie Code had no host on the current skill
New: one notebook for a GPU cluster, DatabricksIdentity() with the notebook's credentials, '<schema>__kumo__<table>' output names, a run_sql statement-API helper (50 s wait, polling) for population staging and read-back, Unity Catalog model registry (UC-assigned integer versions), volume retention, running
What the generated notebook does on Databricks, from the SDK source and GPU runs
agent-skills/skills/hosts/databricks-genie/job.md
Genie host, jobs
New: Databricks job runs on an existing GPU cluster (runs/submit), polling, run output on failure, paused cron schedules on confirmation, cost
Counterpart of ml_job.md, so job requests have a host file instead of "not covered"
A source not in the conversation is restated as recorded with the model, never asked; new table of scoring options by task type (threshold, results per entity 1–500 independent of RANK TOP K, none for regression); a "Scoring options" line in the restatement
Both found by the batch-export eval on every host: agents asked for the source and lacked the scoring options at intake (3/18 → 11–12/18)
agent-skills/skills/kumo-data-science/SKILL.md
Description; job routing
Names "a Databricks job" and metric views next to the Snowflake ML Job
So a Databricks job request routes to the host's job file
agent-skills/scripts/package_skill.py
HOSTS['genie'], Workspace, deploy_genie, main
genie target; --deploy uploads to /Users/<user>/.assistant/skills/kumo-data-science/ and reads every file back; --prune deletes files the package does not ship, inside that folder only
Genie Code reads skills from the workspace; a stale build left there kept a second host directory
agent-skills/tests/test_package_skill.py
Package and adapter tests
Genie ships only its own host and names no secret; every adapter covers preflight and column constraints; every host ships runtime.md; every Snowflake mechanism is mapped; deploy round-trips, fails on a mismatch, prunes only inside the folder
Keeps the new host and the deploy path checked
agent-skills/README.md
Hosts table; packaging
Lists the Genie host, its package and the deploy command
Documentation of the third host
agent-skills/DESIGN.md
Hosts and the access check
Why Genie names no service principal: its SQL is the read tool and the notebook runs as its user
…coring options, quoting)
- A prediction write stages through <catalog>.<schema>._kumo_staging and creates it on first use
(kumo_databricks.output). The adapter lists the grants it needs; the Node 1d output line names
the volume when the write would create it, so the user confirms it.
- genie --deploy refuses, before writing anything, when a file not in the package sits under
hosts/ and --prune is not given: a second host directory would let Genie read the old adapter.
- batch_inference.md's scoring options follow kumo_core.prediction_options: the count is required
and capped at 500 only for link prediction; multilabel ranking has no cap; multiclass and
multilabel fall back to RANK TOP K; multilabel takes a threshold (0.5 default); forecasting
takes no count.
- Hyphenated Unity Catalog names are looked up as written, not rewritten to underscores, and every
identifier in the notebook's SQL goes through a backtick-quoting helper.
- Also: TIMESTAMP_NTZ is a time type; a population may live in another catalog; "latest" comes
from the registry connector's list of ready Kumo versions; the ARRAY row states what the
connector types as lists.
Tests: deploy refuses a stale hosts/ file without --prune; SQL in runtime.md has no bare
identifier; the staging volume is named; the scoring-options rows match the SDK.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kumo-engine 1.0.0's BigQuery source backend raises when a connector names
no identity, though the connector's docstring says None defers to ambient
credentials. BigQueryIdentity() with no arguments is the ambient Google
credential, so naming it changes nothing else. Found by the generic-host
GPU eval on SageMaker (GCS with no identity passed; BigQuery failed at
table_names()).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…med a billing project
The GPU eval found 5/38 BigQuery notebooks stopping at a
'<BIGQUERY_BILLING_PROJECT>' placeholder no user asked for.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oject, never a placeholder
The GPU eval found 7/38 notebooks leaving PROJECT_ID as a fill-in
('the GCP project billed for queries') although the conversation confirmed
kumo-engineering.<dataset>, and 9/38 adding a billing placeholder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reason will be displayed to describe this comment to others. Learn more.
Reviewed at f8cc57d. agent-skills/tests 179 pass and package_skill.py --check resolves coco, generic and genie. The SDK claims in the three host files check out against the engine source except where noted below; the Databricks claims were checked against the Databricks docs.
Blocking, inline on adapter.md §1.1: information_schema.views.view_definition is NULL for anyone but the view's owner, the join mapping ignores cardinality, and a join source need not be a base table. The section already says "not verified"; these three would each send the agent down the wrong branch.
Should fix
runtime.md §4 and kumo_finetuning_sdk.md §9.2: "a bare table name fails in the sink" is false. kumo_databricks/output.pywithin_schema prefixes the connector's schema. Same sentence flagged on #48; fix it in one place.
adapter.md §3 preflight: information_schema.columns.data_type reports ARRAY, not ARRAY<STRING>. Select full_data_type too, or §6 cannot tell a supported array from an unsupported one. "BIGINT (listed as LONG)" is not in the docs; drop it unless you saw it.
batch_inference.md source_scope: "the source recorded with the model" reads as registry metadata, but the registry keeps only spec_version, query and snapshot_id (registry.py_bundle_metadata). Say the team's training record from reuse.md, so the fallback ask is reached when there is none.
job.md §2 asks for name and version up front; batch_inference.md Node 1a asks for a version only when several exist. Pin an explicit integer in the notebook either way, ask only when needed.
job.md §5 names only the binary threshold and the link-prediction count; the new scoring-options table also allows a count for multiclass and multilabel and a threshold for multilabel. Point §5 at the table. The SDK reference's "1-500" row applies to link prediction with predictions only (prediction_options.py).
SKILL.md description is 1259 characters; the Agent Skills spec caps description at 1024 (1188 on #48 already). Move the trigger list into the body.
Nits
deploy_genie --prune uploads before it deletes the stale host files, so a failed delete leaves two host directories, the state the pre-check refuses. Delete stale hosts/ first, or assert containment under target and fail on a miss.
runtime.md §6: exists() then copyfile is not "never over an existing object"; open(target, 'xb') is.
job.md §5: "the output table is the only result that survives" ignores a published model and a retained archive.
test_scoring_options_follow_the_sdk reads only the markdown; read MAX_LINKS_TO_PREDICT from the source or reword the docstring. FakeWorkspace.listing prefilters by prefix, so the prune test cannot catch a containment bug in the real listing.
Branch is two commits behind #48 (25c5c4e3, 1178a6dc); no Genie file affected, merge before marking ready.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: information_schema.views.view_definition is "the view text if the user owns the view, NULL otherwise" (Databricks docs). Anyone but the owner gets NULL here, and the next paragraph then reads a NULL definition as "plain SQL" and treats a metric view as an ordinary view. Databricks' documented way to read a metric view's YAML is DESCRIBE TABLE EXTENDED <catalog>.<schema>.<view> AS JSON; the YAML is the View Text field. Use that, and treat NULL from this query as "cannot read", not as "ordinary view".
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 09baf89. §1.1 now reads the definition with DESCRIBE TABLE EXTENDED … AS JSON (type, view_text). A METRIC_VIEW with no view_text, or an error, is "cannot read": it asks for the YAML and is never read as an ordinary view. Checked in our workspace as a non-owner: DESCRIBE returns both fields, and information_schema.views has no row at all for a metric view, not even a NULL one.
| `source: catalog.schema.table` | a `TABLE` with that base table |
| `source:` a SQL query | a logical table defined by a query → ASK BACK, as that file says |
| each entry of `joins:` (and of a join's own nested `joins:`) with `source: catalog.schema.table` | a `TABLE` with that base table; its `name` is a logical name |
| that join's `on: <parent>.<fk> = <name>.<key>`, or `using: [<col>]` | a `RELATIONSHIP` from the parent (`source` for a top-level join, else the enclosing join) to this table: `FOREIGN_KEY` `<fk>`, `REF_KEY` `<key>` |
The reason will be displayed to describe this comment to others. Learn more.
Blocking: this row assumes every join is many-to-one, parent holds the FK. The metric view YAML has a cardinality field per join (default many_to_one); one_to_many makes the joined table the fact side, so FK and REF_KEY swap. Map one_to_many as FOREIGN_KEY on the joined table and REF_KEY on the parent, or ASK BACK as the non-equality row does.
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 12a105f, as ASK BACK. The FK/REF_KEY mapping now applies only when cardinality is absent or many_to_one. Any other value names the join and its cardinality and asks which table holds the foreign key; the skill never swaps the keys itself. We can add the one_to_many mapping once a real view has gone through intake.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: a three-part source can be a view or another metric view, not only a table. Check information_schema.tables.table_type before calling it a base table; semantic_view.md's physical-table gate depends on that.
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 09baf89. Every three-part source (top-level or join) is checked against information_schema.tables.table_type first. Only MANAGED and EXTERNAL map to a base table; any other type is a query-defined table and goes to ASK BACK.
§1 exempted S3 and GCS from runtime-only constants but not BigQuery, so
6/38 BigQuery notebooks added a '<BILLING_PROJECT_ID>' placeholder and
stopped at the fill-in guard. BigQuery joins the exemption: it bills to
the confirmed dataset's project.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- adapter.md §1.1: read a metric view with DESCRIBE TABLE EXTENDED ... AS JSON
(type, view_text); information_schema.views has no row for one and is NULL for
non-owners. A missing definition is "cannot read", never "ordinary view".
Check information_schema.tables.table_type before treating a source as a base table.
- adapter.md §3: select full_data_type; data_type reports LONG and bare ARRAY.
- runtime.md §4, SDK reference §9.2: a bare Databricks output name lands in the
connector's schema (kumo_databricks.output.within_schema); it does not fail.
- runtime.md §6: copy the archive with open(target, 'xb').
- batch_inference.md: the source comes from the team's training record, not the
registry; a single model version is used and pinned, asked only when several.
- job.md: version asked only per Node 1a; predict arguments follow the scoring-options
table; a published model or retained archive also survives the cluster.
- SDK reference and pql_writing: the 1-500 range is link prediction only.
- SKILL.md: description 778 chars (spec cap 1024); trigger list moved to the body.
- package_skill.py: prune before upload and refuse a listing outside the target.
- tests: read MAX_LINKS_TO_PREDICT from the SDK; cover a leaking listing and a
failed prune delete.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adapter.md §1.1 mapped every join with the parent holding the foreign key. A join's
cardinality (default many_to_one) can say otherwise; any other value now asks the
user which table holds the key instead of building the edge backwards.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thanks for the review. Everything is addressed in 09baf89 and 12a105f; the three blocking items are answered inline. agent-skills/tests: 181 pass. package_skill.py --check resolves coco, generic and genie.
Should fix
Bare output name: removed "fails in the sink" from runtime.md §4. §9.2 of the SDK reference now says a bare name lands in the connector's schema (kumo_databricks.output.within_schema), and runtime.md cites §9.2 instead of restating it.
full_data_type: the §3 columns query selects it, and §6 uses it to tell array types apart. On "LONG": I kept it, because we did see it. In our workspace information_schema.columns.data_type is LONG for bigint columns (e.g. engagement_count, whose full_data_type is bigint). The note now says to read types from full_data_type.
batch_inference source_scope: the source comes from the team's training record (reuse.md), not the registry. It asks only if that record is missing or names no source.
Model version: job.md §2 follows Node 1a. It asks only when several loadable versions exist; a single version is [inferred]. The notebook always pins an explicit integer.
job.md §5: the predict arguments now point at the scoring-options table. The SDK reference row and pql_writing.md now limit 1–500 to link prediction with predictions written.
SKILL.md description: now 778 characters; the trigger list moved to a "When to use" section in the body.
Nits
--prune: stale files are deleted before the upload, and any listed path outside the target stops the deploy before anything is deleted.
runtime.md §6: the archive copy uses open(target, 'xb').
job.md §5: "what survives" now includes a published model and a retained archive.
Tests:test_scoring_options_follow_the_sdk reads MAX_LINKS_TO_PREDICT from prediction_options.py. FakeWorkspace can return a path outside the prefix, and new tests cover that listing and a failed prune delete.
main's squash of #48 is byte-identical to the igutierrez/agent-skills-generic-host
tip already merged here, so every conflict resolves to this branch's side.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This new section says connector.sql() is available for Snowflake, Databricks, and BigQuery, but troubleshooting_signals.md still says that connector.sql(...) does not exist. An agent handling a custom-SQL source can therefore follow conflicting instructions. Scope the prohibition to unsupported connectors and state that supported connector.sql() calls return a source table, not rows. (github.com)
As per coding guidelines, keep one maintained explanation per topic.
19-21: Minor · Data Integrity & Integration · Quick win
Remove connector name unless Snowflake CoCo resolves it to a source scope.
The intake contract allows a connector name only when the active host defines how it resolves. Snowflake CoCo's preflight uses <DB>.INFORMATION_SCHEMA directly, and runtime.md requires explicit database and schema_name values. The current flow provides no mapping from a bare connector name to those values, so this source form can reach intake without a valid preflight or connector scope.
🐛 Suggested fix
-**Source scope.** A Snowflake database and schema (warehouse optional), a fully qualified semantic-view (`DB.SCHEMA.VIEW`, resolved by `kumo-data-science/accept/semantic_view.md`), or a connector-name.+**Source scope.** A Snowflake database and schema (warehouse optional), or a fully qualified+semantic view (`DB.SCHEMA.VIEW`, resolved by `kumo-data-science/accept/semantic_view.md`).
123-125: Minor · Maintainability & Code Quality · Quick win
Include warehouse discovery in the allowed intake operations.
Section 2 requires warehouses.list() during intake, but this rule permits only catalog metadata and the preflight probe. The agent receives conflicting instructions.
Add warehouse discovery to the allowed read-only operations. This is a documentation-contract conflict within §2.
agent-skills/skills/hosts/generic/adapter.md: 1
66-66: Minor · Functional Correctness · Quick win
Collect CSV types before completing preflight.
A CSV header supplies column names, not source types. If no reader returns inferred types, use the §0 ask-back instead of accepting the source as structurally verified. Use duckdb DESCRIBE or Arrow schema inference and record the resulting types. The SDK catalog contract also requires resolved column metadata. (raw.githubusercontent.com)
agent-skills/skills/hosts/generic/runtime.md: 3
202-205: Minor · Functional Correctness · Quick win
Preserve the validated CSV time format.
This path casts raw values directly to timestamp('us'). The SDK contract requires a timestamp_format for CSV time columns. Carry that format from table metadata and parse with it before writing TIMESTAMP; otherwise non-default date strings can fail during population creation. (raw.githubusercontent.com)
240-245: Minor · Functional Correctness · Quick win
Backtick-quote metadata-derived identifiers in the Databricks and BigQuery staging SQL.
The Databricks CREATE OR REPLACE TABLE statement interpolates CATALOG, POP_SCHEMA, POP_TABLE, SCHEMA, ENTITY_TABLE, ENTITY_KEY, and ENTITY_TIME without quoting. A name that contains a space or hyphen, or that is a reserved word, can make the statement fail to parse. An unquoted hyphen can also parse as subtraction, which returns wrong values instead of an error.
The BigQuery block already backtick-quotes its table paths. It still interpolates ENTITY_KEY and ENTITY_TIME without quotes, so the same failure applies to those column names.
🐛 Suggested fix
Databricks:
- time_col = f', CAST({ENTITY_TIME} AS TIMESTAMP) AS TIMESTAMP' if ENTITY_TIME else ''+ time_col = f', CAST(`{ENTITY_TIME}` AS TIMESTAMP) AS TIMESTAMP' if ENTITY_TIME else ''
r = ws.statement_execution.execute_statement(
warehouse_id=DATABRICKS_WAREHOUSE_ID, wait_timeout='50s',
- statement=(f'CREATE OR REPLACE TABLE {CATALOG}.{POP_SCHEMA}.{POP_TABLE} AS '- f'SELECT {ENTITY_KEY} AS ENTITY1{time_col} '- f'FROM {CATALOG}.{SCHEMA}.{ENTITY_TABLE}'))+ statement=(f'CREATE OR REPLACE TABLE `{CATALOG}`.`{POP_SCHEMA}`.`{POP_TABLE}` AS '+ f'SELECT `{ENTITY_KEY}` AS ENTITY1{time_col} '+ f'FROM `{CATALOG}`.`{SCHEMA}`.`{ENTITY_TABLE}`'))
BigQuery:
- time_col = f', CAST({ENTITY_TIME} AS TIMESTAMP) AS `TIMESTAMP`' if ENTITY_TIME else ''+ time_col = f', CAST(`{ENTITY_TIME}` AS TIMESTAMP) AS `TIMESTAMP`' if ENTITY_TIME else ''
...
- f'SELECT {ENTITY_KEY} AS ENTITY1{time_col} '+ f'SELECT `{ENTITY_KEY}` AS ENTITY1{time_col} '
146-147: Minor · Functional Correctness · Quick win
Read back the BigQuery destination from its own project, not from PROJECT_ID.
The read-back at lines 146-147 queries {PROJECT_ID}.{OUTPUT_DATASET}.{OUTPUT_TABLE} with bigquery.Client(project=PROJECT_ID). PROJECT_ID is the source scope. If the confirmed BigQuery destination is in a different project, the query can fail with a not-found error or count an unrelated table. The row-count assertion then does not check the write.
Derive the project from the confirmed destination, and use that value for both the client and the table path.
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Major · Security & Privacy · Quick win
Reject HTTP workspace URLs before sending the token.
If DATABRICKS_HOST or DATABRICKS_URL starts with http://, Workspace.api sends DATABRICKS_TOKEN in an unencrypted Authorization header. Require an https:// URL before the first request. Databricks documents bearer-token API calls over HTTPS. (docs.databricks.com)
The reason will be displayed to describe this comment to others. Learn more.
Major · Data Integrity & Integration · Quick win
Do not silently change a supplied schema name.
If dev-ws is absent but dev_ws exists, this rule selects a different schema without confirmation. That can read or train from the wrong data.
Treat the underscore spelling as a candidate and ask the user to confirm it. This conflicts with the preflight rule that supplied values are not overridden.
<source_evidence>
<source kind="search">
<title>Manage schemas | Databricks on AWS</title>
<location>https://docs.databricks.com/aws/en/schemas/manage-schema</location>
<excerpt>citeturn0search1 [wordlim: 200] Crawled: yesterday; See also What are schemas in Databricks? ... * Permissions tab: grant and revoke privileges on the schema. ... * To add tables, volumes, and other data and AI assets to a schema, see the documentation for creating the asset (for example Databricks tables or Manage model lifecycle in Unity Catalog).
Last updated on Oct 6, 2026
# Manage schemas
This article shows how to view, update, and delete schemas in Unity Catalog.
See also What are schemas in Databricks? and Create schemas.
note
In Hive metastore, you must use SQL commands to manage schemas. Behavior in legacy Hive metastore differs from Unity Catalog. Permissions required depend on whether or not you are using table access control. See Schemas in Hive metastore and Hive metastore privileges and securable objects (legacy).
## Requirements
To work with schemas in Unity Catalog:
* You must have a Unity Catalog metastore linked to the workspace where you perform the schema creation.
* The cluster that you use to run a notebook to manage a schema must use a Unity Catalog-compliant access mode. See Access modes. SQL warehouses always support Unity Catalog.
* Permissions required to alter, view, and drop schemas in Unity Catalog are listed in the sections that follow.
## Find and view schemas
In Unity Catalog, users can see all schemas on which they have been assigned the `USE SCHEMA` permission, along with the `USE CATALOG` permission on the schema's parent catalog. To access or list a table or view in a schema, users must also have `SELECT` permission on the table or view.
* Catalog Explorer
* SQL
1. Log in to a workspace that is linked to the Unity Catalog metastore.
2. Click Catalog.
3. In the Catalog pane on the left, click the catalog that contains the schema (`hive_metastore` if it's in the Hive metastore).
Alternatively, you can search for the schema using the Type to filter field in the Catalog pane.
Run `SHOW SCHEMAS` in a notebook or the SQL query editor to list all schemas in a catalog or those that match a regular expression. Run `DESCRIBE SCHEMA` to get details about a schema. See SHOW SCHEMAS and DESCRIBE SCHEMA.
## Update a schema
To update (or alter) a schema in a Unity Catalog catalog, you can use Catalog Explorer or a SQL command.
`MANAGE` on a schema doesn't require `USE SCHEMA` on that schema. See Usage privilege requirements for `MANAGE`.
* Catalog Explorer
* SQL
1. Log into a workspace that is linked to the Unity Catalog metastore.
2. Click Catalog.
3. In the Catalog pane on the left, click the catalog that contains the schema and then click the schema to open the schema details page.
Alternatively, you can search for the schema using the Type to filter field in the Catalog pane.
4. Use the following page elements on the schema details page to update the schema:
* Overview tab: update the owner, add or update tags, add or update comments. See Manage object ownership, Apply tags to Unity Catalog securable objects, and Add comments to data and AI assets.
* Permissions tab: grant and revoke privileges on the schema. See Manage privileges in Unity Catalog.
* The kebab menu: Rename the schema.
* Create button: create a table or volume in the schema. </excerpt>
</source>
<source kind="search">
<title>Information schema | Databricks on AWS</title>
<location>https://docs.databricks.com/aws/fr/sql/language-manual/sql-ref-information-schema</location>
<excerpt>citeturn0search3 [wordlim: 200] Crawled: 5 days ago; Applies to: Databricks SQL Databricks Runtime 10.4 LTS and above Unity Catalog only ... The purpose of the information schema is to provide a SQL-based, privilege-aware, and self-describing API for accessing catalog metadata. ... If your privileges change, what you see in the information schema changes accordingly.
# Information schema
Applies to: Databricks SQL Databricks Runtime 10.4 LTS and above Unity Catalog only
In the `SYSTEM` catalog, the `INFORMATION_SCHEMA` is a SQL standard schema that provides metadata about objects across all catalogs in the metastore. It does not contain metadata about `hive_metastore` objects.
Separately, each catalog created in Unity Catalog also automatically includes an `information_schema` that describes metadata about objects in that catalog only.
Both types of information schemas automatically filter results to include only the objects you have Unity Catalog privileges to access. This behavior differs from other Databricks system tables. See How information schema system tables handle permissions.
The purpose of the information schema is to provide a SQL-based, privilege-aware, and self-describing API for accessing catalog metadata.
## How information schema system tables handle permissions
`system.information_schema` differs from other system tables in that it implements automatic filtering. This means you see only the objects (catalogs, schemas, tables, columns, etc.) that you have privileges to access in Unity Catalog. If your privileges change, what you see in the information schema changes accordingly. For example, when you query `information_schema.tables`, only rows for tables you have permission to see are returned.
Unlike other system tables, the information schema does not require an explicit `SELECT` grant. Access is governed automatically by your Unity Catalog privileges. You see only the objects that you already have permission to access.
## Entity relationship diagram of the information schema
The following entity relationship (ER) diagram provides an overview of a subset of information schema views and how they relate to each other.
## Information schema views
Name | Description
--- | ---
ABAC_POLICY_DEFINITIONS | Describes attribute-based access control (ABAC) policies attached to securables in the catalog.
CATALOG_PRIVILEGES | Lists principals that have privileges on the catalogs.
</excerpt>
</source>
<source kind="search">
<title>Unity Catalog privileges reference | Databricks on AWS</title>
<location>https://docs.databricks.com/aws/en/data-governance/unity-catalog/access-control/privileges-reference</location>
<excerpt>citeturn0search7 [wordlim: 200] Crawled: yesterday; For more information about secrets, see Secrets in Unity Catalog. ... Following the principle of least privilege, Databricks recommends granting `CREATE SERVICE` at the schema level. ... Following the principle of least privilege, Databricks recommends granting `CREATE TABLE` at the schema level. ... `UPDATE` is one of the fine-grained DML privileges, a least-privilege alternative to `MODIFY`.
### CREATE SCHEMA
* Applicable container objects: `CATALOG`
Allows a user to create a schema in a catalog on which `CREATE SCHEMA` is granted. The user must also have the `USE CATALOG` privilege on the catalog.
### CREATE SECRET
* Applicable container objects: `SCHEMA`, `CATALOG`
Allows a user to create a secret in a schema on which `CREATE SECRET` is granted. The user must also have `USE CATALOG` on the catalog and `USE SCHEMA` on the schema where the secret is created. You can also grant `CREATE SECRET` on a catalog to allow a user to create secrets in any current or future schema in the catalog. For more information about secrets, see Secrets in Unity Catalog.
### CREATE SERVICE
* Applicable container objects: `SCHEMA`, `CATALOG`
Allows a user to create a service in a schema on which `CREATE SERVICE` is granted. Services include model services, model provider services, MCP services, and agent services. Following the principle of least privilege, Databricks recommends granting `CREATE SERVICE` at the schema level. You can also grant `CREATE SERVICE` on a catalog to allow a user to create services in any existing or future schema in the catalog.
The user must also have the `USE CATALOG` privilege on the catalog and `USE SCHEMA` on the schema where the service is created.
### CREATE SERVICE CREDENTIAL
* Applicable container objects: Unity Catalog metastore
Allows a user to create a service credential in a Unity Catalog metastore.
### CREATE STORAGE CREDENTIAL
* Applicable container objects: Unity Catalog metastore
Allows a user to create a storage credential in a Unity Catalog metastore.
### CREATE TABLE
* Applicable container objects: `SCHEMA`, `CATALOG`
Allows a user to create a table or view in a schema on which `CREATE TABLE` is granted. Following the principle of least privilege, Databricks recommends granting `CREATE TABLE` at the schema level. You can also grant `CREATE TABLE` on a catalog to allow a user to create tables or views in any existing or future schema in the catalog.
The user must also have the `USE CATALOG` privilege on the catalog and the `USE SCHEMA` privilege on the schema where the table or view is created.
### UPDATE
Beta
This feature is in Beta.
* Applicable object types: `TABLE`
* Applicable container objects: `SCHEMA`, `CATALOG`
Allows a user to modify existing data in a table. `UPDATE` is one of the fine-grained DML privileges, a least-privilege alternative to `MODIFY`. See Fine-grained DML privileges.
### USE CATALOG
* Applicable container objects: `CATALOG`
`USE CATALOG` is a usage privilege. Generally, users need this privilege to interact with any object within the catalog. `USE CATALOG` does not grant access to the catalog itself or to any specific objects within it.
For example, to read from a table, a user needs `SELECT` on the table, `USE CATALOG` on the parent catalog, and `USE SCHEMA` on the parent schema.
`USE CATALOG` also provides an important access control boundary for catalog owners. Even if a table owner grants `SELECT` on a table to another user, that user cannot access the table unless they also have `USE CATALOG` on the parent catalog. Because only catalog owners or users with `MANAGE` on the catalog can grant `USE CATALOG`, catalog owners retain control over which users can access their objects, regardless of what individual table or schema owners grant.
`USE CATALOG` is not required to discover or read object metadata if the user has the `BROWSE` privilege on that catalog.
### USE CONNECTION
* Applicable object types: `CONNECTION`
Allows a user to list and view details about connections to external databases in a Lakehouse Federation scenario. `USE CONNECTION` is also required to use the `remote_query` function to run SQL queries directly on external databases.
### USE SCHEMA
* Applicable container objects: `SCHEMA`, `CATALOG`
`USE SCHEMA` is a usage privilege. Generally, users need this privilege to interact with any object within the schema. `USE SCHEMA` does not grant access to the schema itself or to any specific objects within it.
For example, to read from a table, a user needs `SELECT` on the table, `USE SCHEMA` on the parent schema, and `USE CATALOG` on the parent catalog.
`USE SCHEMA` also provides an important access control boundary for schema owners. Even if a table owner grants `SELECT` on a table to another user, that user cannot access the table unless they also have `USE SCHEMA` on the parent schema. Because only schema owners or users with `MANAGE` on the schema can grant `USE SCHEMA`, schema owners retain control over which users can access their objects, regardless of what individual table owners grant.
Due to privilege inheritance, you can grant `USE SCHEMA` on a catalog to automatically grant `USE SCHEMA` on all current and future schemas in the catalog.
`USE SCHEMA` is not required to discover or read object metadata if the user has the `BROWSE` privilege on the parent catalog.
### WRITE FILES
* Applicable object types: `EXTERNAL LOCATION`
Allows a user to write files directly to cloud object storage configured as an external location. </excerpt>
</source>
<source kind="search">
<title>Information schema | Databricks on AWS</title>
<location>https://docs.databricks.com/aws/fr/sql/language-manual/sql-ref-information-schema</location>
<excerpt>citeturn1search3 [wordlim: 200] Crawled: 5 days ago; Applies to: Databricks SQL Databricks Runtime 10.4 LTS and above Unity Catalog only ... SCHEMATA | Describes schemas within the catalog. ... * A manual sync using `REPAIR TABLE` may be required for some catalog metadata changes to be reflected in the information schema.
# Information schema
Applies to: Databricks SQL Databricks Runtime 10.4 LTS and above Unity Catalog only
In the `SYSTEM` catalog, the `INFORMATION_SCHEMA` is a SQL standard schema that provides metadata about objects across all catalogs in the metastore. It does not contain metadata about `hive_metastore` objects.
Separately, each catalog created in Unity Catalog also automatically includes an `information_schema` that describes metadata about objects in that catalog only.
Both types of information schemas automatically filter results to include only the objects you have Unity Catalog privileges to access. This behavior differs from other Databricks system tables. See How information schema system tables handle permissions.
The purpose of the information schema is to provide a SQL-based, privilege-aware, and self-describing API for accessing catalog metadata.
## How information schema system tables handle permissions
`system.information_schema` differs from other system tables in that it implements automatic filtering. This means you see only the objects (catalogs, schemas, tables, columns, etc.) that you have privileges to access in Unity Catalog. If your privileges change, what you see in the information schema changes accordingly. For example, when you query `information_schema.tables`, only rows for tables you have permission to see are returned.
Unlike other system tables, the information schema does not require an explicit `SELECT` grant. Access is governed automatically by your Unity Catalog privileges. You see only the objects that you already have permission to access.
## Entity relationship diagram of the information schema
The following entity relationship (ER) diagram provides an overview of a subset of information schema views and how they relate to each other.
## Information schema views
Name | Description
--- | ---
ABAC_POLICY_DEFINITIONS | Describes attribute-based access control (ABAC) policies attached to securables in the catalog.
CATALOG_PRIVILEGES | Lists principals that have privileges on the catalogs.
## Notes
* The information schema implements privilege-aware filtering. You automatically see only the objects you have Unity Catalog permissions to access. See How information schema system tables handle permissions.
* A manual sync using `REPAIR TABLE` may be required for some catalog metadata changes to be reflected in the information schema. For more information, see REPAIR TABLE.
* All identifiers except column and tag names are stored in the information schema as lowercase `STRING`. For query performance, avoid using functions like `LOWER()` or `UPPER()` on the identifier column. Instead, compare identifiers directly using lowercase values.
* To prevent query timeouts, apply selective filters when querying the information schema (e.g. `WHERE table_catalog = 'main' AND table_schema = 'default'`). Refer to the documentation above for a full list of columns that can be used as filters for each Information Schema table.
* Note that `LIMIT` pushdown is not currently supported, so although it can truncate the results it will not improve performance.
## Examples
SQL
`
> SELECT table_name, column_name
FROM information_schema.columns
WHERE data_type = 'DOUBLE'
AND table_schema = 'information_schema';
`
The following are examples of workflows that use the system level information schema tables.
If you want to view all tables that have been created in the last 24 hours, your query could look like the following.
SQL
`
> SELECT table_name, table_owner, created_by, last_altered, last_altered_by, table_catalog
FROM system.information_schema.tables
WHERE datediff(now(), last_altered) < 1;
`
If you want to view how many tables you have in each schema, consider the following example.
SQL
`
> SELECT table_schema, count(table_name)
FROM system.information_schema.tables
WHERE table_schema = 'tpch'
GROUP BY table_schema
ORDER BY 2 DESC
`</excerpt>
</source>
<source kind="search">
<title>Manage schemas | Databricks on AWS</title>
<location>https://docs.databricks.com/aws/en/schemas/manage-schema</location>
<excerpt>citeturn1search5 [wordlim: 200] Crawled: yesterday; * To change the owner, add or update tags, set schema properties, and manage predictive optimization on the tables in a schema, run the `ALTER SCHEMA` command in a notebook or the SQL query editor. ... * To add tables, volumes, and other data and AI assets to a schema, see the documentation for creating the asset (for example Databricks tables or Manage model lifecycle in Unity Catalog). ... For more information, see Cascade deletes bypass share protection.
Last updated on Oct 6, 2026
# Manage schemas
This article shows how to view, update, and delete schemas in Unity Catalog.
See also What are schemas in Databricks? and Create schemas.
note
In Hive metastore, you must use SQL commands to manage schemas. Behavior in legacy Hive metastore differs from Unity Catalog. Permissions required depend on whether or not you are using table access control. See Schemas in Hive metastore and Hive metastore privileges and securable objects (legacy).
## Requirements
To work with schemas in Unity Catalog:
* You must have a Unity Catalog metastore linked to the workspace where you perform the schema creation.
* The cluster that you use to run a notebook to manage a schema must use a Unity Catalog-compliant access mode. See Access modes. SQL warehouses always support Unity Catalog.
* Permissions required to alter, view, and drop schemas in Unity Catalog are listed in the sections that follow.
## Find and view schemas
In Unity Catalog, users can see all schemas on which they have been assigned the `USE SCHEMA` permission, along with the `USE CATALOG` permission on the schema's parent catalog. To access or list a table or view in a schema, users must also have `SELECT` permission on the table or view.
* Catalog Explorer
* SQL
1. Log in to a workspace that is linked to the Unity Catalog metastore.
2. Click Catalog.
3. In the Catalog pane on the left, click the catalog that contains the schema (`hive_metastore` if it's in the Hive metastore).
Alternatively, you can search for the schema using the Type to filter field in the Catalog pane.
Run `SHOW SCHEMAS` in a notebook or the SQL query editor to list all schemas in a catalog or those that match a regular expression. Run `DESCRIBE SCHEMA` to get details about a schema. See SHOW SCHEMAS and DESCRIBE SCHEMA.
## Update a schema
To update (or alter) a schema in a Unity Catalog catalog, you can use Catalog Explorer or a SQL command.
Permissions required: Permissions required to update a schema in Unity Catalog depend on the update:
* To change the owner, you must be the owner or have `MANAGE` on the schema and `USE CATALOG` on the parent catalog.
* To rename the schema, you must be the owner or have `MANAGE` on the schema, and `USE CATALOG` and `CREATE SCHEMA` on the parent catalog.
* To add or update a comment, you must be the owner or have `MANAGE` on the schema and `USE CATALOG` on the parent catalog.
* To add or update tags, you must be the owner or have `USE SCHEMA` and `APPLY TAG` on the schema and `USE CATALOG` on the parent catalog.
* To add a table, you must be the schema owner or have `USE SCHEMA` and `CREATE TABLE` on the schema and `USE CATALOG` on the parent catalog.
* To add a volume, you must be the schema owner or have `USE SCHEMA` and `CREATE VOLUME` on the schema and `USE CATALOG` on the parent catalog.
* To grant and revoke permissions on the schema, you must be the schema owner, the owner of the parent catalog, a metastore admin, or have `MANAGE` on the schema and `USE CATALOG` on the parent catalog.
`MANAGE` on a schema doesn't require `USE SCHEMA` on that schema. See Usage privilege requirements for `MANAGE`.
* Catalog Explorer
* SQL
1. Log into a workspace that is linked to the Unity Catalog metastore.
2. Click Catalog.
3. In the Catalog pane on the left, click the catalog that contains the schema and then click the schema to open the schema details page.
Alternatively, you can search for the schema using the Type to filter field in the Catalog pane.
4. Use the following page elements on the schema details page to update the schema:
* Overview tab: update the owner, add or update tags, add or update comments. See Manage object ownership, Apply tags to Unity Catalog securable objects, and Add comments to data and AI assets.
* Permissions tab: grant and revoke privileges on the schema. See Manage privileges in Unity Catalog.
* The kebab menu: Rename the schema.
* Create button: create a table or volume in the schema. See Create or modify a table using file upload and What are Unity Catalog volumes?.
* To change the owner, add or update tags, set schema properties, and manage predictive optimization on the tables in a schema, run the `ALTER SCHEMA` command in a notebook or the SQL query editor. See ALTER SCHEMA.
* To grant or revoke privileges, use the `GRANT` or `REVOKE` command. See GRANT and REVOKE.
* To add tables, volumes, and other data and AI assets to a schema, see the documentation for creating the asset (for example Databricks tables or Manage model lifecycle in Unity Catalog).
* To rename a schema using SQL, you must create a new schema and move all assets into the new schema.
## Delete a schema
To delete (or drop) a schema in a Unity Catalog catalog, you can use Catalog Explorer or a SQL command.
If the schema or any of its child objects are included in an OpenSharing share, remove them from the share before deleting the schema. </excerpt>
</source>
<omitted_sources count="28">Additional source records were omitted from this bounded result.</omitted_sources>
</source_evidence>
Citations:
- 1: https://docs.databricks.com/aws/fr/sql/language-manual/sql-ref-information-schema?utm_source=openai
- 2: https://docs.databricks.com/aws/en/schemas/manage-schema?utm_source=openai
- 3: https://docs.databricks.com/aws/en/schemas/manage-schema?utm_source=openai
- 4: https://docs.databricks.com/aws/en/data-governance/unity-catalog/access-control/privileges-reference?utm_source=openai
Make the access check prove source readability.
The query checks only information_schema.schemata. Unity Catalog can expose a schema to a user with USE SCHEMA and USE CATALOG while the user lacks SELECT on the requested table or view. A returned schema row therefore does not prove that the source is readable.
After resolving the requested table or metric view, run a source-level read-only check and claim source readability only when that check succeeds.
Restrict metric-view preflight to YAML base tables.
When source_scope is a metric view, resolve its YAML base-table list first. Apply that list to the table, column, and constraint queries. Keep schema-wide enumeration for ordinary catalog/schema sources.
Pass the confirmed write mode through the runtime template.
job.md uses runtime.md §4 for pinned scoring notebooks and includes the confirmed WRITE_MODE in the config. The hard-coded WriteMode.OVERWRITE ignores APPEND, so an APPEND request can replace existing rows. The read-back must also use the APPEND row-delta check instead of comparing the table total. Keep OVERWRITE only as the documented default when no mode is supplied.
BigQueryConnector defaults location='US', but this host does not collect or pass the confirmed dataset location. A source or population dataset in EU or a single region can then fail with a location mismatch. Add a BIGQUERY_LOCATION value from preflight and pass it to both connector calls. BigQuery job locations must match referenced datasets. (raw.githubusercontent.com)
Also applies to: 265-266
Major · Poll the Databricks read-back statement. · runtime.md:151-154
wait_timeout='30s' does not guarantee completion. The API can return a statement ID with PENDING or RUNNING, without result. Dereferencing response.result.data_array then raises even after the write succeeds. Poll until SUCCEEDED, and handle FAILED and CANCELED. (docs.databricks.com)
Major · Align the description with the supported notebook host. · SKILL.md:3
Align the description with the supported notebook host.
The description targets any Python notebook, but the skill body and artifact workflow require an existing Snowflake notebook. Non-Snowflake requests can therefore receive host-specific guidance. Generalize the body and linked workflow, or keep Snowflake in the description.
Major · Generalize the training-diagnostics workflow beyond Snowflake. · SKILL.md:3
Generalize the training-diagnostics workflow beyond Snowflake.
SKILL.md now accepts any Python notebook, but its instructions still require an existing Snowflake notebook run. The linked workflow also labels the fresh-fit example and provenance as Snowflake-specific. Databricks/Genie requests can therefore receive incorrect host guidance.
Suggested fix
- “what does this training progress show?” using evidence from the user's existing Snowflake+ “what does this training progress show?” using evidence from the user's existing
notebook run.
Update the corresponding Snowflake-specific wording in references/diagnostics.md to refer to the user's existing notebook run rather than a Snowflake run.
Major · Include the Snowflake-only session preamble in the replacement. · kumo_finetuning_sdk.md:633-634
Include the Snowflake-only session preamble in the replacement.
The text says that only steps 1, 7, and 8 change for other connectors. The complete example also imports get_active_session() and executes session = get_active_session() before step 1. A File, S3, GCS, BigQuery, or Databricks example that follows this instruction still runs Snowflake-only code and can fail before building its connector. Move the session import and initialization into the Snowflake branch, or state that the complete preamble must be replaced. (github.com)
This new section says connector.sql() is available for Snowflake, Databricks, and BigQuery, but troubleshooting_signals.md still says that connector.sql(...) does not exist. An agent handling a custom-SQL source can therefore follow conflicting instructions. Scope the prohibition to unsupported connectors and state that supported connector.sql() calls return a source table, not rows. (github.com)
As per coding guidelines, keep one maintained explanation per topic.
19-21: Minor · Data Integrity & Integration · Quick win
Remove connector name unless Snowflake CoCo resolves it to a source scope.
The intake contract allows a connector name only when the active host defines how it resolves. Snowflake CoCo's preflight uses <DB>.INFORMATION_SCHEMA directly, and runtime.md requires explicit database and schema_name values. The current flow provides no mapping from a bare connector name to those values, so this source form can reach intake without a valid preflight or connector scope.
🐛 Suggested fix
-**Source scope.** A Snowflake database and schema (warehouse optional), a fully qualified semantic-view (`DB.SCHEMA.VIEW`, resolved by `kumo-data-science/accept/semantic_view.md`), or a connector-name.+**Source scope.** A Snowflake database and schema (warehouse optional), or a fully qualified+semantic view (`DB.SCHEMA.VIEW`, resolved by `kumo-data-science/accept/semantic_view.md`).
123-125: Minor · Maintainability & Code Quality · Quick win
Include warehouse discovery in the allowed intake operations.
Section 2 requires warehouses.list() during intake, but this rule permits only catalog metadata and the preflight probe. The agent receives conflicting instructions.
Add warehouse discovery to the allowed read-only operations. This is a documentation-contract conflict within §2.
agent-skills/skills/hosts/generic/adapter.md: 1
66-66: Minor · Functional Correctness · Quick win
Collect CSV types before completing preflight.
A CSV header supplies column names, not source types. If no reader returns inferred types, use the §0 ask-back instead of accepting the source as structurally verified. Use duckdb DESCRIBE or Arrow schema inference and record the resulting types. The SDK catalog contract also requires resolved column metadata. (raw.githubusercontent.com)
agent-skills/skills/hosts/generic/runtime.md: 3
202-205: Minor · Functional Correctness · Quick win
Preserve the validated CSV time format.
This path casts raw values directly to timestamp('us'). The SDK contract requires a timestamp_format for CSV time columns. Carry that format from table metadata and parse with it before writing TIMESTAMP; otherwise non-default date strings can fail during population creation. (raw.githubusercontent.com)
240-245: Minor · Functional Correctness · Quick win
Backtick-quote metadata-derived identifiers in the Databricks and BigQuery staging SQL.
The Databricks CREATE OR REPLACE TABLE statement interpolates CATALOG, POP_SCHEMA, POP_TABLE, SCHEMA, ENTITY_TABLE, ENTITY_KEY, and ENTITY_TIME without quoting. A name that contains a space or hyphen, or that is a reserved word, can make the statement fail to parse. An unquoted hyphen can also parse as subtraction, which returns wrong values instead of an error.
The BigQuery block already backtick-quotes its table paths. It still interpolates ENTITY_KEY and ENTITY_TIME without quotes, so the same failure applies to those column names.
🐛 Suggested fix
Databricks:
- time_col = f', CAST({ENTITY_TIME} AS TIMESTAMP) AS TIMESTAMP' if ENTITY_TIME else ''+ time_col = f', CAST(`{ENTITY_TIME}` AS TIMESTAMP) AS TIMESTAMP' if ENTITY_TIME else ''
r = ws.statement_execution.execute_statement(
warehouse_id=DATABRICKS_WAREHOUSE_ID, wait_timeout='50s',
- statement=(f'CREATE OR REPLACE TABLE {CATALOG}.{POP_SCHEMA}.{POP_TABLE} AS '- f'SELECT {ENTITY_KEY} AS ENTITY1{time_col} '- f'FROM {CATALOG}.{SCHEMA}.{ENTITY_TABLE}'))+ statement=(f'CREATE OR REPLACE TABLE `{CATALOG}`.`{POP_SCHEMA}`.`{POP_TABLE}` AS '+ f'SELECT `{ENTITY_KEY}` AS ENTITY1{time_col} '+ f'FROM `{CATALOG}`.`{SCHEMA}`.`{ENTITY_TABLE}`'))
BigQuery:
- time_col = f', CAST({ENTITY_TIME} AS TIMESTAMP) AS `TIMESTAMP`' if ENTITY_TIME else ''+ time_col = f', CAST(`{ENTITY_TIME}` AS TIMESTAMP) AS `TIMESTAMP`' if ENTITY_TIME else ''
...
- f'SELECT {ENTITY_KEY} AS ENTITY1{time_col} '+ f'SELECT `{ENTITY_KEY}` AS ENTITY1{time_col} '
146-147: Minor · Functional Correctness · Quick win
Read back the BigQuery destination from its own project, not from PROJECT_ID.
The read-back at lines 146-147 queries {PROJECT_ID}.{OUTPUT_DATASET}.{OUTPUT_TABLE} with bigquery.Client(project=PROJECT_ID). PROJECT_ID is the source scope. If the confirmed BigQuery destination is in a different project, the query can fail with a not-found error or count an unrelated table. The row-count assertion then does not check the write.
Derive the project from the confirmed destination, and use that value for both the client and the table path.
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #48 (base:
igutierrez/agent-skills-generic-host). Review that first; this PR shows only the Genie changes on top of it.Summary
This adds a third host for the
kumo-data-scienceskill: Databricks Genie Code, inside a Databricks workspace. It also fixes two gaps in the shared batch-inference intake that the Genie eval found on every host.The host:
agent-skills/skills/hosts/databricks-genie/adapter.md(intake):information_schemaand resolves the SQL warehouse, which the user confirms with the graph.semantic_view.md, and its primary keys come from the base tables' Unity Catalog constraints.runtime.md(Step 2):DatabricksIdentity()takes the notebook's own credentials; a service principal is used only on request.'<schema>__kumo__<table>'.run_sqlhelper on the statement API (wait_timeout='50s', polling) stages the population, cast toTIMESTAMP, and reads the destination back.job.md, the counterpart ofml_job.md:runs/submiton an existing GPU cluster; it never creates a cluster.Packaging:
package_skill.pygains agenietarget.--deployuploads to/Users/<user>/.assistant/skills/kumo-data-science/and reads every file back byte for byte.--prunedeletes, inside that folder only, the files the package does not ship.Core fix in
accept/batch_inference.md, which changes CoCo and generic too:Source of a saved model: a source that isn't in the conversation is not missing. The agent restates
Source: recorded with <model> [inferred]and reads the record at 1c.Scoring options by task type are now available at intake:
RANK TOP K; above 500, offer up to 500 or embeddings;The Node 1d restatement gains a "Scoring options" line, merged with Add a generic agent-skills host with an access-aware preflight #48's binary threshold default of 0.5.
The router names "a Databricks job" next to "a Snowflake ML Job".
Test plan
pytest agent-skills/tests: 176 pass. New tests check that:runtime.md;package_skill.py --check: coco, generic and genie resolve.kumo-engine[databricks]==1.0.0): 37/38 first try, 38/38 after repair. The one first-try failure was in a Databricks platform cell, not the notebook.Full results: kumo-ai/kumo_skill_dev
eval/results/2026-10-22-genie-host.md.🤖 Generated with Claude Code