Skip to content

feat: add TypeScript directive observability tooling - #16

Merged
pertrai1 merged 3 commits into
mainfrom
feat/directive-observability-ts
May 9, 2026
Merged

pertrai1 merged 3 commits into
mainfrom
feat/directive-observability-ts

Conversation

@pertrai1-bot

@pertrai1-bot pertrai1-bot commented May 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • replace the eval health report generator with TypeScript/Node tooling and add npm scripts
  • add a TypeScript scenario runner that writes deterministic loaded-file manifests with SHA-256 hashes
  • add directive/skill wiring validation and a directive-load-logging eval scenario
  • clarify routing evidence as model self-report versus authoritative harness logs

Verification

  • npm run check
  • npm run eval:scenario -- --print-only directive-load-logging smoke-tested manifest creation
  • npm run eval:report
  • bash -n evals/run-scenario.sh
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Added npm-based evaluation tooling and scripts to assemble scenarios, validate directives, run evaluations, and generate HTML reports.
  • Documentation

    • Updated eval and agent guidance to document the npm workflow, manifest-based evidence, and tooling.
    • Added routing guidance and a new "directive load logging" evaluation scenario.
  • Chores

    • Replaced legacy Python report generator with a TypeScript implementation.
    • Simplified shell wrapper and added ignore rule for node_modules.

@coderabbitai

coderabbitai Bot commented May 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@pertrai1 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 43 minutes and 57 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cd31e155-4035-4e61-8f27-e37f270fa432

📥 Commits

Reviewing files that changed from the base of the PR and between a43fac5 and 6b81329.

📒 Files selected for processing (3)
  • evals/report-results.ts
  • scripts/eval-scenario.ts
  • scripts/validate-directives.ts
📝 Walkthrough

Walkthrough

This PR migrates the agent-directives evaluation framework from Bash and Python to TypeScript npm scripts. It adds project configuration (tsconfig.json, package.json), introduces new directive validation and scenario execution tools (scripts/validate-directives.ts, scripts/eval-scenario.ts), replaces Python report generation with TypeScript (evals/report-results.ts), and updates all supporting documentation to reflect npm-based workflows.

Changes

TypeScript Eval Tooling Migration

Layer / File(s) Summary
Project Configuration
tsconfig.json, package.json, .gitignore
TypeScript ES2022 targeting with NodeNext modules, ESM package config, npm scripts for check/typecheck/validate/eval, and node_modules exclusion.
Directive Guidance & Scenario Definitions
directives/adaptive-routing.md, evals/scenarios/directive-load-logging.md
Adaptive-routing directive clarifies evidence hierarchy: harness/runtime logs are authoritative for loaded directive files; agent self-disclosure serves as reviewer-facing evidence. New directive-load-logging scenario specifies setup (load AGENTS.md + directive), prompt (workflow routing question), expected behaviors (list directive files used), anti-behaviors (no overclaiming internal attention or default loading), and quality criteria.
Directive Validation Tooling
scripts/validate-directives.ts
Validates directive/skill frontmatter (required name and description keys), verifies referenced paths exist, ensures scenario section headings are present and non-empty, requires Setup to reference loadable files, checks adaptive-routing mentions all discovered skills, and exits with error status if validation fails.
Evaluation Scenario Execution
scripts/eval-scenario.ts
CLI script that loads scenario markdown, extracts referenced directive/skill files, computes sha256 hashes and byte counts, assembles CLAUDE.md workspace with load markers, writes deterministic manifest.json with metadata and file tracking, optionally prints preview via --print-only, and spawns claude with exit status recording.
Evaluation Report Generation
evals/report-results.ts (replaces evals/report-results.py)
TypeScript script that collects runs from markdown/JSON results and harness manifests, extracts verdicts/counts from multiple field aliases, synthesizes routing traces (expected/provided/claimed files and deltas), computes per-target pass rates and health metrics, detects stale runs via commit mismatch, renders HTML report with escaped content and tabular summaries, and logs routing precision/recall to stdout.
Shell Wrapper Integration
evals/run-scenario.sh
Converted from standalone Bash workflow into thin wrapper that derives REPO_ROOT, invokes scripts/eval-scenario.ts via local tsx or npx --yes tsx, and forwards all CLI arguments unchanged.
Documentation Updates
AGENTS.md, README.md, evals/README.md, evals/results/README.md
Updated command guidance to use npm scripts (npm run check, npm run eval:scenario, npm run eval:report) instead of bash/python invocations. Documented manifest format, assembled-prompt output, routing_trace schema, and evidence semantics (harness logs authoritative vs. agent self-report). Removed references to python3 evals/report-results.py and inline validation helpers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • pertrai1/agent-directives#14: Introduced Python-based evals/report-results.py for static HTML health dashboard; this PR replaces it with TypeScript implementation.
  • pertrai1/agent-directives#5: Modified directives/adaptive-routing.md and routing-related validation; this PR extends routing directive with evidence-separation semantics.
  • pertrai1/agent-directives#7: Altered AGENTS.md and eval scenario "print-only" flow; this PR refactors run-scenario logic into scripts/eval-scenario.ts while preserving CLI behavior.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: add TypeScript directive observability tooling' directly and accurately summarizes the main change: migrating tooling to TypeScript/Node and adding observability capabilities via manifests and validation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/directive-observability-ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
AGENTS.md (1)

9-9: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

"No package manager" claim is stale after adding npm tooling.

Line 9 states "there is no package manager, build artifact, or runtime application" but the PR introduces package.json and requires npm install. Suggest updating to acknowledge that npm is used for developer scripts only, e.g.:

-- Content-first Markdown repository; there is no package manager, build artifact, or runtime application.
+- Content-first Markdown repository; the directives and templates work without any build step. npm is used only for developer tooling scripts (type-checking, validation, eval reporting) — not for runtime or distribution.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AGENTS.md` at line 9, Update the sentence claiming there is "no package
manager, build artifact, or runtime application" to acknowledge that npm tooling
has been added for developer scripts; edit the text in AGENTS.md so it states
that npm (package.json) is present only for developer scripts and local tooling
(no runtime or build artifact), e.g., replace or append to the existing line to
clearly indicate npm is used for developer-only tasks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package.json`:
- Line 14: Update the dev dependency version for the TypeScript Node typings:
replace the "@types/node": "^20.12.12" entry with a supported LTS range (e.g.
"@types/node": "^24" or "@types/node": "^22") so the project targets a non-EOL
Node release; edit the package.json dependency line for "@types/node"
accordingly and run your package manager to refresh lockfile/install.

In `@scripts/eval-scenario.ts`:
- Around line 144-148: The code currently calls spawnSync('claude', ...) and
only records result.status, which will be null when the binary or cwd is missing
and result.error is never inspected; update the block around spawnSync to check
result.error first (inspect result.error.code, e.g., 'ENOENT') and when present
write a clear diagnostic to stderr (console.error) and record a non-null exit
indicator in the manifest (set manifest.exit_status to a distinct value like 127
or include manifest.error_message with result.error.message) before writing
manifestPath via writeFileSync and calling process.exit with a concrete status;
reference the existing variables/result object (spawnSync call, result,
manifest, manifestPath, writeFileSync, process.exit) to locate and implement
this check and logging.

In `@scripts/validate-directives.ts`:
- Around line 78-80: The current build of the skills list unconditionally
appends "SKILL.md" for every subdirectory (variable skills) so
validateFrontmatter (which calls read()/readFileSync) can throw and crash when a
SKILL.md is missing; update the code that constructs skills to check for the
existence of the SKILL.md file (e.g., fs.existsSync or stat) before including
the path, and if missing call the validator's fail() with a structured error
mentioning the directory name and missing SKILL.md (not letting
read()/readFileSync throw). Locate references to skills, validateFrontmatter,
read()/readFileSync and fail() to implement this change.

---

Outside diff comments:
In `@AGENTS.md`:
- Line 9: Update the sentence claiming there is "no package manager, build
artifact, or runtime application" to acknowledge that npm tooling has been added
for developer scripts; edit the text in AGENTS.md so it states that npm
(package.json) is present only for developer scripts and local tooling (no
runtime or build artifact), e.g., replace or append to the existing line to
clearly indicate npm is used for developer-only tasks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c604e04-7b87-468c-bfe1-4dd206d93621

📥 Commits

Reviewing files that changed from the base of the PR and between a03943b and 976d0c9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • .gitignore
  • AGENTS.md
  • README.md
  • directives/adaptive-routing.md
  • evals/README.md
  • evals/report-results.py
  • evals/report-results.ts
  • evals/results/README.md
  • evals/run-scenario.sh
  • evals/scenarios/directive-load-logging.md
  • package.json
  • scripts/eval-scenario.ts
  • scripts/validate-directives.ts
  • tsconfig.json
💤 Files with no reviewable changes (1)
  • evals/report-results.py

Comment thread package.json Outdated
Comment thread scripts/eval-scenario.ts
Comment thread scripts/validate-directives.ts Outdated
@pertrai1-bot

Copy link
Copy Markdown
Collaborator Author

Addressed the valid review comments in a43fac5:

  • Updated @types/node from ^20.12.12 to ^24.0.0 and refreshed package-lock.json.
  • Added spawnSync error handling in scripts/eval-scenario.ts so a missing claude binary emits a diagnostic, writes exit_status: 127, records error_message, and exits with a concrete status.
  • Updated scripts/validate-directives.ts so skill directories missing SKILL.md are collected as structured validation errors instead of crashing via readFileSync.

Verification:

  • npm run check
  • git diff --check
  • Regression check for missing SKILL.md validation error
  • Regression check for missing claude launch path and manifest exit_status=127

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/eval-scenario.ts`:
- Around line 47-48: The code uses the variable scenario to build filesystem
paths (e.g., scenarioFile) without validation allowing path traversal; before
constructing paths or directory names (and at other uses around the other
occurrences), validate and sanitize scenario: ensure it's non-empty and matches
a safe whitelist (e.g., /^[A-Za-z0-9-_]+$/) or replace it with
path.basename(scenario) to strip any directory components, then reject or error
on invalid input; apply the same validation/sanitization wherever scenario is
used to build paths (including the other mentioned occurrences).
- Line 99: Protect the spawnSync('git', ['rev-parse', '--short', 'HEAD'], { cwd:
repoRoot, encoding: 'utf8' }) call used to set commit by checking the returned
result object before accessing stdout.trim(); if the result has an error, a
non-zero status, or stdout is falsy, use a safe fallback (e.g. 'unknown' or ''),
optionally log the git error/result for diagnostics, and ensure the rest of the
script continues to write the manifest and run diagnostics using that fallback
value instead of throwing in the commit assignment.
- Line 8: Replace the URL.pathname string manipulation used to compute repoRoot
with Node's fileURLToPath conversion to correctly decode percent-encoded
characters and handle platform-specific paths: import fileURLToPath from 'url'
and compute repoRoot by passing new URL('..', import.meta.url) into
fileURLToPath instead of using .pathname; make identical changes where the same
pattern occurs in the other files (the occurrences referenced in this review:
scripts/validate-directives.ts and evals/report-results.ts) so all repo-root
path calculations use fileURLToPath.

In `@scripts/validate-directives.ts`:
- Around line 97-100: The code calls read('directives/adaptive-routing.md')
without guarding for a missing file which can throw; wrap the read call in a
safe check (e.g., try/catch or pre-check with fs.existsSync) and if the file is
missing set adaptive to an empty string or emit a structured warning via
warn(...) so validation continues; update the block around the read(...)
assignment for the variable adaptive and keep the subsequent loop for (const
skill of skills) unchanged so it will report missing mentions rather than
crashing.
- Line 5: The repoRoot calculation uses URL.pathname which is platform-brittle;
replace it with Node's fileURLToPath to get a canonical filesystem path. Import
fileURLToPath from 'url' and change the expression that defines repoRoot
(currently using new URL('..', import.meta.url).pathname.replace(/\/$/, '')) to
use fileURLToPath(new URL('..', import.meta.url)) and remove the manual
trailing-slash regex logic so repoRoot is normalized across OSes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b829bad-9482-4419-a514-2906ae4eff43

📥 Commits

Reviewing files that changed from the base of the PR and between 976d0c9 and a43fac5.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • package.json
  • scripts/eval-scenario.ts
  • scripts/validate-directives.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

Comment thread scripts/eval-scenario.ts Outdated
Comment thread scripts/eval-scenario.ts
Comment thread scripts/eval-scenario.ts Outdated
Comment thread scripts/validate-directives.ts Outdated
Comment thread scripts/validate-directives.ts Outdated
@pertrai1-bot

Copy link
Copy Markdown
Collaborator Author

Addressed the valid comments posted after a43fac5 in 6b81329:

  • Replaced brittle new URL(...).pathname repo-root handling with fileURLToPath(...) in scripts/eval-scenario.ts, scripts/validate-directives.ts, and evals/report-results.ts.
  • Added scenario-name validation before using the scenario in filesystem paths/run-directory names.
  • Hardened the git commit lookup in scripts/eval-scenario.ts so git lookup failures fall back to commit: "unknown" and continue writing the manifest.
  • Guarded the adaptive-routing read in scripts/validate-directives.ts so a missing required directive is reported as a structured validation error instead of an uncaught read crash.

Verification:

  • npm run check
  • npm run eval:report
  • git diff --check
  • Regression: invalid scenario ../escape exits 2 before path use
  • Regression: hidden git produces manifest commit=unknown
  • Regression: temporarily missing directives/adaptive-routing.md reports a structured validation error

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.

2 participants