Skip to content

Add governance audit hook exemplar - #123

Merged
unbraind merged 2 commits into
mainfrom
feat/governance-audit-hooks-exemplar
Jun 6, 2026
Merged

unbraind merged 2 commits into
mainfrom
feat/governance-audit-hooks-exemplar

Conversation

@unbraind

@unbraind unbraind commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Summary

Implements pm-7m8p by making pm-governance-audit the first-party governance hook exemplar for package authors.

  • declares the hooks capability in governance-audit package metadata and manifest
  • registers default-inert onRead and onWrite hooks
  • adds opt-in compact JSONL sidecar logging via PM_GOVERNANCE_AUDIT_HOOK_LOG
  • documents the package-owned hook pattern in SDK, extensions, and package README docs
  • adds package-specific regression coverage so generic hook tests cannot mask missing package hooks
  • closes/releases pm-7m8p and regenerates package-owned CHANGELOG.md

Verification

  • node scripts/run-tests.mjs test -- tests/unit/builtin-extension-entrypoints.spec.ts tests/unit/package-manifest.spec.ts tests/unit/sdk-index.spec.ts -> 62 passed
  • pnpm build
  • isolated temp PM_PATH/PM_GLOBAL_PATH smoke: pm init --type-preset agile, pm install governance-audit --project, create/update/get with PM_GOVERNANCE_AUDIT_HOOK_LOG, verified compact read/write sidecar and no body/snapshot fields, pm package doctor --project --detail deep --trace --json
  • node scripts/run-tests.mjs coverage -> 146 files, 2517 tests, 100% statements/branches/functions/lines
  • pnpm changelog:pm:check
  • pm validate --check-resolution --check-history-drift -> history drift ok; pre-existing resolution warnings remain on older closed items only
  • pnpm audit --audit-level moderate -> clean
  • pm package doctor --project --detail deep --trace --json -> ok
  • GitHub open PRs/issues/dependabot/secret alerts -> zero before PR creation
  • Sentry/telemetry gate -> critical=0, high=0, telemetry finish error rate 1.83%, missing error-code rows=0
  • telemetry stack health -> API ok version 2026.6.6, queue depth 0, 11574 events in last 24h

Review Agents

@codex review
/gemini review
@gemini-code-assist

Implement pm-7m8p by making pm-governance-audit the first-party onRead/onWrite hook exemplar.

- declare hooks capability in governance-audit manifests and package metadata

- register default-inert opt-in compact JSONL sidecar logging via PM_GOVERNANCE_AUDIT_HOOK_LOG

- document the package-author hook pattern in SDK, extensions, and package docs

- add package-specific regression coverage and close/release the pm item

Verification: focused unit/package/SDK tests 62/62; pnpm build; isolated temp install smoke; package doctor; full coverage 2517 tests with 100% statements/branches/functions/lines; changelog check; audit/security/GitHub/Sentry/telemetry gates.

@sourcery-ai sourcery-ai 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.

Sorry @unbraind, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 6, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@unbraind, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 49 minutes and 28 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: a17c74c6-2db5-46a1-be87-c2396bfbbba9

📥 Commits

Reviewing files that changed from the base of the PR and between c177b2b and aabcb37.

📒 Files selected for processing (7)
  • .agents/pm/extensions/.managed-extensions.json
  • .agents/pm/history/pm-mzlu.jsonl
  • .agents/pm/tasks/pm-mzlu.toon
  • CHANGELOG.md
  • packages/pm-governance-audit/extensions/governance-audit/index.js
  • packages/pm-governance-audit/extensions/governance-audit/index.ts
  • tests/unit/builtin-extension-entrypoints.spec.ts
📝 Walkthrough

Walkthrough

This PR implements hooks support for the pm-governance-audit extension. The extension now registers onRead and onWrite hooks during activation and writes optional JSONL audit records to a path specified via PM_GOVERNANCE_AUDIT_HOOK_LOG. Manifest, package metadata, documentation, and unit tests are all updated accordingly.

Changes

Governance Audit Hooks Implementation

