fix(ce-simplify-code): stop entrenching constructs that shouldn't exist - #1
fix(ce-simplify-code): stop entrenching constructs that shouldn't exist#1chreho wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4fbbe37f13
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Wait for all three agents to complete. Aggregate their findings and fix each issue directly. If a finding is a false positive or not worth addressing, note it and move on. Do not argue with the finding or raise questions to the user, just skip it. | ||
|
|
||
| Before applying each fix, confirm it preserves behavior: same output for every input, same error behavior, and same side effects and ordering. If a fix can't clear that test, skip it — automated checks in Step 4 don't cover every behavior. | ||
| **Synthesis before fixing.** Before applying anything, look across the aggregated findings for clustering: if two or more findings touch the same construct (the same helper, field list, mapping table, wrapper, config constant) — including one reviewer *clearing* it while another proposes cleanup around it — treat the cluster as a signal that the construct itself may be the issue. Run the necessity question on it first: can it be derived from an existing source of truth, or does the platform/framework/downstream layer already provide its guarantee? Do not apply pattern-level fixes (merging duplicates, optimizing around it) that would entrench a construct whose necessity is unresolved; resolve necessity first, and if the answer is "shouldn't exist," report that as a design-level finding instead. |
There was a problem hiding this comment.
Make cleared constructs visible to synthesis
The synthesis rule depends on detecting when one reviewer clears a construct while another proposes cleanup around it, but the reviewers are only instructed to return findings or say there is nothing to flag, so this state is not present in the aggregated findings. In that scenario the orchestrator cannot form the intended cluster and may still apply the cleanup/merge that entrenches the construct; require reviewers to emit explicit clears for suspicious constructs or remove this case from the synthesis trigger.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in f2afac5. Both personas' return format now carries an explicit clear/question channel: findings may be question findings (no concrete fix required), and a nothing-to-flag report must briefly note suspicious constructs considered-and-cleared with the reason. The synthesis trigger's clears clause now references data the reviewers actually emit.
The three reviewers operate inside the author's design: reuse hunts importable code, quality hunts patterns, efficiency hunts wasted work. None asks whether a new construct needs to exist at all. On a diff that introduces a hand-maintained mirror of another artifact (a field list copying a schema the serving layer already projects to), the pass merges and optimizes around the construct — entrenching it — instead of surfacing that it may be removable. Close the gap at the owning layers, no new persona or dispatch: - reuse persona: platform/framework/downstream-layer guarantees count as existing functionality; report removal findings with the internal-boundary tradeoff stated - quality persona: for copy-paste, check elimination before proposing a merge; do not clear a suspicious construct by inferring intent — unverified justification is a question finding - SKILL.md Step 3: cluster findings on one construct trigger the necessity question before pattern-level fixes; behavior preservation judged at the observable contract boundary; design-level findings are reported with tradeoffs, never auto-applied - SKILL.md Step 5 + docs page: design-level findings lead the summary
4fbbe37 to
ff05a67
Compare
…estrator Review feedback on the necessity-lens change: - Both personas' return format now accommodates question findings (no concrete fix required) and asks for a brief note of suspicious constructs considered-and-cleared — the synthesis trigger's clears clause previously referenced data the format never carried. - Step 3: clearing the contract-boundary test is necessary but not sufficient; construct-removal/restructure fixes route to the design-level channel regardless of proof. Removes the contradiction with the report-don't-apply rule on the motivating case.
…t only on empty reports The considered-and-cleared note was contractually tied to the nothing-to-flag branch, so a reviewer with mixed output (findings plus a clear on a different construct) was never asked to emit the clear — starving the Step 3 synthesis trigger of exactly the clear-around signal it clusters on. The note is now unconditional.
Summary
ce-simplify-codecan converge on a local optimum at the expense of the global one. Each reviewer evaluates the diff as structured and proposes the best cleanup of that structure — deduplicate these blocks, optimize this call — without ever asking whether the structure itself is the problem. When the highest-value simplification is "this construct shouldn't exist" (it can be derived from a source of truth, or a downstream layer already provides its guarantee), pattern-level polish doesn't just miss that answer — it actively moves the code away from it: every merge and micro-optimization built around the construct adds inertia, making the better architecture more expensive to reach later.The three reviewers each operate inside the author's design: reuse hunts importable code, quality hunts patterns, efficiency hunts wasted work. None of them asks whether a construct the diff introduces needs to exist at all. When a diff introduces a hand-maintained mirror of another artifact — the motivating case was a field allowlist copying a GraphQL schema whose serving layer already projects responses to the selection set — the pass does the opposite of simplifying: the quality reviewer merges the duplicated serializers around the list, the efficiency reviewer optimizes
model_dump(include=...)against it, and the construct comes out more entrenched than before. The reviewer that looked straight at it cleared it by inferring intent ("deliberate public-API allowlist") without verifying that the downstream layer already enforced the same boundary. On the planted-issue eval below, the baseline pass produces zero necessity findings and two entrenchment fixes; the construct's drift risk (schema gains a field → API silently returns nothing for it) ships unflagged.This PR gives the pass a way to notice the global option and surface it rather than silently optimize past it — as rubric lines in the two relevant personas plus a synthesis rule in Step 3. No new persona, no new dispatch.
What changed
code-reuse-reviewer.md— new rubric item 5: guarantees provided by the platform/framework/downstream layer count as "existing functionality" (gateway/GraphQL projection, serializer field enumeration, framework validation). Findings whose removal preserves the external contract but changes internal-boundary shape must be reported with that tradeoff stated, not silently fixed and not silently dropped.code-quality-reviewer.md— rule 3 (copy-paste) now checks elimination before proposing a merge (consolidating an unnecessary thing entrenches it); new guard: do not clear a suspicious construct by inferring intent — an unverified justification is a question finding, and a hand-maintained list mirroring another artifact is a standing red flag.SKILL.mdStep 3 — synthesis before fixing: when ≥2 findings touch one construct (including one reviewer clearing it while another cleans up around it), resolve the necessity question before applying pattern-level fixes that would entrench it. Behavior preservation is judged at the observable contract boundary, with explicit proof required when internal shape changes. Design-level "shouldn't exist" findings are reported with tradeoffs both ways, never auto-applied — they trade on judgment the user owns (payload limits, defense-in-depth, future consumers).SKILL.mdStep 5 +docs/skills/ce-simplify-code.md— design-level findings lead the summary instead of being buried under applied polish.Design decisions
ce-work/lfg. Closing the gap at its owning layers keeps reviewer count and dispatch cost unchanged.Eval evidence
Planted-issue fixture, A/B: synthetic Python/graphql-core repo ("library catalog"). One diff plants: (P1) hand-maintained schema-mirroring field tuples where the executor provably projects; (P2) copy-paste serializers; (P3) a false-positive trap — a hand-rolled JSON coercer where
model_dump(mode="json")is NOT behavior-equivalent (Decimal→str, tz datetime→Zsuffix). Seven Sonnet runs, identical scope prompts, only the persona/orchestration text varies. Rows 5–6 re-run the amended personas at this PR's final text (after review-round fixes); row 7 is an end-to-end integration run — both amended reviewers' verbatim outputs fed through the amended Step 3 synthesis and Step 5 summary.Z/+00:00divergence)str(), space notT, so the hand-rolled.isoformat()is load-bearing)Necessity detection: 0/2 baseline → 2/2 amended → 2/2 at final text. False-positive guard: 7/7. No regression on legitimate findings — the amended runs each also produced a valid extra finding the baselines missed. The integration row is the sharpest evidence for the Step 3 wording: on this input the pre-review text licensed auto-applying the removal (both reviewers had proof), and the pre-PR baseline applied the entrenching merge; the final text routes the decision to the user and applies nothing. Re-runs used a fixture copy with the results file removed (answer-key contamination guard; the original four runs predated that file).
Fixture repo (files, planted diff, run matrix, and a base64 tarball of the full two-commit history): https://gist.github.com/chreho/56e057603e912253ecbec3d1ba8aba86
Validation
npx --yes bun@1.2.20 test --timeout 30000(2,030 passed, 0 failed, 76 files)npx --yes bun@1.2.20 run release:validate(metadata in sync: 0 agents, 30 skills, 0 MCP servers)git diff --check(clean)claude plugin validateon both manifests: pass (local CLI 2.1.110 predates--strict; the diff touches only skill/docs markdown, no manifests, so CI's strict pass is expected unchanged)