SuperAPI AI Directory

triage-lineage

Data & analytics

View repository

Updated 10-16 06:16

About this skill

/triage-lineage — artefact-graph triage advisor

This skill reads the consumer project's existing artefact graph and tells the user where to start: which gap to close first, and which existing stage skill closes it. It is the repo's first advisor (meta) skill (ADR-0002) — a whole-graph diagnostic that runs before any artefact is chosen, not a checklist weighed while producing one.

This skill is self-contained: the vocabulary it leans on is inlined just below, and because it authors no artefact (ADR-0002 exempts advisor skills from the one-skill/one-artefact/one-lint pattern), it ships with no references/ contract and no scripts/ linter — there is nothing to read or run beside it. A per-skill install (npx skills add sleeplessv/relentless-data-skills --skill triage-lineage) is therefore complete on its own; it still reads the consumer's docs/ artefact graph at runtime, which is the point.

Vocabulary this skill assumes (the minimum it needs; the full worldview is optional deeper reading, linked at the end):

  • Artefact graph. The repo-internal set of markdown artefacts under the consumer's docs/ — Decision-Grade Questions (DGQs), ADRs, Source Profiles, Ingestion / Storage / Model Plans, and Serving Surfaces — plus the frontmatter links between them. This skill operates over the graph rather than adding a node to it. The artefact types, their directories, and the edge fields that wire them together are tabulated under What it reads below.
  • Action-change kill-switch. What would behave differently if the answer to a decision flipped. If the honest answer is "nothing" — no decision shifts, no person acts differently, no system reacts — the thing it hangs off does not deserve a build, so it is routed to retire / record rejected, never to build. This skill propagates that test across the whole graph; it is the soul of the skill (see the next section).
  • Live decision. A DGQ whose action_change is not the literal string nothing and whose status is not rejected. Every gap in the graph earns or loses priority by its graph distance to one of these. (Restated operationally where it is first used, below.)
  • Advisor (meta) skill. A skill that diagnoses the graph instead of producing a lifecycle artefact: it writes no durable file of its own and has no linter (ADR-0002). The durable, lint-gated artefacts are produced by the stage skills it routes into.

Optional deeper reading — not required to run this skill (a per-skill install works without it): the full repo worldview (including the "Action-change kill-switch", per-stage kill-switch, and "Advisor (meta) skill" glossary entries) in CONTEXT.md and the lifecycle reference in docs/data-engineering-101.md.

What this skill is — and is not

  • It is a non-interactive, single-pass scan that prints a report and stops. Unlike the stage skills, it runs no branching interview. It reads the graph, ranks the gaps, prints a two-tier report, and offers to launch the top-priority stage skill. There are no "turns".
  • It authors no durable artefact and has no linter. This is the explicit ADR-0002 exemption from ADR-0001's one-skill/one-artefact/one-lint pattern. The durable, lint-gated outputs (Source Profiles, rejections, ADRs) are produced downstream by the stage skills it routes into — they are theirs, not this skill's. This skill writes no file in any case. If you ever feel the urge to Write something here, you have misread the contract — route to the stage skill instead.
  • It is a doorway, not a builder. It opens doorways; the stage skills produce the inspected, lint-gated rooms behind them.

Soul of the skill: the kill-switch flip

ADR-0002 makes the kill-switch the required discipline of every advisor skill — it is what keeps the category from degrading into a generic coverage linter ("here are 40 things wrong"). This skill propagates the action-change kill-switch across the whole graph:

A gap that no live decision pulls on is routed to "confirm it can be retired, or record status: rejected" — never to "go build / document it."

This is the soul. The repo's load-bearing opinion is decisions, not templates. A flat "fix everything" coverage list is the template-mode failure under a new name, and ADR-0002 forbids it for this category. So the report is ranked by proximity to a live decision, and any node that chains to no live decision is sent to the kill-switch-flip section as a retire/reject candidate — it is never listed as "something to build". Refuse, explicitly, to print an exhaustive unranked checklist of everything missing.

A live decision is a DGQ whose action_change is not the literal string nothing and whose status is not rejected. (status: draft, needs-follow-up, and accepted all count as live, as long as action_change ≠ nothing.) Everything in the graph earns or loses priority by its distance to one of these.

What it reads

Layout detection (do this first)

  • If CONTEXT-MAP.md exists at the project root, the project uses the multi-context layout: the map enumerates several context roots, each its own subtree with its own docs/ and CONTEXT.md. Read the map, resolve each context's docs/ location, and triage per context — label every finding with its context so cross-context noise does not get conflated. Rank within each context against that context's own live decisions.
  • Otherwise (a single CONTEXT.md at the root), the project uses the single-context layout: triage the one docs/ tree at the project root.

The map's exact schema is the consumer's; do not assume a rigid format. Treat any path it names as a context root and look for that root's artefact directories beneath it.

The artefact directories

Read every file in each of these directories that exists (skip silently those that do not):