Layer / File(s) Summary
Hook Implementation in governance-audit Extension
packages/pm-governance-audit/extensions/governance-audit/index.ts, packages/pm-governance-audit/extensions/governance-audit/index.js, packages/pm-governance-audit/extensions/governance-audit/manifest.json, packages/pm-governance-audit/package.json, packages/pm-governance-audit/README.md
TypeScript and JavaScript implementations import filesystem utilities and register onRead/onWrite hooks during extension activation. A new appendHookAuditRecord helper conditionally appends JSON records to a sidecar file path resolved from PM_GOVERNANCE_AUDIT_HOOK_LOG. Manifest and package metadata declare the hooks capability.
Documentation and Changelog
docs/EXTENSIONS.md, docs/SDK.md, CHANGELOG.md
SDK and extensions documentation describe the governance-audit hooks feature, sidecar logging behavior, record structure, and environment variable configuration. A changelog entry marks the onRead/onWrite hooks exemplar as added.
Test Infrastructure and Hook Validation
tests/unit/builtin-extension-entrypoints.spec.ts
Test mock API extended with hooks object containing onRead and onWrite hook capture arrays. A new unit test activates the governance audit extension, registers and invokes hook handlers with project data, validates JSONL sidecar log creation and record structure, and ensures cleanup.
Feature Tracking and Metadata
.agents/pm/extensions/.managed-extensions.json, .agents/pm/features/pm-7m8p.toon, .agents/pm/history/pm-7m8p.jsonl
Agent-managed feature record and implementation history updated to reflect completed hooks implementation. Feature marked closed with resolution, expected/actual results, artifact enumeration, and validation evidence. Extension registry timestamp refreshed.

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 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
Title check ✅ Passed The title clearly and concisely describes the main change: implementing a governance audit hook exemplar for the pm-governance-audit package.
Description check ✅ Passed The description is directly related to the changeset, providing a comprehensive summary of the governance audit hook implementation, verification steps, and review agents.
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.


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.

@unbraind

unbraind commented Jun 6, 2026

Copy link
Copy Markdown
Owner Author

@codex review
/gemini review
@gemini-code-assist
@coderabbitai review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements the pm-governance-audit onRead/onWrite hook exemplar, adding the hooks capability to the package manifest and registering hooks that log compact JSONL read/write records to a sidecar path specified by PM_GOVERNANCE_AUDIT_HOOK_LOG. It also includes comprehensive documentation updates and unit tests to verify the new logging behavior. The feedback highlights a critical robustness and performance issue where synchronous I/O operations (mkdirSync and appendFileSync) are executed on every hook invocation without error handling. It is recommended to wrap these operations in a try-catch block to prevent CLI crashes and to cache successfully created directories to avoid redundant disk hits.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch PR info and changed files
gh pr view 123 --repo unbraind/pm-cli --json title,body,files,additions,deletions,commits 2>/dev/null | head -200

echo "---FILES---"
gh pr diff 123 --repo unbraind/pm-cli 2>/dev/null | head -2000

Length of output: 49618



@unbraind This is a clean, well-scoped implementation. The verification matrix is comprehensive and the TS/JS/manifest triple stays in sync. A few observations below.


🔴 Missing error handling in appendHookAuditRecord

packages/pm-governance-audit/extensions/governance-audit/index.ts (and index.js)

mkdirSync and appendFileSync are both synchronous and have no try/catch. A permission error, a read-only filesystem, or a bad user-supplied PM_GOVERNANCE_AUDIT_HOOK_LOG path will throw an uncaught exception directly into the hook dispatch chain, which may crash the CLI process mid-command. Since this is the recommended first-party exemplar for how packages should author hooks, the pattern should also demonstrate graceful degradation:

function appendHookAuditRecord(kind: "on_read" | "on_write", context: OnReadHookContext | OnWriteHookContext): void {
  const logPath = process.env[HOOK_LOG_ENV]?.trim();
  if (!logPath) {
    return;
  }
  try {
    const absoluteLogPath = path.resolve(logPath);
    mkdirSync(path.dirname(absoluteLogPath), { recursive: true });
    const writeContext = kind === "on_write" ? (context as OnWriteHookContext) : undefined;
    appendFileSync(
      absoluteLogPath,
      `${JSON.stringify({
        kind,
        path: context.path,
        scope: context.scope,
        op: writeContext?.op,
        item_id: writeContext?.item_id,
        item_type: writeContext?.item_type,
        changed_fields: writeContext?.changed_fields,
      })}\n`,
      "utf8",
    );
  } catch {
    // Sidecar logging is opt-in and best-effort; do not surface write failures to the caller.
  }
}

🟡 mkdirSync called on every hook invocation

mkdirSync with { recursive: true } is a no-op after the first call, but it still makes a syscall on every read/write event. For high-frequency workloads (e.g., bulk imports) this adds unnecessary overhead. A simple solution — memoize the set of already-created directories:

const createdDirs = new Set<string>();

function appendHookAuditRecord(...): void {
  ...
  const dir = path.dirname(absoluteLogPath);
  if (!createdDirs.has(dir)) {
    mkdirSync(dir, { recursive: true });
    createdDirs.add(dir);
  }
  ...
}

