Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions skills/hotdata/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ Returns workspaces with `public_id`, `name`, `active`, `favorite`, `provision_st

**Parquet only:** `databases tables load` accepts **parquet** files (local `--file`, remote `--url`, or a pre-staged `--upload-id`).

**Active database:** `hotdata databases set <id_or_description>` saves the active database to config. All `databases tables` subcommands and all `context` commands default to the active database; pass **`--database <id>`** to override per-command.
**Active database:** `hotdata databases set <id>` saves the active database to config. All `databases tables` subcommands and all `context` commands default to the active database; pass **`--database <id>`** to override per-command.

```
hotdata databases list [--workspace-id <workspace_id>] [--output table|json|yaml]
hotdata databases create [--name <display_name>] [--catalog <alias>] [--table <table> ...] [--schema public] [--expires-at <duration|timestamp>] [--workspace-id <workspace_id>] [--output table|json|yaml]
hotdata databases fork [<id_or_name>] [--name <display_name>] [--expires-at <duration|timestamp>] [--workspace-id <workspace_id>] [--output table|json|yaml]
hotdata databases set <id_or_name>
hotdata databases set <id>
hotdata databases unset
hotdata databases <id_or_name> [--workspace-id <workspace_id>] [--output table|json|yaml]
hotdata databases delete <id_or_name> [--workspace-id <workspace_id>]
Expand All @@ -116,8 +116,8 @@ hotdata databases tables delete <table> [--database <id_or_name>] [--schema publ

- `list` — all managed databases in the workspace. Active database is marked with `*` under the DEFAULT column; CREATED shows when each database was made.
- `create` — creates a new managed database. `--name` is an optional human-readable display name. `--catalog` sets the SQL alias used in queries (`SELECT … FROM <catalog>.schema.table`); must be `[a-z_][a-z0-9_]*`. `--expires-at` accepts relative durations (`24h`, `7d`, `90m`) or an RFC 3339 timestamp; omitting means no expiry. Repeat `--table` to declare tables up front.
- `fork` — creates a new managed database that is an independent deep copy of an existing one (same schemas, tables, and data); the source is left unchanged and the two diverge freely afterwards. The source defaults to the active database; pass `<id_or_name>` (id, catalog, or name) to fork another. `--name` defaults to `<source>-fork` (so the two stay distinguishable in `list`); `--expires-at` accepts a relative duration or RFC 3339 timestamp, and when omitted a still-future source expiry is carried over. The fork becomes the active database on success. The fork answers to the **same catalog alias** as its source inside its own scope; indexes are **not** carried over. Only databases created with the current (DuckLake) storage engine can be forked — older parquet-backed databases return an error.
- `set` — saves `<id_or_name>` as the active database. Subsequent `databases tables` and `context` commands use it automatically.
- `fork` — creates a new managed database that is an independent deep copy of an existing one (same schemas, tables, and data); the source is left unchanged and the two diverge freely afterwards. The source defaults to the active database; pass `<id_or_name>` (id, catalog, or name) to fork another. `--name` defaults to `<source>-fork` (so the two stay distinguishable in `list`); `--expires-at` accepts a relative duration or RFC 3339 timestamp, and when omitted a still-future source expiry is carried over. The fork becomes the active database on success. The fork answers to the **same catalog alias** as its source inside its own scope; connection catalogs attached to the source are **re-attached** to the fork, but indexes are **not** carried over. Only databases created with the current (DuckLake) storage engine can be forked — older parquet-backed databases return an error.
- `set` — saves the database **id** as the active database (unlike `fork`, `delete`, and inspect, `set` does not resolve catalog aliases or names — pass the `dbid...` id). Subsequent `databases tables` and `context` commands use it automatically. Note that a successful `fork` also updates this: the fork becomes the active database.
- `unset` — clears the active database from config.
- `<id_or_name>` — inspect one database (id, catalog, name, expires_at).
- `delete` — removes the managed database; clears the active-database config if it matched.
Expand Down
13 changes: 13 additions & 0 deletions skills/hotdata/references/WORKFLOWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,19 @@ A `hotdata query` runs inside **one** managed database; its scope sees that data

For **Chain** materializations into managed databases, see **`hotdata-analytics`**.

### Workflow: fork before risky changes

Before destructive experimentation (bulk replaces, schema rework, testing a load pipeline), fork the database and experiment on the copy — the source stays untouched and the two diverge freely:

```bash
hotdata databases list # note the source database id (dbid...)
hotdata databases set <source_id> # source to protect (`set` takes an id)
hotdata databases fork --expires-at 24h # deep copy; becomes the active database
hotdata databases load --catalog sales --table orders --file ./risky.parquet # hits the fork
```

**Capture the source database id up front.** After the fork, both databases answer to the same catalog alias (here `sales`), so the id is the only unambiguous way to refer back to the source. The shared alias means experimental SQL runs unchanged against the fork. Attached connections are re-attached to the fork; indexes are not carried over. When done, keep the fork (`databases set <source_id>` to switch back to the source) or `databases delete` it. Only DuckLake-backed databases can be forked — see `fork` in the main skill for details.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit: (not blocking) The databases delete cleanup path has the same catalog-ambiguity problem this workflow was rewritten to avoid. After the fork, both source and fork answer to catalog sales, so databases delete sales hits resolve_database and errors with "multiple databases have catalog 'sales' — use the database id instead" (src/commands/databases.rs:457-466). Deleting the fork therefore needs the fork id, but the workflow only tells the agent to capture the source id. The fork id is available (the fork command prints it / it's the new active db), so consider noting that databases delete also needs the fork's dbid..., e.g. "or databases delete <fork_id> it (the id fork printed)."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — addressed in the latest commit: the fork step now says to note the fork id from the command output, and the cleanup line reads databases delete <fork_id>. The prose now says to capture both ids (source from databases list, fork from the fork output).


---

## Model
Expand Down
Loading