Skip to content

Adopt the canonical pm-ops docstring gate and document the remaining surface - #60

Merged
unbraind merged 2 commits into
mainfrom
adopt-canonical-docstring-gate
Aug 9, 2026
Merged

Adopt the canonical pm-ops docstring gate and document the remaining surface#60
unbraind merged 2 commits into
mainfrom
adopt-canonical-docstring-gate

Conversation

@unbraind

@unbraind unbraind commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Adopt the canonical docstring gate

pm-context was one of the last repositories without a docstring gate. Six exported declarations carried no documentation, and nothing would have caught a seventh.

  • Thin launcher at scripts/docstring-gate.ts importing analyzeDocstringCoverage from pm-ops/docstrings — the analyzer is imported, never vendored.
  • pm-ops pinned exactly at 2026.8.8.
  • Required CI step after the type check (no continue-on-error) and part of release:check.
  • scripts/docstring-gate.ts added to coverageGate.sources, so the launcher is held to the same floor as the rest of the package rather than sitting outside the gate.

This takes canonical adoption to 18 of 22 once pm-web #84 lands, leaving pm-csv, plus pm-cli (upstream) and pm-rust (Rust).

The documentation itself

Documented CommandError and its exitCode, the PmItem and ContextPackOptions interfaces, and the MARKDOWN_SECTIONS / AGENT_SECTIONS constants.

Two of these could not be written from the constant lists alone, and the draft that was written that way was wrong:

MARKDOWN_SECTIONS contains both neighborhood and neighbors, which read like two spellings of one section. They are not. The markdown renderer matches every section name exactly, and the two emit different content — neighborhood renders the relationship edges ("Dependency Neighborhood"), neighbors renders the neighbouring items ("Neighbor Items"). Selecting one does not include the other.

Only the agent renderer accepts aliases, through a second include parameter: actions and nextactions both select next-actions, and activity selects recent.

A docstring claiming the markdown names were interchangeable would have passed the gate — it enforces presence, not truth — and misled every caller who trusted it. Each claim here was checked against the renderer that implements it.

Verification

Gate Result
npm run docstring exit 0 — 4 files, 19 declarations
npm run typecheck clean
npm test pass
npm run coverage 100/100/100, launcher included
npm run changelog:check up to date

pm item

Summary by Sourcery

Adopt the shared pm-ops docstring gate for pm-context and fully document the remaining exported surface and gate launcher behavior.

New Features:

  • Add a docstring gate launcher script that runs the canonical analyzer from pm-ops/docstrings and integrates it into npm scripts and release checks.

Enhancements:

  • Document CommandError, PmItem, ContextPackOptions, and the MARKDOWN_SECTIONS and AGENT_SECTIONS constants to clarify CLI behavior and context pack semantics.
  • Include the docstring gate script in coverage gate sources so it is held to the same coverage threshold as the rest of the package.

Build:

  • Add pm-ops as a pinned dependency and wire a docstring npm script into the release:check pipeline.

CI:

  • Add a CI step to verify docstring coverage after type checking.

Documentation:

  • Update the changelog to record adoption of the canonical docstring gate and the now-fully-documented surface.

Tests:

  • Introduce a dedicated test suite for the docstring gate launcher covering successful scans, failure reporting, empty-root behavior, CLI entry handling, and symlink/argv resolution.

Chores:

  • Record the pm-context-ylx4 task and history entries in the agent metadata.

Summary by cubic

Adopted the canonical docstring gate via pm-ops/docstrings, documented the remaining public surface, and made the gate required in CI and release:check. Hardened the launcher to fail loudly on broken entry paths; coverage remains 100%.

  • New Features

    • Added scripts/docstring-gate.ts launcher using pm-ops/docstrings (imported, not vendored) and npm run docstring.
    • Required gate in CI and release:check; included the launcher in coverageGate.sources.
    • Documented CommandError (and exitCode), PmItem, ContextPackOptions, MARKDOWN_SECTIONS, and AGENT_SECTIONS.
    • Clarified section behavior: markdown sections match exact names; agent sections support aliases.
  • Bug Fixes

    • Propagate an unresolvable entry path in isMainInvocation instead of skipping the gate, preventing npm run docstring from exiting 0 without scanning; tests updated to assert the throw and symlinked entry handling.