Directory Artefact Authored by
docs/requirements/ Decision-Grade Question (DGQ) /gather-requirements
docs/adr/ Architecture Decision Record (ADR) /write-adr
docs/sources-of-record/ Source Profile /profile-source
docs/ingestion-plans/ Ingestion Plan /plan-ingestion
docs/storage-plans/ Storage Plan /plan-storage
docs/model-plans/ Model Plan /model-data
docs/serving-surfaces/ Serving Surface /serve-data

Parse each file's YAML frontmatter only — you do not need the prose body to build the graph. The fields that carry edges:

Field On artefact Points at Direction
related_dgqs DGQ, Ingestion / Storage / Model Plan DGQ peer / soft
related_adrs every artefact ADR one-way (ADRs do not link back)
consumed_by Source Profile DGQ upstream (chain)
related_sources_of_record Ingestion Plan Source Profile upstream (chain)
related_ingestion_plans Storage Plan Ingestion Plan upstream (chain)
related_storage_plans Model Plan Storage Plan upstream (chain)
depends_on Model Plan Model Plan intra-stage DAG
related_model_plans Serving Surface Model Plan upstream (chain)
serves_dgqs Serving Surface DGQ loop-closure (chain back to Stage 0)

The lineage chain, upstream → downstream, is: DGQ → Source Profile → Ingestion Plan → Storage Plan → Model Plan → Serving Surface → (back to) DGQ. The chain edges are the consumed_by / related_* / serves_dgqs fields above; following them upstream from any node should terminate at a live DGQ. When it does not, you have a finding.

The procedure

  1. Detect layout (above). For a multi-context project, run steps 2–6 per context.
  2. Read the graph. Parse frontmatter from every file in the directories above. Build the node set and the edge set from the link fields. Note each node's status, each DGQ's action_change, and every node's sensitivity (DGQs, Source Profiles, Ingestion/Storage/Model Plans, and Serving Surfaces all carry one; ADRs do not).
  3. Tier 0 — broken references. Walk every link field on every node. Any path that points at a file that does not exist is a Tier-0 finding. Surface these first, always, regardless of action-change.
  4. Tier 1 — real gaps. Detect one-sided links and orphans (below). Rank each by graph distance to the nearest live decision; break ties by sensitivity.
  5. Kill-switch flips. Any node whose upstream chain reaches no live decision is pulled out of the ranked queue and listed separately as a retire/reject candidate — never as a build recommendation.
  6. Cold-start check. If there are zero live decisions in this context, do not produce a ranked queue at all — print the cold-start answer (below).
  7. Print the report. Write no file. Optionally offer to launch the top-priority stage skill.

Tier 0 — broken references (always first)

A broken reference is any consumed_by, related_*, depends_on, or serves_dgqs path that points at a file that does not exist on disk. These are active lies in the graph: the existing stage linters check that these fields are non-empty, but none of them checks that the referenced path resolves — so a dangling crosslink passes every lint today. Closing that gap is the concrete reason this skill exists (ADR-0002 Decision Driver D).

For each dangling reference, the recommendation is always the same and is action-change-independent:

Create the named artefact or remove the dangling reference.

