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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
99 changes: 99 additions & 0 deletions .agents/skills/template-authoring/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
name: template-authoring
description: Create, update, or review RelationalAI templates, including the model package, README, template-docs sidecar, runbook, and validation.
---

# Template authoring

Use this skill for any request to create, refactor, document, or review a
template in this repository.

## Select the operation

- **Create**: start from `sample-template/`, use the standard layout, and complete
every required artifact.
- **Update**: preserve the existing command, behavior, and outputs while
keeping code, README, runbook, and sidecar synchronized.
- **Review**: do not edit. Report reproducibility, structure, documentation,
sidecar, and validation issues with exact file paths.

Legacy templates without `template-docs.yaml` may remain README-only. Do not
require migration merely because an existing template changed. New
`<slug>/README.md` files require a sidecar, and an adopted sidecar must not be
removed while the template remains.

## Required workflow

1. Read the entire template directory, including its runner, `pyproject.toml`,
README, runbook, data files, and existing sidecar.
1. Preserve the entrypoint, solver choices, constraints, thresholds, output
labels, and data semantics unless the request explicitly changes them.
1. For new templates and intentional migrations, use this layout:

```text
<slug>/
├── README.md
├── template-docs.yaml
├── model/
│ ├── __init__.py
│ ├── schema.py
│ └── source.py
├── <runner>.py
├── runbook.md
├── pyproject.toml
└── data/
```

1. Put only stable model declarations in `model/schema.py`: create the
`Model`, then declare concepts, identity keys, properties, and
relationships with direct `model.Concept`, `model.Property`, and
`model.Relationship` calls.
1. Put source reads, normalization, and base-fact mappings in
`model/source.py`. Keep solver declarations, derived reasoning, result
queries, and reporting in the runner.
1. Re-export the model and stable schema symbols from `model/__init__.py`.
A single-source template may load its source on import. A multi-source
template must expose explicit loader functions and let each runner choose
the correct one.
1. Keep README commands, code links, `runbook.md`, and `template-docs.yaml`
aligned with the final paths and symbols.
1. Follow [the sidecar contract](./resources/template-docs.md) and select only
routes from [the guide catalog](./resources/guide-links.md).
1. Run [focused validation](./resources/validation.md). Do not claim runtime
verification if credentials, an engine, Snowflake, or other connected
resources were unavailable.

## README contract

The README remains the runnable GitHub entry point and owns the title,
description, problem statement, prerequisites, commands, and expected output.
README-only templates can retain customization, troubleshooting, and support
information. An enhanced template can keep a short README when its docs page
provides the model explorer and walkthrough.

- Explain the problem before implementation details.
- For a long-form README, put the solution flow in **What you'll build** and
use **What's included** to identify the schema, source, runner, runbook,
sample data, and outputs.
- When the sidecar sets `page.download_and_run_from_readme: true`, a README may
contain only **What this template is for** and **Quickstart**, plus an
opening link to the docs page. Put access requirements, pinned dependencies,
commands, results, and necessary data attribution in Quickstart. Set
`page.omit_readme_preamble: true` when that opening link is for README
readers only.
- Do not add a standalone **Template structure** section. The generated docs
file browser already serves that purpose.
- For long-form READMEs, use small Markdown tables for representative sample
rows. Keep large data sets out of the README.
- If **Model overview** or **How it works** remain in the README, keep them
concise; enhanced docs can omit them through `page.omit_from_readme`.
- Keep the Quickstart copy/paste-friendly and include a small success signal.

## Completion

Report:

- Files changed.
- Behavior intentionally preserved or changed.
- Checks run and their exact outcomes.
- Any connected runtime command that remains unverified and why.
48 changes: 48 additions & 0 deletions .agents/skills/template-authoring/resources/guide-links.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Public guide-link catalog

Use only public, non-draft RelationalAI documentation routes. Prefer the one or
two guides that directly support each walkthrough step.

## Modeling