Written for commit 4d62939. Summary will update on new commits.

Review in cubic

pm-context had no docstring gate, so six exported declarations carried no
documentation and nothing would have caught a seventh. Wires in the analyzer
published as `pm-ops/docstrings` through a thin launcher — the analyzer is
imported, never vendored — pinned exactly at 2026.8.8, as a required CI step
and part of `release:check`.

Documented `CommandError` and its `exitCode`, the `PmItem` and
`ContextPackOptions` interfaces, and the `MARKDOWN_SECTIONS` /
`AGENT_SECTIONS` constants.

Writing the last two required reading the renderers rather than the constant
lists, and the difference matters: `neighborhood` and `neighbors` look like two
spellings of one section, but the markdown renderer matches each exactly and
they emit different content — the relationship edges and the neighbouring items.
Only the agent renderer takes aliases, via a second `include` parameter, where
`actions`/`nextactions` select `next-actions` and `activity` selects `recent`.

Added `scripts/docstring-gate.ts` to `coverageGate.sources` so the launcher is
held to the same floor as the rest of the package instead of sitting outside the
gate. Coverage stays at 100/100/100 with it included.

Tracked as pm-context-ylx4.

@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

@unbraind

unbraind commented Aug 9, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review
@greptileai

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • Quality Improvements

    • Added automated documentation-coverage checks to continuous integration and release validation.
    • Added a command for locally verifying complete documentation coverage.
    • Expanded automated tests for documentation validation and command-line behavior.
  • Documentation

    • Added documentation for previously undocumented public commands, types, and configuration options.
    • Recorded the documentation-coverage improvement in the unreleased changelog.

Walkthrough

Added a pm-ops-based docstring coverage launcher. Integrated it with package scripts, release checks, CI, and coverage configuration. Documented six exported declarations and added tests for launcher behavior and execution safety.

Changes

Docstring coverage gate

Layer / File(s) Summary
Launcher implementation and documented declarations
scripts/docstring-gate.ts, index.ts
The launcher analyzes docstring coverage, formats violations, handles roots and exit codes, and runs only during direct execution. Six exported declarations now have documentation comments.
Package, CI, and behavioral validation
package.json, .github/workflows/ci.yml, test/docstring-gate.test.ts
Added the docstring script, release-check integration, pm-ops, coverage tracking for the launcher, CI execution, and tests for scan results, output, exit codes, symlinks, and unresolved paths.
Release and task records
CHANGELOG.md, .agents/pm/tasks/pm-context-ylx4.toon, .agents/pm/history/pm-context-ylx4.jsonl
Recorded the docstring gate rollout, validation results, and task closure.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI
  participant npm as npm run docstring
  participant Gate as scripts/docstring-gate.ts
  participant Analyzer as analyzeDocstringCoverage
  CI->>npm: Run the docstring check
  npm->>Gate: Invoke the launcher
  Gate->>Analyzer: Analyze the repository root
  Analyzer-->>Gate: Return violations or success
  Gate-->>CI: Write output and set process.exitCode
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly summarizes the main changes: adopting the canonical docstring gate and documenting the remaining public surface.
Description check ✅ Passed The description directly explains the docstring gate adoption, documentation updates, integration work, tests, and verification results.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch adopt-canonical-docstring-gate

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.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

@unbraind I will perform a full review of pull request #60.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 34 minutes.

@sourcery-ai

sourcery-ai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a canonical docstring gate launcher based on pm-ops/docstrings, wires it into CI and release checks, and documents previously undocumented public surface (errors, interfaces, and section constants) while providing behavioral tests for the gate.

Sequence diagram for the new docstring gate invocation in CI

sequenceDiagram
  actor CI
  participant npm_script_docstring as npm_run_docstring
  participant node_process as node
  participant docstring_gate_module as scripts_docstring_gate_ts
  participant pm_ops_docstrings as pm_ops_docstrings

  CI->>npm_script_docstring: run docstring
  npm_script_docstring->>node_process: node scripts/docstring-gate.ts
  node_process->>docstring_gate_module: isMainInvocation(process.argv, import.meta.url)
  docstring_gate_module-->>node_process: true
  node_process->>docstring_gate_module: main(process.argv.slice(2))
  docstring_gate_module->>docstring_gate_module: runGate(root)
  docstring_gate_module->>pm_ops_docstrings: analyzeDocstringCoverage({ root })
  pm_ops_docstrings-->>docstring_gate_module: report
  docstring_gate_module-->>node_process: GateResult
  node_process->>CI: exitCode / stdout / stderr
Loading

File-Level Changes

Change Details Files
Introduce a thin docstring gate launcher that delegates to the canonical pm-ops/docstrings analyzer and expose a small CLI with testable behavior.
  • Add scripts/docstring-gate.ts implementing runGate, main, and isMainInvocation using analyzeDocstringCoverage from pm-ops/docstrings.
  • Design runGate to be pure (no direct process IO) and to return structured exit code/stdout/stderr strings based on violations.
  • Implement main to resolve the scan root from argv, call runGate, write newline-terminated output, and set process.exitCode without exiting.
  • Add isMainInvocation helper that resolves argv[1] via realpathSync and compares to import.meta.url, with ENOENT handled as a non-main case.
  • Use an indexed function-call pattern at module bottom to avoid uncoverable branches under test while still running the gate on direct invocation.
scripts/docstring-gate.ts
Add a behavioral test suite around the docstring gate launcher to validate default root, failure reporting, empty-root behavior, CLI IO, and entry-point detection.
  • Create test/docstring-gate.test.ts with node:test cases covering runGate success/failure scenarios, handling of empty repositories, and main’s stdout/stderr and exitCode semantics.
  • Test isMainInvocation for direct invocations, non-main argv, symlinked entry paths, and non-resolvable argv paths.
  • Exercise interaction with temporary directories, symlinks, and process state (stdout/stderr write, exitCode) to ensure non-flaky CI behavior.
test/docstring-gate.test.ts
Wire the docstring gate into npm scripts, CI workflow, coverage configuration, and dependencies so it runs as part of release checks and uses a pinned canonical analyzer version.
  • Add npm run docstring script that invokes the new launcher, and include it in the release:check pipeline before build.
  • Update the coverageGate configuration to treat scripts/docstring-gate.ts as a covered source so it meets the same coverage floor as the rest of the package.
  • Extend the CI workflow to run npm run docstring after typechecking.
  • Add pm-ops@2026.8.8 as a devDependency to consume the canonical docstrings analyzer.
  • Update package-lock.json to reflect the new dependency and scripts changes.
package.json
.github/workflows/ci.yml
package-lock.json
Document previously undocumented public API surface: CommandError, PmItem, ContextPackOptions, and markdown/agent section constants, and propagate those docstrings to built artifacts.
  • Add a descriptive JSDoc block to CommandError explaining its purpose, exitCode behavior, and name for cross-module recognition, plus a field-level doc for exitCode.
  • Document the PmItem interface, including optional fields, index signature rationale, and multiple spellings for relationship fields due to SDK/CLI JSON discrepancies.
  • Add detailed JSDoc for MARKDOWN_SECTIONS explaining neighborhood vs neighbors semantics and validateSections behavior.
  • Add JSDoc for AGENT_SECTIONS describing differences from markdown sections and supported aliases.
  • Document ContextPackOptions fields and groupings, including generatedAt’s role in deterministic pack generation.
  • Ensure generated dist/index.d.ts and dist/index.js carry the new documentation comments and keep source and built declarations in sync.
  • Regenerate source maps to align with the new comments in dist/index.d.ts.map and dist/index.js.map.
