Skip to content

Tables and Columns as Workspace Outputs

llms.txt lists every page for an agent
Optional: hand this page to your coding agentThe steps work by hand too.
Show the whole prompt
Read https://intentius.io/chant/lexicons/sql/workspace-outputs/.
In this chant workspace, add a link in `chant.workspace.json` from the member I name to each table or column it reads in the sql member, by its output name such as `public.orders.customer_id`.
Run `npx chant workspace check` and `npx chant workspace graph`, fix each link it reports missing or unresolved, and open a pull request with the declaration.
Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.

In a chant workspace, a member that declares sql tables exposes each table and view, and each of their columns, as an output. Another member links to one the way it links to any output, and chant workspace check fails when the column is gone. Nobody writes output(...) for these. They were added in #3931.

DialectTable or viewColumn
Postgres<schema>.<table><schema>.<table>.<column>
ClickHouse<database>.<table><database>.<table>.<column>

An unqualified Postgres name is in public, and an unqualified ClickHouse name in default.

Names are written unquoted, in the case the dialect keeps:

  • Postgres folds an unquoted identifier to lower case and keeps a quoted one as written. CREATE TABLE Orders and CREATE TABLE orders are both public.orders, while CREATE TABLE "Orders" is public.Orders, a different output. A quoted name appears in the output without its quotes.
  • ClickHouse is case-sensitive, so a name is kept as written, quoted or not.

A link that differs from an output only in case is told the name it probably meant, since links match exactly.

The names come from the declarations in source, never from a profile’s, environment’s or tenant’s rendering. A member that renames its database or schema per environment at deploy time exposes the same outputs everywhere.

Views and materialized views are outputs, named like tables. Their columns are outputs too:

  • a declared column list, CREATE VIEW totals (customer_id, total) AS ..., gives the columns;
  • otherwise each item of the select list gives one, by its alias or the column it reads (SELECT customer_id, sum(amount) AS total gives customer_id and total);
  • a *, or an expression with no alias, can’t be named without a server. The view’s columns are then incomplete, and a link to one is reported as unresolved rather than missing.

A workspace with a Postgres member db and an app that reads orders.customer_id:

{
"name": "shop",
"schema": 1,
"members": [
{ "name": "db", "dir": "db", "kind": "chant" },
{
"name": "app",
"dir": "app",
"kind": "other",
"because": "the service that reads the database",
"links": [{ "member": "db", "output": "public.orders.customer_id" }]
}
]
}
db/src/orders.ts
import { table } from "@intentius/chant-lexicon-sql/postgres";
export const orders = table`
CREATE TABLE orders (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_id bigint NOT NULL,
amount numeric(12, 2) NOT NULL
)`;

db exposes public.orders, public.orders.id, public.orders.customer_id and public.orders.amount, and the link resolves. Drop customer_id and the check fails, naming the consumer:

WSP093 app's link to db output public.orders.customer_id does not resolve: db has no output public.orders.customer_id; its outputs: public.orders, public.orders.amount, public.orders.id

Rename it and leave a rename hint, and the message says where it went:

buyer_id bigint NOT NULL, -- previously: customer_id
db has no output public.orders.customer_id; it was renamed to public.orders.buyer_id, so link to that instead

The same workspace with a ClickHouse member links to analytics.events.user_id for a table declared as ${analytics}.events.

chant workspace check never runs a member’s code. It folds the member’s TypeScript the way chant build does under its sandbox: a file whose table and view templates are plain text and interpolations of other declarations folds to the same tables a build makes. The member’s plain .sql files are read too.

A file that imports the sql lexicon and does not fold, such as one that reads process.env to choose a table’s name, is not run. Its tables are a gap: the member’s outputs are marked incomplete, and a link to a name the check did not find is unresolved (WSP094, info) rather than missing. Under chant workspace check --at, the revision’s files are not on disk to fold, so a sql member’s outputs are a gap there too.

chant workspace graph lists the outputs in its exports, from each member’s chant graph --format ir, with a renamed output’s old names in previously.

chant