Skip to content
Data
Skill

/knowledge-base

Write a technical spec after research. Distills exploration into structured decisions. On retries, read the existing spec instead of re-researching.

BOOST
From plugin
signalpilot
48728 skills2 agents
Install
$ npx -y skills add signalpilot-labs/signalpilot --skill knowledge-base --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/knowledge-base

Context preview

The summary Claude sees to decide when to auto-load this skill.

Write a technical spec after research. Distills exploration into structured decisions. On retries, read the existing spec instead of re-researching.

SKILL.md

knowledge-base.SKILL.md
name: knowledge-base
description: "Write a technical spec after research. Distills exploration into structured decisions. On retries, read the existing spec instead of re-researching."

Knowledge Base - Technical Spec

1. Check for Existing Spec

Check if `<project_dir>/technical_spec.md` exists.

  • **If it exists**: preserve `prebuild_state.md` and validate affected decisions against the task, YML/config, source relations, verifier findings, and preserved pre-build evidence because retries may invalidate implementation assumptions. Do not treat a relation first materialized during the attempt as original evidence. Update unsupported decisions before SQL changes.
  • **If it does not exist**: write one using the rules in Sections 2-5.

2. Write the Spec

After Step 5 research, MUST write `<project_dir>/technical_spec.md`.

The spec distills exploration into decisions. NOT a copy of research output. NOT SQL. NOT domain knowledge. The spec answers: "what will I build, from what sources, with what joins and filters, and why?"

STOP writing the spec when every model has all seven fields from Section 3 and every decision in Section 4 has WHAT + WHY + EVIDENCE.

3. Per-Model Plan (mandatory fields)

For EACH model, MUST include ALL seven fields:

1. **Source**: `ref('model_name')` or raw table name. If an intermediate model already computes a value you need, MUST write `ref('that_model')`. Do NOT recompute from raw tables - recomputing introduces precision drift from rounding order differences. Before finishing the spec, check it against itself: when Key expressions names a model as the source of an expression, Source must list `ref()` of that same model - fix whichever is wrong. 2. **Driving table**: which table in the FROM clause. State the row count from the Step 1 scan or a `query_database` COUNT. 3. **Joins**: each join with type (LEFT/INNER/FULL OUTER) and exact keys. "Join some dimension table" is not a plan. `LEFT JOIN dim_customers ON fct.customer_id = dim.customer_id` is a plan. 4. **Key expressions**: computed columns. If a sibling or upstream model defines this expression, copy it exactly and name the source model and column. Untraced expression reuse causes silent divergence. 5. **Filters**: WHERE/HAVING clauses with justification (domain skill rule, YML description, or `query_database` discovery). If no filter, write "none." Unjustified filters silently drop rows and break row counts. 6. **Expected grain**: what one row represents (one per customer, one per line item, one per day-product pair). 7. **Expected rows**: from `query_database` cardinalities or entity counts. Do NOT guess.

Example:

## Model: fct_revenue
- Source: ref('int_order_items') - already computes item_total, do NOT recompute
- Driving table: int_order_items (600K rows)
- Joins: dim_customers ON customer_id = customer_id (LEFT JOIN)
- Key expressions:
 - total_revenue = SUM(item_total)  [from int_order_items.item_total]
 - order_count = COUNT(*)
- Filters: WHERE status != 'returned' (domain-ecommerce: exclude returns from revenue)
- Expected grain: one row per customer
- Expected rows: ~75K (query: 75K distinct customers excluding returns)

4. Decisions Section

MUST include a Decisions section after all model plans. Each decision states WHAT you chose, WHY, and what EVIDENCE supports it. These are the choices a reviewer needs to verify your work.

One decision per line. Example:

## Decisions
- int_order_items computes item_total -> fct_revenue refs it (avoids precision drift from recomputation)
- Returns excluded in fct_revenue, not in int_order_items (intermediate preserves all rows for other consumers)
- LEFT JOIN dim_customers (query: 75K customers vs 73K in dim - some deleted, keep all)
- COUNT(*) not COUNT(DISTINCT order_id) (grain check: COUNT(*) != COUNT(DISTINCT) on int_order_items)

5. Build Order

MUST list models in dependency order at the top of the spec. For each model, note its layer (staging/intermediate/mart) and dependencies. Build failures from wrong ordering waste turns on debugging instead of building.

## Build Order
1. stg_payments (staging - no dependencies)
2. int_order_items (intermediate - depends on stg_payments)
3. fct_revenue (mart - depends on int_order_items)

6. Updating After Verification

When a verifier reports FAIL, update `technical_spec.md` BEFORE changing SQL. The spec is the source of truth - SQL follows the spec, not the other way around. Changing SQL without updating the spec causes the spec to drift, making future retries unreliable.

1. Find the model section in the spec. 2. Edit the field that caused the failure. 3. Add a decision line explaining the change. 4. Rewrite the SQL from the updated spec.

7. What Does NOT Go in the Spec

  • Full SQL - that belongs in `.sql` files (written after the spec)
  • Raw `query_database` output - that is exploration data
  • Domain knowledge - that is in domain skills
  • Column descriptions from YML - read YML directly when writing SQL
  • dbt-write rules (JOIN defaults, filter rules, grain checks) - those

rules live in the dbt-write skill. The spec records your DECISIONS about which rules apply, not the rules themselves.

Read more
Ships withsignalpilot
Get the whole plugin
Stats
487
Stars
27
Forks
Active
Maintenance
Python
Language
Apache-2.0
License
17d ago
Last commit
6mo ago
Created
4h ago
Added

Repo: signalpilot-labs/signalpilot

Other skills on signalpilot.