index.ts
dist/index.d.ts
dist/index.js
dist/index.d.ts.map
dist/index.js.map
Record the adoption of the docstring gate in project metadata and changelog.
  • Add a changelog entry under the "Other" section noting the adoption of the canonical docstring gate and its pm item reference.
  • Create pm agent history and task artifacts for pm-context-ylx4 to track this work in the project’s internal PM system.
CHANGELOG.md
.agents/pm/history/pm-context-ylx4.jsonl
.agents/pm/tasks/pm-context-ylx4.toon

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adopts the canonical pm-ops docstring analyzer and documents the remaining exported declarations.

  • Adds a required docstring check to CI, release validation, and coverage accounting.
  • Pins pm-ops at 2026.8.8 and adds launcher-focused tests.
  • Updates generated distribution artifacts, changelog entries, and task metadata.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
scripts/docstring-gate.ts Adds a thin CLI launcher that invokes the shared analyzer, formats violations, and fails closed on invalid invocation state.
test/docstring-gate.test.ts Covers successful and failing scans, empty roots, stream and exit-code behavior, direct invocation, and symlink resolution.
package.json Pins the analyzer dependency and integrates the gate into release and coverage checks.
.github/workflows/ci.yml Runs the docstring gate as a required CI step after type checking.
index.ts Adds documentation for the previously undocumented exported API surface.

Reviews (2): Last reviewed commit: "fix(gate): propagate an unresolvable ent..." | Re-trigger Greptile

@unbraind

unbraind commented Aug 9, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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 `@scripts/docstring-gate.ts`:
- Around line 128-135: The isMainInvocation function currently treats
realpathSync resolution failures as a non-main invocation, allowing the gate to
exit successfully. Make resolution failures propagate or produce a distinct
failure state that the top-level selector converts to a non-zero exit, while
preserving false for genuinely different entry paths; update the corresponding
docstring-gate tests to assert the failure behavior.
🪄 Autofix

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: ASSERTIVE

Plan: Pro Plus

Run ID: b749deb9-ad19-4873-a206-654310a16114

📥 Commits

Reviewing files that changed from the base of the PR and between 5e08ae5 and 442f07d.

⛔ Files ignored due to path filters (5)
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • .agents/pm/history/pm-context-ylx4.jsonl
  • .agents/pm/tasks/pm-context-ylx4.toon
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • index.ts
  • package.json
  • scripts/docstring-gate.ts
  • test/docstring-gate.test.ts

Comment thread scripts/docstring-gate.ts Outdated
`isMainInvocation` caught a `realpathSync` failure and returned false, so the
top-level selector called the no-op placeholder and `npm run docstring` exited 0
having scanned nothing — a required release check reporting success without
doing its job, which is the single failure this gate exists to prevent.

The docstring and the test both described that as failing closed. They were
using the phrase to mean "does not crash", which inverts it: the crash is the
safe outcome and the silent skip is the dangerous one. Reaching this case
requires `argv[1]` to stop resolving after Node has already loaded the file, so
it means the environment is broken, and a broken environment must not quietly
satisfy a gate.

Removes the catch, states the throw in the docstring, and rewrites the test to
assert the throw rather than the silent false. A genuinely different entry path
still returns false, which is how a test import declines to run the gate.

This copy now differs from the same launcher in the other repositories that run
the canonical analyzer; propagating it is tracked separately.

Found in review of #60.
@unbraind
unbraind merged commit 5baaa89 into main Aug 9, 2026
9 checks passed
@unbraind
unbraind deleted the adopt-canonical-docstring-gate branch August 9, 2026 23:40
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