🟢 Minor: README path note

The README example uses a relative path:

PM_GOVERNANCE_AUDIT_HOOK_LOG=.pm-local/governance-hooks.jsonl pm update pm-demo --status closed

path.resolve() resolves this relative to process.cwd(). It would be helpful to mention that the path resolves from the working directory where pm is invoked, so users know where the sidecar will land when running from different directories.


✅ What looks good

  • TS / JS / manifest capabilities array is in sync across all three files.
  • The on_read JSONL record correctly omits undefined write fields due to JSON.stringify semantics — tested precisely.
  • Env-var save/restore in finally is correct and prevents test pollution.
  • Inert-by-default check (rejects.toMatchObject({ code: "ENOENT" })) is a solid regression guard.
  • Hook capability declared before api.hooks.* calls are made — avoids the extension_capability_missing doctor failure noted in the subagent findings.
  • pm-7m8p history chain is complete with full subagent evidence comments.

🧠 Learnings used
Learnt from: CR
Repo: unbraind/pm-cli PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-20T21:10:16.414Z
Learning: Use sandbox-safe commands for verification. For documentation-only work, run at least `pnpm build` and a focused link/content check. For broader work, run linked tests, coverage, validation, and release gates.

Learnt from: CR
Repo: unbraind/pm-cli PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-20T21:10:16.414Z
Learning: Every code, docs, or test change must be linked to a `pm` item with files/docs/tests and evidence comments.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements the pm-governance-audit package as the first-party governance hook exemplar, registering opt-in onRead and onWrite hooks that log compact JSONL records to a sidecar file when PM_GOVERNANCE_AUDIT_HOOK_LOG is set. It also updates the extension manifests, package metadata, documentation, and adds robust unit tests. The feedback highlights a potential reliability issue where synchronous file system operations (mkdirSync and appendFileSync) are performed without error handling. Wrapping these operations in a try...catch block is recommended to prevent any logging failures from crashing the main CLI workflows.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@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: 1

🤖 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 `@packages/pm-governance-audit/extensions/governance-audit/index.ts`:
- Around line 113-133: In appendHookAuditRecord, make filesystem ops fail-open:
wrap the mkdirSync and appendFileSync calls (the code using absoluteLogPath
derived from process.env[HOOK_LOG_ENV] and the writeContext construction) in a
try/catch so any errors (permissions/ENOSPC/invalid path) are caught and do not
propagate; on error, emit a non-throwing warning (e.g., console.warn or
processLogger.warn) that includes the absoluteLogPath and the error message,
then return silently so normal read/write operations continue unaffected.
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 106ca321-02e0-4e3f-ab6d-aef5e9c4fb2d

📥 Commits

Reviewing files that changed from the base of the PR and between 4f87b07 and c177b2b.

📒 Files selected for processing (12)
  • .agents/pm/extensions/.managed-extensions.json
  • .agents/pm/features/pm-7m8p.toon
  • .agents/pm/history/pm-7m8p.jsonl
  • CHANGELOG.md
  • docs/EXTENSIONS.md
  • docs/SDK.md
  • packages/pm-governance-audit/README.md
  • packages/pm-governance-audit/extensions/governance-audit/index.js
  • packages/pm-governance-audit/extensions/governance-audit/index.ts
  • packages/pm-governance-audit/extensions/governance-audit/manifest.json
  • packages/pm-governance-audit/package.json
  • tests/unit/builtin-extension-entrypoints.spec.ts

Address PR #123 CodeRabbit and Gemini feedback.

- wrap governance-audit sidecar filesystem writes in best-effort try/catch

- cache created log directories to avoid redundant mkdir calls

- add regression coverage for invalid sidecar paths

- track and close pm-mzlu review follow-up with regenerated changelog

Verification: focused package tests 62/62; pnpm build; temp governance-audit install smoke with invalid sidecar path fail-open; full coverage 2517 tests at 100%; changelog check; validate history drift ok.
@unbraind

unbraind commented Jun 6, 2026

Copy link
Copy Markdown
Owner Author

@codex review
/gemini review
@gemini-code-assist
@coderabbitai review

Pushed review follow-up aabcb37: sidecar hook logging now fails open, caches created directories, and includes invalid-path regression coverage.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the follow-up commit diff
gh api repos/unbraind/pm-cli/commits/aabcb376 --jq '.files[] | "=== \(.filename) ===\n\(.patch)"' 2>/dev/null

Length of output: 18570