- `/build/guides/modeling/create-model-instance/`
- `/build/guides/modeling/declare-concepts/`
- `/build/guides/modeling/declare-relationships-and-properties/`
- `/build/guides/modeling/declare-data-sources/`
- `/build/guides/modeling/define-base-facts/`
- `/build/guides/modeling/derive-facts-with-logic/`
- `/build/guides/modeling/query-a-model/`

## Rules-based reasoning

- `/build/guides/reasoning/rules-based/`
- `/build/guides/reasoning/rules-based/aggregate-and-group-data/`
- `/build/guides/reasoning/rules-based/handle-missing-data/`
- `/build/guides/reasoning/rules-based/use-dates-and-datetimes/`
- `/build/guides/reasoning/rules-based/work-with-numbers/`
- `/build/guides/reasoning/rules-based/work-with-strings/`

## Graph reasoning

- `/build/guides/reasoning/graph/create-a-graph/`
- `/build/guides/reasoning/graph/run-an-algorithm/`

## Predictive reasoning

- `/build/guides/reasoning/predictive/construct-a-graph/`
- `/build/guides/reasoning/predictive/define-a-learning-task/`
- `/build/guides/reasoning/predictive/solve-a-classification-problem/`
- `/build/guides/reasoning/predictive/inspect-predictions/`
- `/build/guides/reasoning/predictive/monitor-training/`

## Prescriptive reasoning

- `/build/guides/reasoning/prescriptive/decision-problems/create/`
- `/build/guides/reasoning/prescriptive/decision-problems/variables/`
- `/build/guides/reasoning/prescriptive/decision-problems/constraints/`
- `/build/guides/reasoning/prescriptive/decision-problems/solve/`
- `/build/guides/reasoning/prescriptive/decision-problems/solutions/`

The docs preview validates routes against the current public collection and
rejects missing, private, or draft targets. Update this catalog when a route
moves; do not work around validation with a redirect, query, or fragment.
187 changes: 187 additions & 0 deletions .agents/skills/template-authoring/resources/template-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# `template-docs.yaml` contract

The sidecar is inert data consumed by the documentation build. It must contain
no HTML, MDX, imports, exports, expressions, JavaScript, or executable code.
Unknown keys are errors.

## Top-level shape

```yaml
version: 1

page:
lead_from_readme: []
omit_from_readme: []

model_explorer:
title: Plain-text title
description: Plain-text description
concepts: []
property_labels: []
relationships: []
sources: []

guided_walkthrough:
title: Plain-text title
description: Plain-text description
steps: []

sample_data:
default_rows: 4
tables: []
```

`sample_data` is optional. Every other top-level key is required.

## Page composition

- `lead_from_readme`: zero or more unique lowercase README heading IDs.
- `omit_from_readme`: zero or more unique lowercase README heading IDs.
- A heading ID cannot appear in both lists.
- Both lists must reference headings still present in the README. Use
`omit_from_readme: []` when a shorter README removes those sections.
- Use the IDs produced by GitHub-style heading slugs, such as
`what-this-template-is-for` and `what-youll-build`.
- `download_and_run_from_readme: true` (optional) extracts the README Quickstart
into a generated "Download and run the template" section. State access and
Python requirements before the first step, include any required SQL setup
there, then provide five ordered steps: download, Python environment,
install, configure with the Start building with PyRel configuration builder,
and run. Keep any representative output directly after its runner command.
Templates without this flag retain their existing rendering.
- `omit_readme_preamble: true` (optional) excludes the text before the first
README `##` heading from the enhanced HTML and Markdown pages. Use it when
the README opens with links to its own generated model explorer and
walkthrough. Without the flag, existing preamble text remains visible.

## Model explorer

`concepts` contains 1-50 entries:

```yaml
- symbol: Account
description: A customer account evaluated by the model.
```

The symbol must be a top-level concept declared in `model/schema.py`. Identity
keys and properties are extracted from Python and must not be repeated.

`property_labels` optionally overrides the short road label for a
concept-valued property:

```yaml
- symbol: Scenario.regime
label: has regime
reading: Scenario has regime
```

