Skip to content

Commit the agent tooling: workflow hooks, three project skills, and a fully ignored reports/ - #53

Open
andre-salvati wants to merge 5 commits into
mainfrom
docs/data-divergence-skill
Open

Commit the agent tooling: workflow hooks, three project skills, and a fully ignored reports/#53
andre-salvati wants to merge 5 commits into
mainfrom
docs/data-divergence-skill

Conversation

@andre-salvati

Copy link
Copy Markdown
Owner

What?

Makes this repo's agent tooling part of the repo instead of one developer's local config:

  • .claude/hooks/ + .claude/settings.json — the three workflow hooks (branch protection, PR description as merge body, CHANGELOG gate) and the settings file that registers them.
  • data-divergence — a new skill for investigating why two datasets that should agree don't.
  • project-costs / sql-diagram — converted from slash commands to skills, each shipping a worked example.md plus the artifact it reads.
  • reports/ is now entirely gitignored, and the four artifacts that were tracked there moved into the skills that use them.

Why?

CLAUDE.md and specs/workflow.md state the hook-enforced rules as project rules, but the hooks lived only in an ignored config — so the rules were a description of one machine, not a property of the repo. A fresh clone got none of them.

The two slash commands only loaded when someone typed them. As skills their descriptions sit in context and match on relevance, so "why is our Databricks spend up?" reaches project-costs without anyone remembering it exists. Typing /project-costs still works.

data-divergence came out of a live investigation this week (batch vs SDP silver in prod, a 13-day date shift). It is written generically — no table or column names from this project.

How?

.gitignore un-ignores by name, never by wildcard. The AI Dev Kit installs ~30 user-level skills into .claude/skills/; a wildcard there would commit all of them, the exact drift specs/tooling.md#install-layout documents as having shadowed the user-level set for two months. Git also won't descend into an excluded directory, so .claude/skills/ is re-included before its children are re-excluded. git add -An .claude/ is the check — it must list only our paths.

settings.json uses $CLAUDE_PROJECT_DIR. Absolute paths would break every other clone. Machine-specific entries (an update check pointing into ~/.ai-dev-kit/) moved to the still-ignored settings.local.json; Claude Code merges the two.

Examples live with the skill, not in reports/. .gitignore only governs untracked files, so ignoring reports/ would have left the four force-added artifacts in the index and made the rule a lie. They moved to .claude/skills/<skill>/examples/, a committed path. The old "git add -f one to keep it as an example" advice is removed everywhere it appeared.

Validation?

  • git add -An .claude/ lists only our paths — no kit skills leak in. Re-run after touching that block.
  • Hooks commit at mode 100755; verified against a throwaway index.
  • protect-main-branch.sh ran on all three commits in this branch under the new $CLAUDE_PROJECT_DIR path and correctly allowed them (on a branch, not main). The other two fire on gh pr merge and are untested until this PR merges — require-changelog-entry.sh blocking that merge until the CHANGELOG entry lands is itself the test.
  • Both README example links re-checked against their new paths.
  • All three skills parse: valid frontmatter, name matching directory.
  • sql-diagram was exercised end to end on a deliberately complex query. That run found real blind spots in the tool — window functions are never drawn, WHERE is only drawn above a join, OUTPUT shows aliases not expressions — which are now documented in the skill rather than left to be rediscovered.
  • No Python changed; ruff pre-commit hooks skipped on every commit.

Impact in prod

  • No table schema/data change — no production impact.
  • Schema change — classify and declare the remediation:

Tooling and docs only. No commonSchemas.py, task module, cluster key, job definition or bundle resource is touched, so nothing here reaches a medallion table or a running job.

Chosen strategy: leave as-is — nothing to migrate.


⚠️ Unrelated and still open: job1_prod has failed daily since 2026-07-24 (extract_source2, DQX 0.15.0 metadata mismatch on raw.order_quarantine). The fix is commit 6606021 on docs/ci-cd-hardening, not yet merged. It is not addressed here.

andre-salvati and others added 5 commits July 25, 2026 06:47
… wiring

Adds a repo-owned `data-divergence` skill for investigating why two datasets
that should agree don't, and commits the three workflow hooks plus the
settings file that registers them.

The hooks enforce rules CLAUDE.md and specs/workflow.md already state as
project rules (branch protection, PR description as merge body, CHANGELOG
gate), but they lived only in one developer's ignored config — so the rules
were documentation of one machine rather than a property of the repo.
settings.json now refers to them via $CLAUDE_PROJECT_DIR; machine-specific
entries move to the still-ignored settings.local.json.

.gitignore keeps `.claude/*` blanket-ignored and un-ignores only these paths
by name, so the AI Dev Kit's user-level skills in .claude/skills/ stay out.
`git add -An .claude/` is the check that this holds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…xamples

/project-costs and /sql-diagram were slash commands, so their instructions
loaded only when the user typed them. As skills their descriptions sit in
context and match on relevance — "why is our Databricks spend up?" now reaches
project-costs without anyone remembering the command exists. Typing the slash
name still works.

Each ships an example.md alongside the SKILL.md, walking a committed artifact
end to end: reports/sql-diagram/job_spend_plan.* for the plan-mode reading
(CTE sub-pipelines, LEFT joins that must stay LEFT, the range predicates that
stop a slowly-changing dimension fanning out), and reports/cost/2026-07-22.md
for the cost analysis (per-active-day normalisation, reconciling the
attributed total, treating SQL-warehouse silence as a finding). The examples
reference those artifacts rather than duplicating them, so there is one copy
to keep current.

.claude/commands/ is gone; the .gitignore block is restructured to un-ignore
the three repo skills by name, with the no-wildcard rule stated inline —
a wildcard there would commit the AI Dev Kit's user-level skills.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
reports/ is generated output — coverage, spend reports carrying account cost
figures, query diagrams — and none of it should be in git. The three
directory-level rules are replaced by a single `reports/`.

Four artifacts were tracked there, force-added as worked examples for the
project-costs and sql-diagram skills. .gitignore only governs untracked files,
so ignoring the directory would have left them in the index and made the rule
a lie; they are moved to .claude/skills/<skill>/examples/ instead, which is a
committed path. The examples and the two README links keep working, and
reports/ becomes purely the place the tools write.

The "git add -f one to keep it as an example" advice is removed from both the
gitignore comment and the sql-diagram skill, and replaced with the rule that a
new example is a copy into the skill's examples/ directory. Also drops the now
redundant reports/coverage/ entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
workflow.md said the schema-drift guard had a single exception (ops._health).
There are two: raw.order_quarantine also writes with overwriteSchema=true,
added in #52 and already documented in CLAUDE.md — the spec was not updated in
the same commit, which is what its own "keep docs in sync" section exists to
prevent. Also corrects the Co-Authored-By trailer, which named Opus 4.8.

require-changelog-entry.sh printed guidance the spec had superseded: "at most
3 sentences" (dropped at #49 because it constrained nothing) and a header
template built from the branch name. Both now match specs/workflow.md — a
~1000-character single paragraph and the PR-URL header — and the message links
to the section so the two cannot drift silently again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
EOF --subject 'Commit the agent tooling: workflow hooks, three project skills, and a fully ignored reports/' --body-file /tmp/pr-body-c1_otrlp.md
The plan diagram is authoritative on scans, joins and join predicates and
silent on windows, CTE-level filters and projection expressions — which is
where the defects that produce wrong numbers live. The skill now traces the
query through a handful of hand-built rows after the chart and ships both as
one self-contained HTML page.

Two rules the trace depends on: never hand-trace (rewrite each source table as
a literal VALUES CTE, run it, paste the real result — NULL propagation,
COUNT(DISTINCT) and window ordering are all easy to get wrong on paper), and
embed the rendered .svg as a data URI rather than re-rendering the .mmd, which
also keeps the SVG's own generic class names out of the page cascade.

examples/job_spend_plan.html is the worked instance: five usage rows through
the repo's own per-job spend query, showing a date-scoped price join picking
one price per row — with the verified counterfactual that dropping the range
predicates doubles quantity and inflates spend from $10.00 to $19.50 — a LEFT
join keeping an unpriced SKU alive, and a filter that discards unattributable
usage, which is why the attributed total never equals the Databricks total.

example.md is deleted. It asserted in prose what the page now demonstrates
with data; its unique content (the regenerate step, the CTE two-node shape)
moved into SKILL.md. project-costs keeps its example.md, because a page of
cost tables cannot explain why its analysis is written the way it is — the
rule is now stated in specs/tooling.md: add a commentary file only when the
artifact cannot speak for itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant