.agents/skills/auditor/SKILL.md
Continuous background audit loop. Runs incremental audits every 10 minutes (when git changes are detected) and a comprehensive full audit every hour. Emits a heartbeat to a shared state file so the development-orchestrator can detect and restart a dead auditor.
npx skillsauth add em-jones/staccato-toolkit auditorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Run a continuous background audit loop. The loop has two cadences:
Emit a heartbeat on every iteration so the development-orchestrator can detect a dead auditor and restart it.
The auditor writes a heartbeat file on every successful iteration. The development-orchestrator reads this file to determine whether the auditor is alive.
.opencode/auditor/heartbeat.json
{
"pid": <process-id>,
"session": "<session-id>",
"iteration": <integer>,
"cadence": "incremental" | "comprehensive",
"last_run_utc": "<ISO-8601-timestamp>",
"next_run_utc": "<ISO-8601-timestamp>",
"status": "alive" | "completing",
"last_audit_summary": {
"critical": <n>,
"warning": <n>,
"info": <n>,
"changes_detected": ["<file>", ...]
}
}
After every audit iteration (incremental or comprehensive), write the heartbeat:
mkdir -p .opencode/auditor
cat > .opencode/auditor/heartbeat.json <<EOF
{
"pid": $$,
"session": "<td-session-id>",
"iteration": <n>,
"cadence": "<cadence>",
"last_run_utc": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"next_run_utc": "<computed>",
"status": "alive",
"last_audit_summary": {
"critical": <n>,
"warning": <n>,
"info": <n>,
"changes_detected": [<list>]
}
}
EOF
The heartbeat file is gitignored (.opencode/auditor/ is in .gitignore) — do NOT commit it.
On launch, immediately:
Get or create the current td session:
td usage 2>&1 | head -5
Write an initial heartbeat with status: "alive" and iteration: 0.
Record the current git commit as the baseline for incremental diffing:
git rev-parse HEAD > .opencode/auditor/last-seen-commit
Announce startup:
[auditor] started — session <id>, pid <pid>
[auditor] incremental: every 10 min | comprehensive: every 1 hr
[auditor] heartbeat: .opencode/auditor/heartbeat.json
Enter the main loop (see below).
loop forever:
sleep 10 minutes
if (elapsed since last comprehensive) >= 60 minutes:
run comprehensive audit
reset comprehensive timer
reset incremental timer
else:
detect git changes since last-seen-commit
if changes detected:
run incremental audit for affected domains
else:
log "no changes detected — skipping incremental"
write heartbeat
update last-seen-commit to HEAD
Use a 10-minute sleep between iterations. Because agents don't have native sleep, simulate with
repeated date comparisons anchored to wall-clock start time:
LOOP_START=$(date -u +%s)
TARGET=$((LOOP_START + 600)) # 600 seconds = 10 minutes
while [ $(date -u +%s) -lt $TARGET ]; do
sleep 30
done
Use the same pattern scaled to 3600 seconds (1 hour) for the comprehensive cadence timer.
LAST=$(cat .opencode/auditor/last-seen-commit 2>/dev/null || echo "")
CURRENT=$(git rev-parse HEAD)
if [ "$LAST" = "$CURRENT" ]; then
echo "no changes"
else
git diff --name-only "$LAST" "$CURRENT" 2>/dev/null || git diff --name-only HEAD~1 HEAD
fi
Store results in a variable CHANGED_FILES.
| Changed path pattern | Affected audit domains |
|---|---|
| src/**/*.go, */go.mod, go.work | go-libraries, go-patterns, observability |
| src/**/*.ts, src/**/*.tsx, */package.json | node-libraries, typescript-patterns |
| .github/workflows/** | ci-cd, github-actions |
| src/**/Dockerfile*, src/**/Containerfile* | container-images, base-images |
| .entities/** | catalog |
| .opencode/rules/** | usage-rules |
| openspec/specs/**, openspec/changes/** | spec-coverage |
| devbox.json | devbox-tools, catalog |
| **/*.yaml, **/*.yml (excluding .github/) | infrastructure |
A single changed file may map to multiple domains. Collect the union of all domains from all changed files — that is the incremental audit scope for this iteration.
Run only the sub-audits relevant to the affected domains. For each domain in the scope:
go-librariesCheck all direct Go imports in changed .go files against the OpenSpec change registry:
# Extract imports from changed Go files
for f in $CHANGED_GO_FILES; do
grep -E '"github\.com/[^"]+"' "$f" 2>/dev/null
done | sort -u
For each import, verify it appears in at least one design.md Technology Adoption table or has a
usage rule at .opencode/rules/technologies/.
go-patternsScan changed Go files for pattern violations:
# Check for patterns that need usage rules
grep -E '(slog\.|log\.With|zap\.|logrus\.)' $CHANGED_GO_FILES 2>/dev/null
grep -E '(otel\.|opentelemetry|tracer\.|meter\.)' $CHANGED_GO_FILES 2>/dev/null
Cross-reference against .opencode/rules/patterns/ to confirm coverage.
observabilityVerify any new OTel instrumentation in changed files follows the span-instrumentation and trace-context-propagation rules:
cat .opencode/rules/patterns/observability/span-instrumentation.md 2>/dev/null | head -5
Flag any instrumentation that doesn't match the rule structure.
node-libraries / typescript-patternsFor changed package.json files, extract new direct dependencies and check coverage.
ci-cd / github-actionsFor changed workflow files, verify they use only approved actions from the catalog:
cat .opencode/rules/patterns/actions/approved-actions-catalog.md 2>/dev/null
grep -rh "uses:" $CHANGED_WORKFLOW_FILES 2>/dev/null | sed 's/.*uses: //' | sort -u
container-imagesFor changed Dockerfiles/Containerfiles, verify base images comply with the base-images rule:
cat .opencode/rules/patterns/infrastructure/base-images.md 2>/dev/null | head -20
grep "^FROM" $CHANGED_CONTAINER_FILES 2>/dev/null
catalogFor changed .entities/*.yaml files, verify entity structure is valid (has required fields:
apiVersion, kind, metadata.name, spec.type).
usage-rulesFor changed .opencode/rules/** files, check they follow the rule template structure:
cat .opencode/rules/TEMPLATE.md 2>/dev/null | head -20
spec-coverageFor changed spec files, verify all requirements have corresponding td tasks:
# Check for requirements without task IDs in the spec
grep -E "^### Requirement:" $CHANGED_SPEC_FILES 2>/dev/null | grep -v "td-"
devbox-toolsFor changed devbox.json, extract newly added packages and check catalog and usage rule coverage.
infrastructureFor changed YAML/YML files outside .github/, check for:
apiVersion patternsRun the full technology-audit skill logic (Steps 2–5 from that skill), but in read-only mode —
do NOT create tasks or changes during the audit loop. Instead, write findings to the audit log file
and create a summary in the heartbeat.
mkdir -p .opencode/auditor
AUDIT_LOG=".opencode/auditor/audit-$(date -u +%Y%m%dT%H%M%SZ).log"
Run all domains:
Write to $AUDIT_LOG:
## Comprehensive Audit — <ISO-8601-timestamp>
### Critical Gaps 🔴
<list>
### Warning Gaps 🟡
<list>
### Info Gaps 🟢
<list>
### Fully Documented ✓
<list>
Also write a compact JSON summary to .opencode/auditor/latest-findings.json:
{
"timestamp": "<ISO-8601>",
"cadence": "comprehensive",
"critical": <n>,
"warning": <n>,
"info": <n>,
"gaps": [
{ "severity": "critical", "technology": "<name>", "category": "<cat>", "missing": ["change", "usage-rule"] },
...
]
}
Keep only the 10 most recent audit log files (prune older ones after writing):
ls -t .opencode/auditor/audit-*.log | tail -n +11 | xargs rm -f 2>/dev/null
For each affected domain that finds a gap, append to the current incremental log:
INCR_LOG=".opencode/auditor/incremental-$(date -u +%Y%m%dT%H%M%SZ).log"
Write findings in the same format as the comprehensive audit, scoped to the affected domains. Keep only the 20 most recent incremental log files.
These findings are urgent enough that the auditor should create td tasks immediately rather than
waiting for a human to review the audit log:
| Condition | Action |
|---|---|
| A Go file imports a module that has no OpenSpec change AND no usage rule | td create "Critical: undocumented dependency <import>" --type task |
| A workflow uses an unapproved GitHub Action | td create "Critical: unapproved action <action> in <file>" --type task |
| A container uses a base image NOT in the approved list | td create "Critical: non-compliant base image <image> in <file>" --type task |
| A spec requirement has no corresponding td task | td create "Gap: requirement without task in <spec>" --type task |
For all other gaps, log them and let humans triage via the audit log.
If the auditor receives a termination signal or is about to exit:
status: "completing".trap 'write_final_heartbeat; exit 0' SIGTERM SIGINT
.opencode/auditor/ which is in
.gitignore pathstd ls --status open | grep "<title fragment>"
Base directory for this skill: file:///home/em/repos/oss/openspec-td/.opencode/skills/auditor Relative paths in this skill (e.g., scripts/, reference/) are relative to this base directory.
tools
<!--VITE PLUS START--> # Using Vite+, the Unified Toolchain for the Web This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`. ## Vite+ Workflow `vp` is a global binary that handles the full development lifecycle. Run `vp help` to pr
development
Guide for building performant data tables. Uses tanstack-table for table logic (sorting, filtering, pagination) and tanstack-virtual for rendering large datasets efficiently.
development
Expert guidance for building observable, expressive, and fault-tolerant TypeScript applications using the effect-ts/effect ecosystem. Covers Effect<A, E, R> type, error management, dependency injection via Layers, observability (logging, metrics, tracing), concurrency with Fibers, retry/scheduling, Schema validation, Streams, and Sinks.
tools
Complete E2E (end-to-end) and integration testing skill for TypeScript/NestJS projects using Jest, real infrastructure via Docker, and GWT pattern. ALWAYS use this skill when user needs to: **SETUP** - Initialize or configure E2E testing infrastructure: - Set up E2E testing for a new project - Configure docker-compose for testing (Kafka, PostgreSQL, MongoDB, Redis) - Create jest-e2e.config.ts or E2E Jest configuration - Set up test helpers for database, Kafka, or Redis - Configure .env.e2e environment variables - Create test/e2e directory structure **WRITE** - Create or add E2E/integration tests: - Write, create, add, or generate e2e tests or integration tests - Test API endpoints, workflows, or complete features end-to-end - Test with real databases, message brokers, or external services - Test Kafka consumers/producers, event-driven workflows - Working on any file ending in .e2e-spec.ts or in test/e2e/ directory - Use GWT (Given-When-Then) pattern for tests **REVIEW** - Audit or evaluate E2E tests: - Review existing E2E tests for quality - Check test isolation and cleanup patterns - Audit GWT pattern compliance - Evaluate assertion quality and specificity - Check for anti-patterns (multiple WHEN actions, conditional assertions) **RUN** - Execute or analyze E2E test results: - Run E2E tests - Start/stop Docker infrastructure for testing - Analyze E2E test results - Verify Docker services are healthy - Interpret test output and failures **DEBUG** - Fix failing or flaky E2E tests: - Fix failing E2E tests - Debug flaky tests or test isolation issues - Troubleshoot connection errors (database, Kafka, Redis) - Fix timeout issues or async operation failures - Diagnose race conditions or state leakage - Debug Kafka message consumption issues **OPTIMIZE** - Improve E2E test performance: - Speed up slow E2E tests - Optimize Docker infrastructure startup - Replace fixed waits with smart polling - Reduce beforeEach cleanup time - Improve test parallelization where safe Keywords: e2e, end-to-end, integration test, e2e-spec.ts, test/e2e, Jest, supertest, NestJS, Kafka, Redpanda, PostgreSQL, MongoDB, Redis, docker-compose, GWT pattern, Given-When-Then, real infrastructure, test isolation, flaky test, MSW, nock, waitForMessages, fix e2e, debug e2e, run e2e, review e2e, optimize e2e, setup e2e