The symbol must resolve to a direct `model.Property` declaration on a selected
concept with exactly two distinct selected concept inputs. Repeated inputs of
the same concept collapse to one road endpoint, so a property over
`Stock, Stock, Regime` connects `Stock` to `Regime`. Use `reading` when the
inspector headline needs the destination concept or other context that the
short road label omits. Direct concept-valued properties appear as roads
automatically; `property_labels` opts scalar-valued properties into the diagram.
Other scalar properties remain in the owning concept's details.

`relationships` contains up to 100 entries:

```yaml
- symbol: Transaction.sender
label: sent by
reading: Transaction is sent by Account
description: Connects each transfer to its sending account.
```

The relationship symbol must resolve in `model/schema.py`. Unary relationships
appear in the owning concept's details, while binary relationships also appear
as links in the model diagram. Endpoints are extracted; the sidecar supplies
the reader-facing label, reading, and description.

`sources` contains up to 50 entries:

```yaml
- path: data/accounts.csv
description: Account identifiers and attributes.
```

Use repository-relative paths. The extractor infers mappings from
`model/source.py`. Add `populates` only when dynamic code makes the mapping
ambiguous:

```yaml
populates:
- Account
- Transaction.sender
```

Every override must name a concept or relationship selected by
`model_explorer`.

## Guided walkthrough

Provide 1-6 semantic steps. One or two steps may be present while a walkthrough
is under editorial review; a complete walkthrough should normally have 3-6
steps. Each step has one canonical Python file, one focus form, and 1-2 public
guide links:

```yaml
- id: load-inputs
title: Load account records
explanation: >-
load_accounts maps account rows into the shared Account concept.
focus:
file: model/source.py
symbols:
- load_accounts
references:
load_accounts:
symbol: load_accounts
Account:
symbol: Account
links:
- title: Define base facts
href: /build/guides/modeling/define-base-facts/
```

- Prefer `focus.symbols`; use 1-25 unique Python symbols.
- Use `focus.anchors` only for a meaningful span without a stable symbol:

```yaml
focus:
file: runner.py
anchors:
- start: "# Stage 3: Optimize"
end: "# Stage 4: Report"
```

- Anchor text must occur exactly once, in order, in the selected file.
- Reference keys must appear verbatim in the explanation.
- Reference values contain only `symbol`.
- IDs use lowercase words separated by hyphens.
- Update the sidecar whenever a referenced path, symbol, or anchor changes.

## Sample data

Select only local CSV files and representative columns:

```yaml
sample_data:
default_rows: 4
tables:
- path: data/accounts.csv
title: Accounts
description: Representative account records.
columns:
- id
- status
rows: 3
```

- `default_rows` and per-table `rows` must be integers from 1 through 10.
- A table needs at least one unique column and may select at most 50.
- The docs build reads headers, counts all rows, and emits only the bounded
sample. Do not copy data rows into YAML.
- Order tables by the reader's workflow rather than alphabetically.

Use `sample-template/template-docs.yaml` as the copyable minimal example.
33 changes: 33 additions & 0 deletions .agents/skills/template-authoring/resources/validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Focused validation

Run the smallest checks that cover the changed template and repository policy.
From the repository root:

```bash
ruff check <template-path> sample-template scripts tests
python -m compileall -q <template-path> sample-template
python -m unittest discover -s tests -p "test_*.py"
python scripts/generate_template_index.py --check
```

For a committed branch, run the pull-request policy against its base:

```bash
python scripts/validate_changed_templates.py --base-ref origin/main
```

The changed-template check:

- Requires `template-docs.yaml` when a `<slug>/README.md` is newly added or
moved into a new template directory.
- Allows changes to existing README-only templates without forcing migration.
- Rejects removing an adopted sidecar while that template's README remains.

For any new or changed sidecar, use the docs preview workflow as the
authoritative strict-schema, source-symbol, anchor, CSV, and public-guide-link
validation.

Finally, run the exact README command in a fresh environment. If it needs
customer credentials, a RelationalAI engine, Snowflake, or another unavailable
connected resource, report the command as unverified. Linting and compilation
are not runtime proof.
Loading
Loading