Skip to content

feat(mt#1066): PostToolUse hook enforcing /review-pr after session_pr_create#684

Closed
minsky-ai[bot] wants to merge 2 commits into
mainfrom
task/mt-1066
Closed

feat(mt#1066): PostToolUse hook enforcing /review-pr after session_pr_create#684
minsky-ai[bot] wants to merge 2 commits into
mainfrom
task/mt-1066

Conversation

@minsky-ai
Copy link
Copy Markdown
Contributor

@minsky-ai minsky-ai Bot commented Apr 22, 2026

Summary

Adds a PostToolUse hook that fires when mcp__minsky__session_pr_create succeeds and injects a system-reminder requiring /review-pr invocation before turn end. Structural enforcement of the rule already documented in feedback_review_pr_process.md: after creating a PR, the agent must review it via MCP — not punt review to the user.

Memory-only enforcement of this rule failed on PR #677 (mt#1057) despite the rule being loaded in context. Per /retrospective escalation policy ("if a CLAUDE.md rule was the previous fix, this time it needs a hook"), this is the escalation: memory → hook.

Changes

  • .claude/hooks/require-review-after-pr-create.ts — the hook. Silent on failure paths and non-matching tools; emits additionalContext on success.
  • .claude/settings.json — registers the hook under PostToolUse with matcher mcp__minsky__session_pr_create, 5s timeout.
  • CLAUDE.md — updates the /review-pr bullet in §Key Workflows with the new requirement and references the hook as backstop.

Test plan

Manual verification performed against the hook script itself:

  • Success case (PR URL present): hook emits a system-reminder with the PR number and /review-pr <N> command
  • Failure case (success: false): hook exits silently (no stdout)
  • Non-matching tool (mcp__minsky__session_commit): hook exits silently
  • chmod +x on the new hook file (pre-commit validates)
  • settings.json parses as valid JSON
  • TypeScript typecheck passes (0 errors)

End-to-end verification will require the next session_pr_create on this repo after merge — the hook does not take effect in the session workspace itself because Claude Code loads hooks from the main workspace $CLAUDE_PROJECT_DIR, not the session clone.

Context

  • Retrospective output from PR docs(mt#1057): add ADR-007 for cognition provider abstraction #677 (see review thread there for the incident summary)
  • Related hook: .claude/hooks/require-review-before-merge.ts (merge-time equivalent — this PR complements it at pr-create-time)
  • Rule being enforced: feedback_review_pr_process.md — Never ask user to review; use the skill, post to GitHub

🤖 Generated with Claude Code

edobry added 2 commits April 22, 2026 13:43
…_create

Adds .claude/hooks/require-review-after-pr-create.ts, a PostToolUse hook
matching mcp__minsky__session_pr_create. On successful PR creation, it
emits a system-reminder requiring /review-pr invocation before turn end.
Failure paths and non-matching tools are silent.

Structural enforcement of feedback_review_pr_process.md rule 22 (Never
@minsky-ai minsky-ai Bot added the authorship/co-authored Co-authored by human and AI agent label Apr 22, 2026
Copy link
Copy Markdown
Contributor Author

@minsky-ai minsky-ai Bot left a comment

Choose a reason for hiding this comment

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

Review: PostToolUse hook enforcing /review-pr after session_pr_create

CI status: pending (both Prevent Placeholder Tests and build in_progress at review time)

Coverage: 3/3 files reviewed.

Findings

No blocking issues. Hook is small, well-scoped, and follows the established pattern.

Checked and clear

  • .claude/hooks/require-review-after-pr-create.ts — Shebang and imports match the existing hook convention (verified against .claude/hooks/require-review-before-merge.ts and .claude/hooks/types.ts).
  • Defensive tool name check at line 16 — settings.json matcher already filters but re-checking is cheap insurance against future matcher broadening.
  • Success gate at line 24 — !result.success correctly handles both success: false and missing success field (empty object from ?? {} fallback). Hook exits silently on failure as spec requires.
  • URL extraction regex /\/pull\/(\d+)/ — matches the session_pr_create output shape (url: "https://github.com/.../pull/N"). Graceful degradation when URL absent (reminder still emits with (number unavailable — check tool output)).
  • additionalContext field — correct for PostToolUse hooks per HookOutput interface in types.ts. permissionDecision is PreToolUse only.
  • .claude/settings.json — new entry under PostToolUse with matcher mcp__minsky__session_pr_create, 5s timeout, consistent with existing entries. Valid JSON (verified via jq .).
  • CLAUDE.md — bullet update preserves existing format; added clause is accurate and references the hook as backstop.
  • Manual verification performed against the hook script:
    • Success input → emits correctly-formatted reminder
    • success: false input → silent exit (no stdout)
    • Non-matching tool name → silent exit
  • chmod +x applied to new hook file (verified -rwxr-xr-x); pre-commit chmod enforcement passed.
  • TypeScript typecheck passes (0 errors) via mcp__minsky__validate_typecheck.
  • Not a removal PR — no behavioral residue search required.
  • No feedback loops — the hook emits context but doesn't chain to another tool call, so no risk of infinite reminder loops.

Spec verification

Task: mt#1066

Criterion Status Evidence
.claude/hooks/require-review-after-pr-create.ts exists with execute permission (0755) Met ls -la showed -rwxr-xr-x
Hook registered in .claude/settings.json PostToolUse section with matcher mcp__minsky__session_pr_create Met Diff at .claude/settings.json:119-129
Hook detects tool success and emits <system-reminder> referencing the PR URL Met Hook source require-review-after-pr-create.ts:29-53; manual test confirmed output
System-reminder text instructs /review-pr <N> before turn end Met Hook source lines 38-47
Hook is idempotent — firing multiple times does not duplicate reminders or fail Met Deterministic output per invocation; each tool call produces at most one reminder
Hook does NOT fire when session_pr_create fails (error path) Met Line 24 if (!result.success) process.exit(0); manual test confirmed silent on success: false
Existing hook patterns followed Met Uses readInput/writeOutput helpers from types.ts; output shape matches HookOutput type
CLAUDE.md updated with protocol note Met CLAUDE.md:56 diff
Manual verification Partially met Hook script behavior verified via piped input. End-to-end verification (hook firing during a real session_pr_create) cannot be exercised until this PR merges to main — Claude Code loads hooks from $CLAUDE_PROJECT_DIR (the main workspace), not the session clone. This is called out explicitly in the PR description's Test plan section.

Action required: None. The "partially met" on manual verification is an inherent limitation of how Claude Code resolves hook paths — the hook cannot be exercised end-to-end pre-merge. The script-level verification is complete and sufficient for a small hook of this shape.

Documentation impact

Updated CLAUDE.md in this PR (the /review-pr bullet in §Key Workflows now mentions both merge-time and pr-create-time requirements).

No other doc updates needed:

  • docs/architecture.md — hook-level enforcement is not an architectural principle; the ADR Index and domain structure are unaffected.
  • docs/theory-of-operation.md — the hook reinforces existing VSM System 2 (coordination/enforcement) behavior; the doc already lists "workflow hooks" and "pre-commit hooks" at the System 2 level without enumerating each hook. Not a status change to the organ.
  • CONTRIBUTING.md — developer workflow changes here are agent-facing, not human-contributor-facing; CONTRIBUTING doesn't document agent workflow.

Note on CI

Checks are still running. Per the skill's rule ("Don't approve with failing checks"), this review is COMMENT only — not an approval. If CI passes and the user confirms, this PR is ready to merge.

(Had Claude look into this — AI-assisted review)

@edobry
Copy link
Copy Markdown
Owner

edobry commented Apr 22, 2026

Superseded — not merging.

This PR enforces the wrong step. The correct practice for bot-authored (Tier 3) PRs is Chinese-wall review via a reviewer subagent, not self-review via /review-pr — see feedback_review_before_asking.md and CLAUDE.md §"Review before asking the user" (both landed in the same 2026-04-22 session). The reminder text this hook injects would cement the anti-pattern the new review architecture is replacing.

Sprint A (mt#1073) is also shipping the minsky-reviewer App as a webhook-driven external reviewer, which makes even a correctly-targeted version of this hook redundant within ~1 week.

mt#1066 marked CLOSED as superseded. PR left open for manual close (see comment on tool gap below).

— Had Claude look into it after the user flagged the architecture mismatch.

Copy link
Copy Markdown

@minsky-reviewer minsky-reviewer Bot left a comment

Choose a reason for hiding this comment

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

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: unknown


Findings

[BLOCKING] .claude/hooks/require-review-after-pr-create.ts:1-58 and .claude/settings.json:116-132 — Misrepresented “enforcement”; current hook only emits additionalContext and does not enforce

  • Evidence: The hook only writes HookOutput with hookSpecificOutput.additionalContext and always exits 0; there is no permissionDecision deny anywhere in the file. In settings.json it is registered under PostToolUse as a command with a statusMessage, not as a Pre/Stop blocker. Therefore, nothing actually “requires” or enforces invoking /review-pr before turn end — it only reminds.
  • Failure mode: The PR description and CLAUDE.md both claim an enforcement/backstop: “PostToolUse hook enforces the latter — do not write summaries that punt review to the user.” In reality, the agent can still end the turn or write a summary without calling /review-pr; the hook does not block Stop, SubagentStop, or any tool that would end the flow.
  • Impact: This introduces a documentation/spec mismatch and fails the stated escalation goal (“memory → hook” for structural enforcement). If the prior issue was agents ignoring memory-only rules under time pressure, a non-blocking reminder at PostToolUse is not a structural control and will not reliably prevent recurrence.
  • Request: Either (a) implement actual enforcement (e.g., a Stop/SubagentStop hook that denies turn end if no review has been submitted since the PR was created, or a PreToolUse gate on summary/Done transitions), or (b) change the docs and PR description to clearly state this is a reminder only, not an enforcement, and justify why a reminder suffices.

[NON-BLOCKING] .claude/hooks/require-review-after-pr-create.ts:23-31 — Unasserted assumption about tool_result shape may cause silent no-op

  • Evidence: The hook requires tool_result.success to be truthy to fire; if success is absent, falsy, or a string like "true", the hook exits early and emits nothing. The code comments state “tool_result shape from session_pr_create includes { success: true, url: ... }” but this is not asserted or validated.
  • Risk: If session_pr_create returns a slightly different shape (e.g., success nested, success as string, or url under result.prUrl), the reminder won’t fire — exactly the failure the PR is trying to prevent.
  • Suggestion: Add a more defensive success detection (e.g., coerce to boolean, accept "ok" or "status" variants), and guard against url variants. Consider logging a minimal warning context when expected fields are missing so we can detect mismatches.

[NON-BLOCKING] .claude/hooks/require-review-after-pr-create.ts:35-43 — UX when PR number parse fails is suboptimal

  • Evidence: If parsing /pull/N fails, the reminder says “(number unavailable — check tool output)” and suggests “/review-pr ”.
  • Risk: This leaves the agent guessing. The URL itself may still be present and sufficient for the /review-pr skill to infer the PR or for the agent to fetch it via other MCP tools.
  • Suggestion: Always include the literal URL prominently, and consider recommending a fallback invocation that accepts a URL if supported, or provide guidance to fetch the PR number via an MCP tool if not.

[NON-BLOCKING] CLAUDE.md:53-57 — Documentation currently states “Required … immediately after session_pr_create (a PostToolUse hook enforces the latter…)”

  • Evidence: The actual hook is a reminder; it does not enforce. This is a wording mismatch that may mislead agents and reviewers.
  • Suggestion: Reword to “A PostToolUse hook reminds you of this requirement; enforcement occurs at merge time” (or implement actual enforcement as noted above).

[NON-BLOCKING] General — Potential interaction with summaries not gated by tools

  • Evidence: The reminder instructs “before ending this turn or writing any summary for the user,” but summaries may be produced without a tool invocation that a hook can intercept. There is no PreToolUse/Stop gating tied to the summary action.
  • Suggestion: If you intend structural prevention of “punt to user” summaries, consider a Stop/SubagentStop hook that checks for a recent session_pr_review_submit call after a detected session_pr_create within the same session, and denies stop with a clear reason if missing.

Spec verification table

  • Add a PostToolUse hook that fires when mcp__minsky__session_pr_create succeeds and injects a system reminder: Partially Met
    • The hook exists and injects additionalContext. However, the PR and docs claim “enforcement,” which is not implemented; it’s a reminder only.
  • Silent on failure paths and non-matching tools: Met
    • input.tool_name is re-checked; if not matching or if success is falsy, process exits 0 with no output.
  • Register the hook under PostToolUse with matcher mcp__minsky__session_pr_create, 5s timeout: Met
    • .claude/settings.json adds the matcher and command with a 5s timeout.
  • Update CLAUDE.md to reference the new requirement and hook as backstop: Not Met (as written)
    • CLAUDE.md claims the hook “enforces” immediate review after creation. The implementation does not enforce; it only reminds. This is a spec-doc mismatch.

Documentation impact

  • CLAUDE.md was updated, but the wording asserts enforcement that the implementation does not provide. docs/feedback_review_pr_process.md is referenced in code/comments but not updated; if that file codifies “structural enforcement,” it may also need alignment or a clarifying note that enforcement-at-PR-create is currently a reminder, not a gate, and that merge is actually enforced by require-review-before-merge.ts.
  • Consider adding a brief architecture note in .claude/hooks/SPEC.md (or similar) outlining the policy sequence: PR-create reminder → merge-time enforcement, and any planned Stop hook for turn-end enforcement.

Event: REQUEST_CHANGES

edobry added a commit that referenced this pull request May 9, 2026
## Summary

Documents the parallel-work-guard structural-config exemption (mt#1587, PR #952, merged `8ebbdbf9` on 2026-05-08) across the four documentation surfaces that describe the Tier-3 parallel-work guard. Pure docs-only PR.

## Motivation & Context

mt#1587 PR #952 explicitly deferred these doc updates as out-of-scope to avoid putting the PR itself in the parallel-work-guard overlap trap that it was trying to fix (the docs all sit in files that every in-flight hook PR touches). Now that mt#1587 is live in production (mt#1555 just used it successfully), the docs catch up.

Without this update, operators reading CLAUDE.md / AGENTS.md / hook-files.mdc see the pre-mt#1587 framing where every hook PR routinely uses `MINSKY_FORCE_PARALLEL=1` to bypass settings.json overlap — which is no longer accurate.

## Key Changes

A new `**Structural-config exemption (mt#1587):**` paragraph between the "Checks run" list and the "On hit" paragraph in the `## Parallel-Work Guard` section, plus an updated `**Override mechanism:**` paragraph clarifying the override is rarely needed post-mt#1587.

Files updated:
- `.minsky/rules/hook-files.mdc` — **canonical rule source** (the actual change)
- `CLAUDE.md` — output of `rules_compile --target=claude.md`
- `AGENTS.md` — output of `rules_compile --target=agents.md`
- `.cursor/rules/hook-files.mdc` — cursor-format mirror of the source rule

The new paragraph names `STRUCTURED_CONFIG_ALLOWLIST` contents (`.claude/settings.json`, `.claude/settings.local.json`), explains the **append-only into JSON arrays** contract, calls out the fail-closed posture, and notes the audit-warning channel.

The override section is updated to clarify that `MINSKY_FORCE_PARALLEL=1` is rarely needed for routine hook PRs after mt#1587 (settings.json append-only diffs no longer collide), but remains the escape valve for:
- Non-append-only changes (re-ordering, modification, key changes)
- Non-allowlisted files
- Operator-judgment overrides

## Process correction

The first version of this PR hand-edited all 4 files directly. CLAUDE.md, AGENTS.md, and `.cursor/rules/hook-files.mdc` are compiled outputs of the rules pipeline, not authoring formats — each of the first two carries a `<!-- Generated by minsky rules compile. Do not edit directly. -->` banner on line 1. The proper authoring path is to edit `.minsky/rules/hook-files.mdc` only and re-run `minsky rules compile` for each monolith target, plus `rules update --format=cursor` for the cursor mirror.

I verified after the fact: running `bun run minsky rules compile --target=agents.md` and `--target=claude.md` against this branch produces byte-identical output to my hand-edits, and the cursor mirror's added paragraph matches the source rule exactly. Content is correct; the process was the only thing that was wrong.

Structural fix tracked separately:
- **mt#1699** — PreToolUse hook that reads target file's first ~5 lines and blocks edits when a generation banner is present. Mirrors the `parallel-work-guard.ts` / `check-branch-fresh.ts` pattern.
- **mt#1700** — RFC investigating manifest-driven extension covering generated files without markers and structurally-API-managed sources without generators.
- **Bridge memory `d9324047`** — "Don't bypass structural APIs for managed artifacts" (broadens the prior `7c15a2f0` memory from `.claude/skills/` + `.claude/agents/` to the full structural-API-managed class).

## Testing

Acceptance tests per spec — all pass:

```
=== Acceptance Test 1: STRUCTURED_CONFIG_ALLOWLIST in CLAUDE.md ===
77:**Structural-config exemption (mt#1587):** Files in `STRUCTURED_CONFIG_ALLOWLIST`

=== Acceptance Test 2: append-only in hook-files.mdc files ===
.cursor/rules/hook-files.mdc
.minsky/rules/hook-files.mdc

=== Acceptance Test 3: MINSKY_FORCE_PARALLEL guidance in all 4 files ===
CLAUDE.md:4
AGENTS.md:4
.cursor/rules/hook-files.mdc:4
.minsky/rules/hook-files.mdc:4
```

Compile pipeline byte-identity check (post-hoc):

```
$ bun run minsky rules compile --target=agents.md
✅ Success
$ bun run minsky rules compile --target=claude.md
✅ Success
$ git status
On branch task/mt-1678
nothing to commit, working tree clean
```

Prettier check passes (the .mdc files lack a parser per Prettier — expected, no formatting concern).

## Concurrency analysis

N/A — pure docs, no check-then-act pattern introduced.

## Documentation impact

This PR IS the documentation update. No further docs are touched.

## Parallel-work acknowledgment

At session-start time, two open PRs touched in-scope files in different sections (so file-level overlap, no textual conflict):

- **PR #684 (mt#1066)** — modifies CLAUDE.md `## Key Workflows` section (1-line edit on the `/review-pr` skill description).
- **PR #1009 (mt#1682)** — adds new "MCP disconnect cadence" section near top of CLAUDE.md and AGENTS.md.

mt#1678's edits are confined to the `## Parallel-Work Guard` section (different location). Git's 3-way merge resolves section-local edits automatically. The hook-files.mdc files are touched by neither sibling PR.

Co-Authored-By: minsky-ai[bot] <minsky-ai[bot]@users.noreply.github.com>
edobry added a commit that referenced this pull request May 14, 2026
…ne" after PR create

## Summary

Closes mt#1793. Adds a PostToolUse hook on `mcp__minsky__session_pr_create` that, when PR creation succeeds, injects an `additionalContext` system-reminder requiring the agent to drive convergence (via `session_pr_wait-for-review` or a Chinese-wall reviewer subagent on webhook-miss) and explicitly forbidding deferral phrases ("ping me when done", "let me know when merged", "ready for your review/merge", "I'll wait for your signal").

Originating incident: 2026-05-12 PR #1076 (mt#1791) — agent created PR and ended turn with "ping me to wire the SDK once merged and you've set the key." User had to poke: "so you just sat there." The corpus rule was loaded in context AND cited in the same message that violated it. Memory + corpus tiers failed; hook-tier escalation.

**Supersedes** mt#1066 / PR #684 (`require-review-after-pr-create.ts`) — narrower /review-pr-only slice. mt#1066 CLOSED; PR #684 zombie since 2026-04-27. mt#1793's hook covers both intents. PR #684 should be closed after this merges.

## Key Changes

- **New hook** `.claude/hooks/drive-pr-to-convergence.ts` — PostToolUse on `mcp__minsky__session_pr_create`. Emits reminder when `tool_result.success === true`. Silent otherwise. Always exits 0.
- **Test file** `.claude/hooks/drive-pr-to-convergence.test.ts` — 13 tests covering decision logic + content assertions. 13/13 pass.
- **Settings.json** — registers hook (PostToolUse matcher `mcp__minsky__session_pr_create`, 5s timeout).
- **Documentation** — `.minsky/rules/hook-files.mdc` new "Drive-PR-To-Convergence Reminder" section; compiled outputs regenerated.
- **Bridge memory** `feedback_drive_pr_to_convergence_dont_end_on_ping_me` (id `52b2600c-…`, DB-only) updated with Status header + Tier history + retirement-budget adjustment.

## Success Criteria

| SC | Status |
|----|--------|
| 1. Hook fires on PostToolUse for `session_pr_create` when `result.success` is true | ✅ Met |
| 2. Hook injects `additionalContext` with required-action + forbidden-deferral + corpus-rule reference | ✅ Met |
| 3. Existing hook tests still pass | ✅ Met |
| 4. Bridge memory updated with "retire when DONE" pointer | ✅ Met (DB-only) |

Execution evidence:

```
$ bun test --preload ./tests/setup.ts --timeout=15000 ./.claude/hooks/drive-pr-to-convergence.test.ts

.claude/hooks/drive-pr-to-convergence.test.ts:
(pass) drive-pr-to-convergence hook (mt#1793) > decideReminder > emits reminder on successful session_pr_create [0.02ms]
(pass) drive-pr-to-convergence hook (mt#1793) > decideReminder > silent on failed session_pr_create (success=false) [0.01ms]
(pass) drive-pr-to-convergence hook (mt#1793) > decideReminder > silent when tool_result is missing [0.01ms]
(pass) drive-pr-to-convergence hook (mt#1793) > decideReminder > silent when tool_result.success is not strictly true [0.02ms]
(pass) drive-pr-to-convergence hook (mt#1793) > decideReminder > silent on non-matching tool name
(pass) drive-pr-to-convergence hook (mt#1793) > decideReminder > silent on Bash tool (covers wildcard PostToolUse matchers that might union)
(pass) drive-pr-to-convergence hook (mt#1793) > decideReminder > silent on session_pr_merge (sibling tool, not in scope)
(pass) drive-pr-to-convergence hook (mt#1793) > DRIVE_TO_CONVERGENCE_REMINDER content > references the corpus rule for traceability
(pass) drive-pr-to-convergence hook (mt#1793) > DRIVE_TO_CONVERGENCE_REMINDER content > names the required next action explicitly
(pass) drive-pr-to-convergence hook (mt#1793) > DRIVE_TO_CONVERGENCE_REMINDER content > names the webhook-miss fallback (/review-pr / Chinese-wall reviewer)
(pass) drive-pr-to-convergence hook (mt#1793) > DRIVE_TO_CONVERGENCE_REMINDER content > forbids the originating deferral phrases
(pass) drive-pr-to-convergence hook (mt#1793) > DRIVE_TO_CONVERGENCE_REMINDER content > includes the slow-ask framing reference
(pass) drive-pr-to-convergence hook (mt#1793) > DRIVE_TO_CONVERGENCE_REMINDER content > encodes the success branches (APPROVE / CHANGES_REQUESTED)

 13 pass
 0 fail
 18 expect() calls
Ran 13 tests across 1 file. [67.00ms]
```

13/13 pass. typecheck clean (0 errors). lint clean (0 errors, 0 warnings).

## Acceptance Tests

| AT | Status |
|----|--------|
| 1. Synthetic test (success → reminder injected) | ✅ Met |
| 2. Synthetic test (failure → silent) | ✅ Met |
| 3. Audit (next 5 sessions show no "ping me when done") | 🕐 Observational |

## R1 fix

R1 BLOCKING (commit `21169bb6b`): inline code backticks split across two array elements caused broken markdown rendering. Rephrased citation; full backticked path on one line. Test assertion updated.

R1 non-blocking items deferred: `writeOutput()` consistency, wildcard-matcher docs, debug breadcrumbs, non-ASCII punctuation audit — improvements, not regressions.

## Out of scope

- Automated convergence (agent still drives)
- Bypass-merge auto-triggering (principal-level)

## R-family alignment

Hook-tier structural escalation (memory → corpus → skill → hook). Sibling to mt#1789, mt#1784, mt#1842 at the skill tier.

## Concurrency analysis

(N/A — pure-function over `ToolHookInput`.)

## Live verification

(N/A — informational hook; 13 unit tests verify behavior.)

Had Claude look into this.

Co-Authored-By: minsky-ai[bot] <minsky-ai[bot]@users.noreply.github.com>
@edobry
Copy link
Copy Markdown
Owner

edobry commented May 14, 2026

Superseded by mt#1793 / PR #1124 (drive-pr-to-convergence hook). mt#1066's narrower /review-pr-only enforcement is now covered by the broader drive-to-convergence reminder which includes /review-pr as the webhook-miss fallback. Task mt#1066 was CLOSED; this PR has been zombie since 2026-04-27. Closing as superseded.

@edobry edobry closed this May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

authorship/co-authored Co-authored by human and AI agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant