Skip to content

Add project skills for build, duckdb, maintenance, and release - #2853

Merged
erikdarlingdata merged 2 commits into
devfrom
chore/share-project-skills
Sep 3, 2026
Merged

Add project skills for build, duckdb, maintenance, and release#2853
erikdarlingdata merged 2 commits into
devfrom
chore/share-project-skills

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

What

Moves four skills out of the personal ~/.claude/skills directory into .claude/skills so they travel with the repo. Personal skills are machine-local, and cloud sessions do not read them at all, so a skill living only in ~/.claude/skills is unavailable to every session outside the one machine it was written on.

.gitignore goes from .claude/ to .claude/* plus !.claude/skills/, which exposes skills and nothing else. settings.local.json, commands/, and worktrees/ stay ignored.

Skill Purpose
release-checklist Pre-release checklist
build Build a component, report where the exe landed
duckdb Read-only query against Lite's DuckDB store
maintenance Quarterly dependency, build, and hygiene pass

Credentials removed

release-checklist contained the lab sa password and a reused Azure/AWS admin password in plaintext. This repo is public, so both are gone:

  • Cloud instance creation now takes "$SQL_TEST_PASSWORD", a throwaway generated per run.
  • The local SQL instance inventory, and the rule that sql2022 and sql2025 hold real monitoring data, moved to the untracked local CLAUDE.md. Those VMs exist on a single machine, so the committed procedure stays machine-neutral.

Portability

  • %LOCALAPPDATA% replaces absolute C:\Users\... paths. duckdb resolves the store through os.environ['LOCALAPPDATA'].
  • build uses repo-relative paths instead of C:\GitHub\PerformanceMonitor\.
  • Region guidance reads "close to the machine running the collector" instead of being hardcoded to US East for one developer's timezone.
  • maintenance/skill.md renamed to SKILL.md. It resolved on Windows but would not have on the case-sensitive filesystem a cloud session runs on.

Drive-by fix

build was stale. It pointed at Dashboard/Dashboard.csproj, which has been bin/obj leftovers since v3.3.0 moved Dashboard and Installer to deprecated/, and it did not know Darling exists. The argument table is rebuilt from git ls-files "*.csproj" with correct paths and target frameworks, now covering the Darling service and Viewer, with the deprecated projects labeled.

Test plan

  • git check-ignore confirms .claude/skills is tracked while settings.local.json, commands/, and worktrees/ stay ignored
  • Credential scan clean across every committed skill
  • No absolute paths or single-machine assumptions remain
  • Frontmatter name parses on every SKILL.md
  • Clone on a second machine and confirm the four skills list in /skills

Docs and config only. No product code changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EbYty5EYQwd4YGTDcJfEkE

Move four skills out of the personal ~/.claude/skills directory into
.claude/skills so they travel with the repo to other machines and to
cloud sessions, which do not read the local personal skills directory.

.gitignore now un-ignores .claude/skills only. settings.local.json,
commands/, and worktrees/ stay ignored.

Machine-specific content was stripped rather than committed:

- release-checklist no longer contains any credentials. Cloud test
  instances take a per-run throwaway password via $SQL_TEST_PASSWORD.
  The local SQL instance inventory, and the rule that sql2022 and
  sql2025 hold real data, moved to the untracked local CLAUDE.md.
- Region guidance is now "close to the machine running the collector"
  rather than hardcoded to US East for one developer's timezone.
- Absolute C:\Users and C:\GitHub paths are gone. duckdb resolves the
  store through %LOCALAPPDATA%, build uses repo-relative paths.
- maintenance was named skill.md; renamed to SKILL.md so it resolves on
  case-sensitive filesystems.

build was also stale. It pointed at Dashboard/Dashboard.csproj, which has
been bin/obj leftovers since the v3.3.0 move to deprecated/. The argument
table is rebuilt from git ls-files with correct paths and target
frameworks, and now covers the Darling service and Viewer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbYty5EYQwd4YGTDcJfEkE
4. Firewall churn: DELETE the allow rule, wait 3–5 minutes, re-add it. Collection must resume on its own without restarting the service. (CAVEAT, verified v3.2.0: a bare rule-deletion often does NOT sever an actively-collecting client — connection pooling keeps the open connection alive and Azure gates only NEW connections — so treat a no-outage result as inconclusive rather than a pass; the recovery logic's authoritative validation is the unit suites.)
5. Clean up: `az group delete --name rg-release-test --yes --no-wait`

**AWS RDS:**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Portability drift: the PR description says region guidance was generalized to "close to the machine running the collector" instead of being hardcoded for one developer's timezone, and the Azure section above (line ~78) was updated that way ("Use a region geographically close to the machine running the collector ... From US East that is eastus or eastus2"). This AWS RDS section wasn't updated the same way — it still hardcodes us-east-1 with reasoning specific to a US-East-based operator ("cross-country latency to us-west-2"). Someone running this checklist from a different region will get steered to the wrong AWS region, same class of bug the PR set out to fix for Azure.

@claude

claude Bot commented Sep 3, 2026

Copy link
Copy Markdown

Review

This PR is docs/config-only (four SKILL.md files moved into .claude/skills/ plus a .gitignore tweak) — no product code, T-SQL, or C# changes, so the T-SQL style rules and Lite/Darling code-parity checks in CONTRIBUTING.md don't apply here. Reviewed against the PR's own stated goals: credential removal, portability, and correct .gitignore scoping.

Verified clean:

  • No plaintext credentials in any of the four skills — SQL_TEST_PASSWORD is consistently read from the environment, never hardcoded.
  • No leftover absolute C:\Users\... paths; duckdb and build now use %LOCALAPPDATA%/repo-relative paths as claimed.
  • .gitignore's .claude/* + !.claude/skills/ is the correct idiom to un-ignore one subdirectory while leaving settings.local.json, commands/, and worktrees/ ignored (negating a wildcard-excluded directory re-enables recursion into it, unlike negating a file under an excluded dir).
  • build's project-path table matches the real .csproj layout (Lite/, Darling/PerformanceMonitor.Darling.Service/, Darling/PerformanceMonitor.Darling.Viewer/, deprecated/Dashboard, deprecated/Installer*).
  • release-checklist's claim that check-version-bump.yml only reads deprecated/Dashboard/Dashboard.csproj checks out against the actual workflow.

One finding posted inline: the AWS RDS section of release-checklist/SKILL.md still hardcodes us-east-1 with US-East-specific latency reasoning, while the Azure section right above it was generalized to "close to the machine running the collector" per this PR's stated portability fix. Same class of single-developer-timezone assumption the PR set out to remove, just missed in the AWS half.

The Azure block was changed to "close to the machine running the
collector" but the AWS RDS block kept "Use us-east-1, cross-country
latency to us-west-2", which is the same single-developer-timezone
assumption this branch set out to remove. Both halves now read the same
way and keep their concrete US East example region.

Also notes that the AWS block uses the same $SQL_TEST_PASSWORD throwaway
as the Azure block, since the two can be run independently.

Caught in review on #2853.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EbYty5EYQwd4YGTDcJfEkE
@erikdarlingdata

Copy link
Copy Markdown
Owner Author

Good catch on the AWS half. Fixed in the follow-up commit: the RDS block now reads "close to the machine running the collector" exactly like the Azure block above it, keeping us-east-1 as the concrete US East example. Also flagged that the AWS block uses the same SQL_TEST_PASSWORD throwaway, since the two blocks can be run independently.


## A. Dependencies & Security

> **Scope — scan every project, not just the solution.** A repo's `.sln` may not list every project. PerformanceStudio's `PlanViewer.sln` omits `server/PlanShare.csproj` and the SSMS VSIX (`PlanViewer.Ssms`, `PlanViewer.Ssms.Installer`), so the `dotnet list <Solution>.sln …` scans and the solution build all silently skip them. Run the checks against those projects too. The net472 VSIX is old-style, so `dotnet list` is unreliable on it — read its `<PackageReference>`s by hand (its `Microsoft.VSSDK.BuildTools` is intentionally held on the 17.x line; 18.x is un-restorable from nuget.org and targets VS 18, not VS 2022). Where the `.sln` covers all projects, the solution is enough.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "Scope" callout (and several others below — line 24's .github/workflows/release.yml for PerformanceStudio, line 26's lock-file comparison, the cross-platform publish step) hardcodes facts about PerformanceStudio, a separate/sibling repo that doesn't exist anywhere in this codebase. PlanViewer.sln, server/PlanShare.csproj, and the PlanViewer.Ssms* VSIX projects aren't in this repo — I checked git ls-files "*.csproj" and there's no PlanViewer.sln at all (this repo's solution is PerformanceMonitor.sln, and "PlanViewer" here only refers to the plan-viewer feature inside Lite/Darling/deprecated Dashboard, e.g. Lite/Windows/PlanViewerWindow.xaml).

This looks like a personal skill written to cover two of the author's repos at once, moved into .claude/skills here as-is. The PR's stated goal is removing single-machine/single-developer assumptions so skills work for anyone who clones this repo — but a skill that spends a third of its "Dependencies & Security" section on another private repo's solution layout is exactly that kind of leftover context, just not the flavor (paths/credentials) the cleanup targeted. Worth stripping the PerformanceStudio-specific detail down to a one-line pointer ("apply the same process to sibling repos you maintain") rather than embedding another codebase's file layout into this one.

2. **Vulnerable packages (security).** `dotnet list <Solution>.sln package --vulnerable --include-transitive`
- Must be **zero**. Any hit (incl. transitive) is urgent — bump or pin to a fixed version. This catches CVEs the `--outdated` check does not.
- **Code-level pass, not just packages:** run the `security-review` skill/agent on the diff since the last maintenance pass. These apps have real attack surface beyond their dependencies — PerformanceStudio's MCP server opens a local network listener, both store DB credentials (Windows Credential Manager), and both parse untrusted input (e.g. execution-plan XML). Triage anything it flags.
- **Calibrate severity to the deployment.** PerformanceStudio runs on a single-user personal laptop, and its MCP tools are strictly read-only (no arbitrary SQL, no writes/config changes). So loopback-bound / opt-in / local-IPC findings — the MCP listener, the named-pipe single-instance server — are **Low/informational here, not High**: there's no other local user or attacker to exploit them, and read-only tools can at most leak data they already return. Reserve High for *remotely reachable* vectors (e.g. a missing `Host`/`Origin` check that allows DNS rebinding) or credential disclosure. This calibration would change only if Studio shipped the MCP server enabled-by-default or ran on a shared/multi-user host. Don't re-raise the same local-IPC findings at High each pass.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This severity calibration is written for PerformanceStudio's threat model only ("single-user personal laptop," "MCP tools are strictly read-only"), but the paragraph above it (line 30) frames the finding-triage instruction as applying to both apps ("These apps have real attack surface... both store DB credentials... both parse untrusted input"). That's a real mismatch for this repo:

  • Darling's MCP surface is explicitly not read-only-only — README.md calls out "write-capable tools (Darling's view authoring, alert tuning, and server onboarding) change the monitor's own configuration."
  • Darling is explicitly not a single-user personal-laptop deployment — README.md describes it as "the always-on edition for teams," a headless service with an opt-in network web dashboard (--enable-web, port 5153) and MCP endpoint (--enable-mcp, port 5152) serving a fleet of monitored servers, viewable from "any seat."

If someone runs /maintenance against this repo and pattern-matches the reasoning here ("no other local user or attacker... reserve High for remotely reachable vectors") onto Darling's --enable-mcp/--enable-web surfaces or its write-capable MCP tools, they'd downgrade findings that don't actually fit the "no other user, read-only" justification. Worth adding a PerformanceMonitor-specific calibration line (or explicitly noting Darling's write-capable tools and multi-seat/team deployment as the higher-severity case) rather than leaving this repo to fall through on PerformanceStudio's reasoning by default.

@claude

claude Bot commented Sep 3, 2026

Copy link
Copy Markdown

Reviewed. This is a docs/config-only PR (four .claude/skills/*/SKILL.md files + .gitignore) — no T-SQL, no product code, so the usual style/parity/DMV-folklore checks don't apply here. Verified the PR's specific claims against the actual repo:

  • .gitignore un-ignore pattern is correct. .claude/* + !.claude/skills/ follows git's documented approach for re-including a directory (negate the directory entry itself, not files inside it) — this avoids the classic "can't re-include a file whose parent dir is excluded" gotcha. settings.local.json, commands/, worktrees/ stay ignored as claimed.
  • No leftover credentials or absolute paths in any of the four files — confirmed by reading each in full.
  • All file paths referenced check out against git ls-files "*.csproj" (build, release-checklist) and against actual source (duckdb's %LOCALAPPDATA%\PerformanceMonitorLite-Data / #1832 claim matches Lite/Services/DataRootMigration.cs; the check-version-bump workflow claim matches .github/workflows/check-version-bump.yml).
  • One real issue, flagged inline on maintenance/SKILL.md: it carries a substantial amount of content specific to a sibling repo ("PerformanceStudio") that doesn't exist in this codebase — PlanViewer.sln, server/PlanShare.csproj, an SSMS VSIX, none of which are here (this repo's solution is PerformanceMonitor.sln). More importantly, the security-severity calibration guidance ("single-user personal laptop," "MCP tools are strictly read-only") is written for PerformanceStudio's threat model only, while the paragraph above it frames the triage instruction as applying to both apps. Darling's actual MCP/web-dashboard surface doesn't fit that calibration — it has write-capable MCP tools and is explicitly a team/fleet deployment (README.md), not a single-user local app — so an agent following this skill's reasoning on this repo could downgrade findings that don't actually meet the "no other user, read-only" justification.

Given the PR's own stated goal is stripping single-machine/single-developer assumptions so skills work for any clone, this is worth cleaning up before merge, but it's not a blocker for the mechanical parts of the migration (gitignore change, credential removal, path fixes), which all check out.

@erikdarlingdata
erikdarlingdata merged commit 6d44812 into dev Sep 3, 2026
6 checks passed
@erikdarlingdata
erikdarlingdata deleted the chore/share-project-skills branch September 3, 2026 17:33
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