@unbraind All three points confirmed addressed in aabcb37:

  • 🔴 Fail-open error handling — both index.ts and index.js now wrap the full mkdirSync + appendFileSync block in try/catch with the best-effort comment. Symmetric across both files. ✅
  • 🟡 Directory caching — const createdHookLogDirs = new Set<string>() added at module scope; the if (!createdHookLogDirs.has(logDir)) guard prevents redundant syscalls on repeated hook invocations. ✅
  • 🟢 Invalid-path regression — the new test sets PM_GOVERNANCE_AUDIT_HOOK_LOG to a directory path (path.dirname(hookLogPath)) — which would normally produce EISDIR — invokes the write hook, and asserts .resolves.toBeUndefined(), proving the hook swallows the error silently. ✅

The pm-mzlu task chain (create → in_progress → close → release) is also complete with evidence and linked to parent pm-7m8p. Everything looks clean.

[resolve]


🧠 Learnings used
Learnt from: CR
Repo: unbraind/pm-cli PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-20T21:10:16.414Z
Learning: Use sandbox-safe commands for verification. For documentation-only work, run at least `pnpm build` and a focused link/content check. For broader work, run linked tests, coverage, validation, and release gates.

Learnt from: unbraind
Repo: unbraind/pm-cli PR: 0
File: :0-0
Timestamp: 2026-05-28T05:46:05.731Z
Learning: In the `unbraind/pm-cli` repository, `.agents/pm/` files (issues, history, epics, extensions) are the source of truth for the pm CLI tracker and are committed to git as the result of pm CLI mutations (`pm close`, `pm comments`, `pm changelog generate`, etc.). They should not be flagged as hand-edited files in code reviews.

Learnt from: unbraind
Repo: unbraind/pm-cli PR: 0
File: :0-0
Timestamp: 2026-05-21T22:17:12.545Z
Learning: In the `unbraind/pm-cli` repository, files under `.agents/pm/` (with extensions `.toon` and `.jsonl`) are generated and managed exclusively by the `pm` CLI tool itself (via `pm create`, `pm close`, `pm update`, etc.). They are never manually edited. Committing these files alongside the work they track is the established convention in this repo (see PRs `#36`–#39). These files should NOT be flagged with "do not edit directly" or similar warnings in code review.

Learnt from: unbraind
Repo: unbraind/pm-cli PR: 0
File: :0-0
Timestamp: 2026-05-28T06:10:29.890Z
Learning: In the `unbraind/pm-cli` repository, files under `.agents/pm/` (including `.agents/pm/epics/*.toon`, `.agents/pm/extensions/.managed-extensions.json`, `.agents/pm/history/*.jsonl`, and similar) are intentional source-of-truth tracker files for the pm-cli project management system. They are tracked in git by design and should NOT be flagged as files that shouldn't be edited or committed. Review comments suggesting these files should not be modified are false-positives for this repository.

Learnt from: unbraind
Repo: unbraind/pm-cli PR: 0
File: :0-0
Timestamp: 2026-05-30T22:17:32.126Z
Learning: In the `unbraind/pm-cli` repository, files under `.agents/pm/**` (e.g. `.agents/pm/issues/`, `.agents/pm/chores/`, `.agents/pm/features/`, `.agents/pm/history/`) are git-tracked by design and are created/updated exclusively via the sanctioned `pm` CLI tooling (`pm create`, `pm close`, `pm comments`, etc.). These files are the repository's internal system of record and should NOT be flagged as "do not edit directly" — direct edits via the `pm` CLI are the correct and intended workflow.

Learnt from: CR
Repo: unbraind/pm-cli PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-20T21:10:16.414Z
Learning: Applies to **/*.test.{js,ts,mjs,cjs} : Tests must never read or write the real repository `.agents/pm` data. Use `node scripts/run-tests.mjs` for local tests and avoid recursive `pm test-all` item links.

Learnt from: CR
Repo: unbraind/pm-cli PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-20T21:10:16.414Z
Learning: Every code, docs, or test change must be linked to a `pm` item with files/docs/tests and evidence comments.

Learnt from: CR
Repo: unbraind/pm-cli PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-20T21:10:16.414Z
Learning: Keep edits scoped to the claimed item. Link changed files with `pm files`, docs with `pm docs`, and runnable verification with `pm test`.

Learnt from: CR
Repo: unbraind/pm-cli PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-20T21:10:16.414Z
Learning: Orient by running `pm context`, `pm search`, `pm list-open`, and `pm list-in-progress` before `pm create`. If net-new work is required, create or reuse the parent lineage first and record duplicate-check evidence in a create-time comment.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@unbraind
unbraind merged commit 290698f into main Jun 6, 2026
13 checks passed
@unbraind
unbraind deleted the feat/governance-audit-hooks-exemplar branch June 6, 2026 18:21
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