Summary
humanize is a great foundation for an iterative implement-review-iterate loop, and the natural next step is for other Claude Code plugins to extend it — adding reviewers, gates, context-gathering passes, or convergence
checks — without forking or reaching into humanize's filesystem layout.
Today, the only extension surface is Claude Code's plugin-level hook composition (Stop/PreToolUse/etc.). That works as a foothold but isn't a real extension API: there's no schema for what an extender produces, no ownershi
p of merged output, no defined behavior when two extenders both want to block, and no surface for non-Stop lifecycle moments. This issue proposes humanize expose its own extension points that sibling plugins register again
st at install time.
Motivating example: a panel of reviewers, not just Codex
The most immediate use case is letting a sibling plugin add additional reviewers alongside Codex on every round. Imagine a multi-personality reviewer with several distinct lenses — e.g. a test-completeness personality, a s
cope-discipline personality, an architecture personality, a performance personality, a naming personality. Each lens is most useful as a separate registration into a reviewer panel that humanize aggregates, not as a single
monolithic review.
This generalizes well beyond any one reviewer:
- Custom review personalities tuned for a specific codebase (a security personality, an API-stability personality, a docs personality, …).
- A
cargo clippy / eslint / pylint reviewer that emits findings in the same schema.
- A license/compliance reviewer that gates convergence regardless of Codex's verdict.
- A test-coverage gate that blocks convergence if coverage regressed.
If reviewer registration is first-class, all of these become drop-in plugins on equal footing with Codex.
Why hook composition isn't enough
A sibling plugin can register its own Stop hook today and have it fire alongside humanize's loop-codex-stop-hook.sh at the same event. This
works, but the seams show:
-
Sibling plugins must reach into humanize's filesystem layout. To produce per-round artifacts, an extender has to locate .humanize/rlcr/<timestamp>/, parse state.md for current_round, and write next to humanize
's round-N-review-result.md. That's an implicit ABI — humanize doesn't owe anyone stability on those paths, but extenders depend on them.
-
Decision merging is unspecified. If humanize's Codex hook returns {"decision":"block","reason":"..."} and a sibling plugin's hook does the same, what reaches Claude's next-turn context? Both? Last-write-wins? Wi
thout a defined merge policy, the only safe move for a sibling is to silently append findings to humanize's already-written review file and exit 0 — i.e. give up the block decision and trust humanize to relay the merged co
ntent.
-
No surface beyond Stop. Plan refinement, pre-round setup, convergence vote, post-round artifact contribution — none are extensible. A security plugin that wants to veto convergence has no clean way in. A planner-ext
ension that wants to add repo-specific context to gen-plan has no clean way in.
-
Recursion guards are per-plugin. Any hook that spawns claude --print … itself fires Stop hooks, inviting infinite recursion. Each plugin has to invent its own env-var dance to early-exit on re-entry.
-
No unified findings schema. Codex emits [P0-P9] severities, other reviewers emit their own (BLOCKING/SHOULD-FIX/NIT, error/warning, …). Merging them for a single repair turn is the sibling plugin's problem.
Proposed extension points
humanize would expose a small set of named extension points. Sibling plugins declare which they participate in via a manifest (e.g. .claude-plugin/humanize-extension.json or similar), which humanize discovers at loop sta
rt.
A non-exhaustive sketch:
reviewer — register an executable that receives {diff, round_metadata, loop_dir} and returns findings in a unified schema ({severity, message, file, line, suggested_fix?}). humanize merges all reviewers' findin
gs into a single round-N-review.md, decides block/convergence based on aggregated severity (with a configurable policy), and feeds the merged feedback to the next repair turn.
convergence-gate — per-round veto. Returns PASS/FAIL with reason. Loop cannot converge while any gate fails. Distinct from reviewer because the gate's job is yes/no, not finding production.
planner-extension — additional context/critique passes for gen-plan and refine-plan. Useful for repo-specific conventions, regulatory context, or interactive planning aids.
round-artifact — register additional artifacts to write into .humanize/rlcr/<ts>/ each round (with humanize owning the directory layout).
event-listener — pre-round, post-round, loop-start, loop-end. For plugins that observe but do not gate (e.g. metric collection, PR comment posting).
Each extension point has a defined input contract, output schema, and merge/composition policy owned by humanize. That gives sibling plugins a small, stable contract to implement and gives humanize a real ownership story f
or merged output.
What this would unlock
- For humanize: the RLCR loop becomes a platform. Reviewers, gates, planners, and context-gatherers can evolve independently in their own plugins without anyone forking humanize.
- For sibling plugins: small, stable contracts to implement; no reaching into humanize's internal paths; no decision-merge guesswork; recursion guards owned in one place.
- For the ecosystem: any team can ship a Claude Code plugin that extends the RLCR loop — security gates, lint reviewers, coverage gates, repo-specific personalities — without needing to coordinate with humanize maintai
ners.
Open questions / discussion
- Is there appetite for this on humanize's side, or is the preferred extension model "fork and customize"?
- If reviewer registration lands, what's the right merge policy default — strict (any BLOCKING blocks), majority vote, configurable per-loop?
- Should extension manifests live in the plugin manifest (
.claude-plugin/plugin.json) under a humanize key, or in a separate file? The former is discoverable via Claude Code's plugin metadata; the latter keeps humanize
-specific config out of the plugin manifest.
- For convergence gates and reviewers: should humanize expose a way for extenders to read/write loop state via an API, or do they continue to read
state.md directly (with a documented schema)?
Happy to discuss further or prototype any of these as a concrete validation case.
Summary
humanize is a great foundation for an iterative implement-review-iterate loop, and the natural next step is for other Claude Code plugins to extend it — adding reviewers, gates, context-gathering passes, or convergence
checks — without forking or reaching into humanize's filesystem layout.
Today, the only extension surface is Claude Code's plugin-level hook composition (Stop/PreToolUse/etc.). That works as a foothold but isn't a real extension API: there's no schema for what an extender produces, no ownershi
p of merged output, no defined behavior when two extenders both want to block, and no surface for non-Stop lifecycle moments. This issue proposes humanize expose its own extension points that sibling plugins register again
st at install time.
Motivating example: a panel of reviewers, not just Codex
The most immediate use case is letting a sibling plugin add additional reviewers alongside Codex on every round. Imagine a multi-personality reviewer with several distinct lenses — e.g. a test-completeness personality, a s
cope-discipline personality, an architecture personality, a performance personality, a naming personality. Each lens is most useful as a separate registration into a reviewer panel that humanize aggregates, not as a single
monolithic review.
This generalizes well beyond any one reviewer:
cargo clippy/eslint/pylintreviewer that emits findings in the same schema.If reviewer registration is first-class, all of these become drop-in plugins on equal footing with Codex.
Why hook composition isn't enough
A sibling plugin can register its own Stop hook today and have it fire alongside humanize's
loop-codex-stop-hook.shat the same event. Thisworks, but the seams show:
Sibling plugins must reach into humanize's filesystem layout. To produce per-round artifacts, an extender has to locate
.humanize/rlcr/<timestamp>/, parsestate.mdforcurrent_round, and write next to humanize's
round-N-review-result.md. That's an implicit ABI — humanize doesn't owe anyone stability on those paths, but extenders depend on them.Decision merging is unspecified. If humanize's Codex hook returns
{"decision":"block","reason":"..."}and a sibling plugin's hook does the same, what reaches Claude's next-turn context? Both? Last-write-wins? Without a defined merge policy, the only safe move for a sibling is to silently append findings to humanize's already-written review file and exit 0 — i.e. give up the block decision and trust humanize to relay the merged co
ntent.
No surface beyond Stop. Plan refinement, pre-round setup, convergence vote, post-round artifact contribution — none are extensible. A security plugin that wants to veto convergence has no clean way in. A planner-ext
ension that wants to add repo-specific context to gen-plan has no clean way in.
Recursion guards are per-plugin. Any hook that spawns
claude --print …itself fires Stop hooks, inviting infinite recursion. Each plugin has to invent its own env-var dance to early-exit on re-entry.No unified findings schema. Codex emits
[P0-P9]severities, other reviewers emit their own (BLOCKING/SHOULD-FIX/NIT, error/warning, …). Merging them for a single repair turn is the sibling plugin's problem.Proposed extension points
humanize would expose a small set of named extension points. Sibling plugins declare which they participate in via a manifest (e.g.
.claude-plugin/humanize-extension.jsonor similar), which humanize discovers at loop start.
A non-exhaustive sketch:
reviewer— register an executable that receives{diff, round_metadata, loop_dir}and returns findings in a unified schema ({severity, message, file, line, suggested_fix?}). humanize merges all reviewers' findings into a single
round-N-review.md, decides block/convergence based on aggregated severity (with a configurable policy), and feeds the merged feedback to the next repair turn.convergence-gate— per-round veto. Returns PASS/FAIL with reason. Loop cannot converge while any gate fails. Distinct fromreviewerbecause the gate's job is yes/no, not finding production.planner-extension— additional context/critique passes forgen-planandrefine-plan. Useful for repo-specific conventions, regulatory context, or interactive planning aids.round-artifact— register additional artifacts to write into.humanize/rlcr/<ts>/each round (with humanize owning the directory layout).event-listener— pre-round, post-round, loop-start, loop-end. For plugins that observe but do not gate (e.g. metric collection, PR comment posting).Each extension point has a defined input contract, output schema, and merge/composition policy owned by humanize. That gives sibling plugins a small, stable contract to implement and gives humanize a real ownership story f
or merged output.
What this would unlock
ners.
Open questions / discussion
.claude-plugin/plugin.json) under ahumanizekey, or in a separate file? The former is discoverable via Claude Code's plugin metadata; the latter keeps humanize-specific config out of the plugin manifest.
state.mddirectly (with a documented schema)?Happy to discuss further or prototype any of these as a concrete validation case.