Route the "create" half to the stage skill that owns the missing artefact (a missing docs/sources-of-record/*.md → /profile-source; a missing docs/adr/*.md → /write-adr; etc., per the routing table). The "remove" half is a one-line manual edit to the referencing file's frontmatter. Do not rank Tier-0 findings against action-change — a lie in the graph is fixed before anything is prioritised.

Tier 1 — real gaps, ranked by distance to a live decision

Detect, at minimum, two shapes:

  • One-sided links. A names B in a peer cross-link field, but B does not name A back. The only schema-symmetric field is related_dgqs between two DGQs (and any same-type peer cross-reference) — DGQ A's related_dgqs names B, but B's related_dgqs omits A. Recommend reconciling the pair (add the back-link, or drop the one-way link if it was wrong). Do not flag one-way-by-design fields as one-sided: related_adrs (ADRs never link back), depends_on (a directed DAG), and the chain fields consumed_by / related_sources_of_record / related_ingestion_plans / related_storage_plans / related_model_plans / serves_dgqs are meant to be one-directional — their gaps surface as orphans, not as one-sided links.
  • Orphans. A node that does not chain to a live decision in the direction it should:
    • An accepted DGQ with no downstream artefact referencing it — no Source Profile names it in consumed_by and no Serving Surface names it in serves_dgqs. A live decision with nothing built toward it. Route to /profile-source to start the chain.
    • A chain that does not terminate upstream at a live DGQ — follow the chain edges upstream from any node; if you never reach a DGQ whose action_change ≠ nothing (and which is not rejected), the node is floating. If the chain reaches a DGQ but that DGQ is dead (action_change: nothing or status: rejected), that is a kill-switch flip, not a build gap — see below.
    • A mid-chain stall — a node that does chain to a live decision upstream but has no downstream artefact one stage further (a Source Profile with no Ingestion Plan; an Ingestion Plan with no Storage Plan; a Storage Plan with no Model Plan; a Model Plan with no Serving Surface). Route to the next stage skill.

Ranking. Order Tier-1 findings by graph distance to the nearest live decision — distance 0 (the live DGQ itself, un-built-on) ranks first, then distance 1 (its Source Profile gap), and so on. Closer to a live decision = higher priority, because that is where documenting next buys the most. Tiebreaker within equal distance: sensitivity — regulated first, then confidential, then internal, then public. A regulated-data gap at the same distance as an internal one is the one to close first.

The kill-switch flip — the discipline that keeps this from being a linter

When a node's upstream chain reaches a DGQ that is dead (action_change: nothing, or status: rejected), or reaches no DGQ at all in a graph that has live decisions elsewhere, the honest recommendation is not "build the missing downstream artefact". It is:

This node chains to no live decision. Confirm it can be retired, or record status: rejected (re-run the owning stage skill to set the status and capture the rationale). Do not build downstream.

List these in a dedicated "Kill-switch flips — nothing live pulls on these" section, after the ranked Tier-1 queue. Never let a decision-less node sit in the build queue. This is the single rule that separates this advisor from a coverage linter: the linter says "this Source Profile has no Ingestion Plan — go build one"; this skill says "this Source Profile serves no live decision — confirm you can retire it." Same missing edge, opposite recommendation, and the difference is the whole point.

Cold-start — no live decisions yet

If the context has zero live decisions — no DGQs at all, or every DGQ is rejected / action_change: nothing — then every Tier-1 gap has infinite distance to a decision and there is nothing to rank. Do not invent a ranked queue. Say so plainly:

Surface any Tier-0 broken references first (they are still lies in the graph). Then: you have no live decisions yet — start with /gather-requirements. Until an ask is interrogated into a decision whose answer would change an action, nothing here chains to anything, so there is no "where to start" beyond starting at Stage 0.

This is the navigation case ADR-0002 was written for: "I have 40 undocumented pipelines and no DGQs — where do I start?" The answer is Stage 0, every time.

Routing table

Every finding names the exact existing skill that closes it. The advisor opens the doorway; the stage skill produces the lint-gated artefact.

Finding Route to
No live decisions / a real decision with no DGQ /gather-requirements
Accepted DGQ with no downstream Source Profile /profile-source
Source Profile (live-chained) with no Ingestion Plan /plan-ingestion
Ingestion Plan (live-chained) with no Storage Plan /plan-storage
Storage Plan (live-chained) with no Model Plan /model-data
Model Plan (live-chained) with no Serving Surface /serve-data
Dangling reference (Tier 0) the stage skill owning the missing artefact, or a manual frontmatter edit to remove the reference
Dangling / missing related_adrs, or a cross-cutting platform commitment surfaced by a repeated pattern /write-adr
A node that chains to no live decision (kill-switch flip) not a build skill — confirm retirement, or re-run the owning stage skill to record status: rejected

Report format

Print a single report. Lead with the scan summary, then Tier 0, then Tier 1 (or the cold-start answer), then the kill-switch flips. Keep it scannable — one finding per line, each ending in its route. Example shape (single-context project):

# /triage-lineage report

Layout:  single CONTEXT.md
Scanned: 3 DGQs · 2 Source Profiles · 1 Ingestion Plan · 0 Storage Plans · 0 Model Plans · 0 Serving Surfaces · 4 ADRs
Live decisions (action_change ≠ nothing, not rejected): 2

## Tier 0 — broken references (fix first; these pass every linter today)
1. docs/ingestion-plans/orders-into-raw.md → related_sources_of_record names
   docs/sources-of-record/kafka-orders.md, which does not exist.
   → Create it with /profile-source, OR remove the dangling reference.
(none → print "None.")

## Tier 1 — gaps ranked by distance to a live decision
1. [dist 0 · regulated]  docs/requirements/sara-churn-calls.md (accepted) has no
   downstream Source Profile — a live decision with nothing built toward it.
   → Start the chain with /profile-source.
2. [dist 1 · internal]   docs/sources-of-record/stripe-charges.md chains to a live
   decision but has no Ingestion Plan.
   → /plan-ingestion.

## Kill-switch flips — nothing live pulls on these (do NOT build)
- docs/sources-of-record/legacy-mixpanel.md: its only consumer DGQ
  (docs/requirements/growth-vanity-metric.md) is status: rejected.
  → Confirm it can be retired, or record status: rejected via /profile-source.
  Do not build an Ingestion Plan for it.

For the cold-start case, replace the Tier-1 section with the cold-start answer above. After printing, write nothing. Offer once to launch the top-priority route — e.g. "Want me to start /profile-source for the churn DGQ now?" — and if the user says yes, hand off to that skill; this skill still authors nothing itself.

Scope guard (v0.1)

Repo-internal self-audit only. This slice reads the markdown artefact graph under docs/ and nothing else. It does not:

  • parse a dbt manifest.json or any transformation-tool metadata;
  • query a live warehouse, lakehouse, or operational store;
  • introspect an orchestrator (Airflow/Dagster/etc.) or a BI/serving tool;
  • measure dashboard usage or pipeline run history.

Those external-graph sources are deferred to later slices. Within this scope, the skill's correctness rests entirely on this prompt — there is nothing for a linter to check, which is exactly why the kill-switch discipline above is non-negotiable.