Skip to content

Commit 84d3553

Browse files
nhortonclaude
andauthored
fix: remove redundant review rules and fix strategy/criteria mismatch (#348)
* fix: remove redundant review rules and fix strategy/criteria mismatch Several review cleanups driven by the observation that the `add_documentation_rules` step review was taking forever: - job.yml: change `add_documentation_rules` review from `strategy: individual` to `strategy: matches_together`. Two of its three criteria (Documentation Covered, Efficient Rule Count) are project-wide and cross-cutting, so running them per-file forced each reviewer to redo the full project scan N times. - job.yml: drop the `apply_rule` "Valid Configuration" criterion — the `deepreview` DeepSchema already enforces structural/schema validation via `json_schema_path`. - job.yml: collapse the duplicated rule-YAML blocks in `add_deepwork_native_reviews`. The step previously showed the same two rules twice (once as a file-ref reference example, once as the inline version to emit) and told the agent to consult both, creating a contradiction about which form to use. - Delete `src/deepwork/standard_jobs/deepwork_reviews/.deepreview` (`job_definition_review` rule): fully redundant with the `job_yml` DeepSchema which covers the same files and criteria. - Delete `job_schema_instruction_compatibility` from the top-level `.deepreview`: its whole purpose was verifying job.yml files conform to `job.schema.json`, which is exactly what the `job_yml` DeepSchema's `json_schema_path` already enforces. - Add `review-strategy-matches-criteria-scope` requirement to the `job_yml` DeepSchema so this class of bug is caught going forward: review `strategy: individual` must only be used when every criterion can be evaluated from a single file in isolation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add no-sentinel-files SHOULD requirement to job_yml DeepSchema Discourages the sentinel-placeholder-file workaround (e.g., writing a NONE.md file when the real result is "nothing to report") used to satisfy required file_path outputs that would otherwise be empty. The fix is to use type: string for outputs whose list can legitimately be empty, since string outputs can naturally carry a narrative "no items found" message. Kept as SHOULD so genuine filesystem-artifact needs (manifests, etc.) can still opt into a sentinel, but the common "required output can't be empty" workaround is explicitly not a sufficient reason. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: replace migrate_existing_skills sentinel file with empty list The step previously directed the agent to write a .deepwork/tmp/migrated_skills/NONE.md sentinel file as a workaround for "required file_path output can't be empty" — exactly the anti-pattern the new no-sentinel-files DeepSchema requirement added in a4dc74c prohibits. Verified the MCP validation accepts empty lists for required file_path outputs (no minimum-length check in src/deepwork/jobs/mcp/tools.py), so the sentinel workaround was never necessary. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: restore reference to example review prompt files The previous consolidation commit (1994f94) removed the duplicated rule-YAML blocks but also removed the pointers to plugins/claude/example_reviews/*.md, which contain the full detailed prompts that the inline YAML condenses. Those pointers are legitimately useful — they tell an agent writing condensed inline versions where to read for tone, intent, and checklist context. Restored as a "Reference material" section that clearly resolves the original inline-vs-file-based contradiction: always emit the inline form (target projects don't have the example files), and use the example files only as reference when deciding what the condensed inline text should say. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: soften review-strategy-matches-criteria-scope wording The previous wording forbade any cross-file reasoning from `strategy: individual`, which would disqualify legitimate cases like a Python code review rule where the reviewer may need to consult other project files (imports, references, related code, conventions) while evaluating a single changed file. Reworded so the distinction is about whether the reviewer needs to look at the OTHER CHANGED FILES in the same review set, not whether they need to look at any other file at all. Individual is appropriate when focus is heavily on each file and the reviewer is unlikely to need to see the other changed files; matches_together is for criteria that reason about the set as a whole (coverage, deduplication, consistency across the set). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use RFC 2119 keywords in review-strategy-matches-criteria-scope Restructured the requirement to use SHOULD/MAY/MUST NOT explicitly, matching the RFC 2119 style of the other requirements in this schema. The substantive guidance is unchanged: individual is preferred when focus is on each file and the reviewer is unlikely to need to see the other changed files (consulting unchanged project files is explicitly allowed as MAY); matches_together is preferred when changed files need to be looked at alongside each other; and individual is a hard MUST NOT when any criterion is a property of the set of changed files as a whole. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: broaden deepschema matchers to **/deepschema.yml The meta-DeepSchema governing deepschema files previously only matched .deepwork/schemas/*/deepschema.yml and **/.deepschema.*.yml, which missed the project's own standard schemas in src/deepwork/standard_schemas/ — they were exempt from the rules they define for users. Consolidated both hard-coded directory matchers into a single generic **/deepschema.yml pattern that: - Covers .deepwork/schemas/*/deepschema.yml (user-created named schemas) - Covers src/deepwork/standard_schemas/*/deepschema.yml (built-in schemas) - Covers any other location a user might put a deepschema.yml - Self-matches the meta-schema itself, which is fine — it conforms to its own requirements Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 267b03c commit 84d3553

5 files changed

Lines changed: 45 additions & 95 deletions

File tree

.deepreview

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -369,46 +369,6 @@ shell_code_review:
369369
section markers) still accurate after the changes? Flag any comments
370370
that describe behavior that no longer matches the code.
371371

372-
job_schema_instruction_compatibility:
373-
description: "Verify all standard and library job.yml definitions and templates are compatible with the job schema."
374-
match:
375-
include:
376-
- "src/deepwork/jobs/job.schema.json"
377-
- "src/deepwork/standard_jobs/*/job.yml"
378-
- "src/deepwork/standard_jobs/deepwork_jobs/templates/job.yml.*" # Templates users copy — must match schema
379-
- "library/jobs/*/job.yml"
380-
review:
381-
strategy: matches_together
382-
additional_context:
383-
unchanged_matching_files: true
384-
instructions: |
385-
When the job schema, standard job definitions, or library job definitions
386-
change, verify they are still compatible with each other.
387-
388-
Read src/deepwork/jobs/job.schema.json to understand the current schema.
389-
Then read each job.yml (standard and library) and check:
390-
391-
1. **Field references**: Every field name referenced in inline step
392-
instructions must exist in the schema at the correct level.
393-
Pay special attention to step_arguments vs workflow vs step fields.
394-
395-
2. **Required vs optional**: If instructions say a field is required,
396-
verify the schema agrees. If instructions say a field is optional,
397-
verify the schema doesn't require it.
398-
399-
3. **Schema structure**: Any YAML examples shown in inline instructions
400-
must match the schema's property names and nesting.
401-
402-
4. **Terminology consistency**: Instructions should use the same field
403-
names as the schema (e.g., if the schema uses
404-
"common_job_info_provided_to_all_steps_at_runtime", instructions
405-
should not call it "description" or "job_description").
406-
407-
Output Format:
408-
- PASS: All job definitions are compatible with the schema.
409-
- FAIL: Incompatibilities found. List each with the file path, line
410-
reference, the incompatible content, and what the schema actually says.
411-
412372
agents_md_claude_md_symlink:
413373
description: "Ensure every AGENTS.md file has a sibling CLAUDE.md symlink pointing to it, because Claude Code reads CLAUDE.md but ignores AGENTS.md."
414374
match:

src/deepwork/standard_jobs/deepwork_reviews/.deepreview

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/deepwork/standard_jobs/deepwork_reviews/job.yml

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -49,59 +49,25 @@ workflows:
4949
5050
Ensure the project's top-level `.deepreview` file contains the two built-in DeepWork review rules: `suggest_new_reviews` and `prompt_best_practices`. These are general-purpose rules that benefit any project using DeepWork Reviews.
5151
52-
## Task
53-
54-
### 1. Read the example review instruction files
52+
## Reference material
5553
56-
Read these files from the DeepWork plugin:
54+
The DeepWork plugin ships full, detailed versions of these two review prompts at:
5755
- `plugins/claude/example_reviews/prompt_best_practices.md`
5856
- `plugins/claude/example_reviews/suggest_new_reviews.md`
5957
60-
These are the full, detailed versions of the two review instruction prompts. Read them to understand the review's intent, checklist, and tone. The inline YAML rules in steps 3 and 4 below are condensed versions — use the example files to fill in any gaps or to judge whether the inline version captures the key points.
61-
62-
For reference, this is how the DeepWork project's own `.deepreview` configures these two rules (using `instructions: { file: ... }` to point at the example files above):
63-
64-
```yaml
65-
prompt_best_practices:
66-
description: "Review prompt/instruction markdown files for Anthropic prompt engineering best practices."
67-
match:
68-
include:
69-
- "**/CLAUDE.md"
70-
- "**/AGENTS.md"
71-
- ".claude/**/*.md"
72-
- ".deepwork/review/*.md"
73-
- ".deepwork/jobs/**/*.md"
74-
review:
75-
strategy: individual
76-
instructions:
77-
file: .deepwork/review/prompt_best_practices.md
78-
79-
suggest_new_reviews:
80-
description: "Analyze all changes and suggest new review rules that would catch issues going forward."
81-
match:
82-
include:
83-
- "**/*"
84-
exclude:
85-
- ".github/**"
86-
review:
87-
strategy: matches_together
88-
instructions:
89-
file: .deepwork/review/suggest_new_reviews.md
90-
```
91-
92-
When creating rules for the target project, adapt the `match.include` patterns to its structure. The inline YAML in steps 3 and 4 uses inline `instructions:` text (suitable for projects that don't have the external instruction files), while the above uses `instructions: { file: ... }` references.
58+
Read these for context on each review's intent, checklist, and tone. The inline YAML rules in steps 2 and 3 below are condensed versions suitable for emitting into the target project's `.deepreview` file — always emit the inline form (not `instructions: { file: ... }`), since target projects don't have the example files. Use the example files only as reference when deciding what the condensed inline text should say.
9359
94-
If the example files are not found (e.g., the plugin is installed differently), proceed using the inline YAML in steps 3 and 4 below.
60+
## Task
9561
96-
### 2. Check the existing `.deepreview` file
62+
### 1. Check the existing `.deepreview` file
9763
9864
Read the top-level `.deepreview` file if it exists. Check whether `suggest_new_reviews` and/or `prompt_best_practices` rules are already present.
9965
10066
- If both rules already exist with reasonable configurations, skip to the output step — no changes needed.
10167
- If one or both are missing, proceed to add the missing rule(s).
10268
- If a rule exists but has a substantially different configuration (wrong strategy, missing match patterns), update it to match the specification below.
10369
104-
### 3. Add the `prompt_best_practices` rule (if not present)
70+
### 2. Add the `prompt_best_practices` rule (if not present)
10571
10672
Add to `.deepreview`:
10773
@@ -144,7 +110,7 @@ workflows:
144110
145111
Adapt the `match.include` patterns to the project if needed. Check for directories containing `.md` files that appear to be AI instruction files (e.g., `.gemini/`, `.cursorrules`, custom agent directories). If found, add those patterns too. You may add both missing rules in a single edit to the `.deepreview` file. The patterns above are the baseline.
146112
147-
### 4. Add the `suggest_new_reviews` rule (if not present)
113+
### 3. Add the `suggest_new_reviews` rule (if not present)
148114
149115
Add to `.deepreview`:
150116
@@ -175,7 +141,7 @@ workflows:
175141
5. If no rules are warranted, say so. An empty suggestion list is valid.
176142
```
177143
178-
### 5. Validate
144+
### 4. Validate
179145
180146
Ensure the `.deepreview` file is valid YAML. Ensure both rules have all required fields: `description`, `match.include`, `review.strategy`, `review.instructions`.
181147
@@ -267,7 +233,7 @@ workflows:
267233
268234
### migrated_skill_backups
269235
270-
All backup copies of deleted skills in `.deepwork/tmp/migrated_skills/`. If no skills were migrated, this output should contain a single file `.deepwork/tmp/migrated_skills/NONE.md` stating that no review-like skills were found.
236+
All backup copies of deleted skills in `.deepwork/tmp/migrated_skills/`. If no skills were migrated, this output should be an empty list.
271237
272238
inputs: {}
273239
outputs:
@@ -347,14 +313,12 @@ workflows:
347313
deepreview_files:
348314
required: true
349315
review:
350-
strategy: individual
316+
strategy: matches_together
351317
instructions: |
352-
Read each .deepreview file and the documentation files its rules protect.
353-
Verify that the trigger scope of each rule is as narrow as possible —
354-
it should only fire when files that could actually affect the doc's accuracy
355-
change. Consider whether having more separate reviews with narrower scope
356-
is actually more efficient than a slightly wider, shared review — each
357-
review spawns a sub-agent with material overhead.
318+
Read all .deepreview files together along with the documentation files their
319+
rules protect. The criteria below are cross-cutting — Documentation Covered
320+
and Efficient Rule Count require a project-wide view of all rules at once,
321+
which is why this review runs once over the full set rather than per file.
358322
359323
Evaluate the output against these criteria:
360324
- Documentation Covered: Every project documentation file that describes the project itself has a corresponding rule (either newly created or pre-existing).
@@ -905,10 +869,8 @@ workflows:
905869
instructions: |
906870
Read the dependency analysis from the previous step to verify the rule
907871
faithfully implements the approved plan. Read the documentation file
908-
referenced in the rule's instructions. Check the .deepreview file for
909-
valid YAML syntax and consistency with existing rules.
872+
referenced in the rule's instructions.
910873
911874
Evaluate the output against these criteria:
912875
- Faithful Implementation: The rule accurately implements the dependency analysis from the previous step — same match patterns, same strategy, same rule name convention.
913-
- Valid Configuration: The .deepreview YAML is syntactically valid and follows the schema. All required fields (description, match.include, review.strategy, review.instructions) are present.
914876
- Effective Instructions: Review instructions clearly tell the reviewer to check whether the documentation file is still accurate given the source file changes. The documentation file path is explicitly referenced. Uses additional_context.unchanged_matching_files: true so the reviewer can read the doc even when only source files changed.

src/deepwork/standard_schemas/deepschema/deepschema.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ instructions: |
88
99
1010
matchers:
11-
- ".deepwork/schemas/*/deepschema.yml"
11+
- "**/deepschema.yml"
1212
- "**/.deepschema.*.yml"
1313

1414
json_schema_path: "deepschema_schema.json"

src/deepwork/standard_schemas/job_yml/deepschema.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ requirements:
7676
auto-pass rather than fail. Avoid criteria that penalize steps for not doing things
7777
outside their scope.
7878
79+
review-strategy-matches-criteria-scope: >
80+
The review `strategy` SHOULD match whether the criteria need to reason across the
81+
other changed files in the same review set. `strategy: individual` SHOULD be used
82+
when the focus is on each file itself and the reviewer is unlikely to need to see
83+
the other changed files in order to evaluate this one. A reviewer operating under
84+
`individual` MAY consult unchanged project files for context (imports, references,
85+
related code, conventions); such consultation does NOT require switching to
86+
`matches_together`. `strategy: matches_together` SHOULD be used when the changed
87+
files are likely to need to be looked at alongside each other during review.
88+
`strategy: individual` MUST NOT be used when any criterion is a property of the
89+
set of changed files as a whole (e.g., coverage across the set, deduplication of
90+
the set, cross-file consistency, set-level minimality), because it forces each
91+
spawned reviewer to redo the cross-file scan N times and multiplies latency
92+
without improving review quality.
93+
7994
review-no-redundant-context: >
8095
Review `instructions` MUST NOT repeat domain context already in `common_job_info` since
8196
the framework automatically prepends it to review prompts.
@@ -129,6 +144,20 @@ requirements:
129144
that are too large for inline strings. The existence of a `.deepwork/tmp/` path
130145
in a step_argument name is a strong signal the argument should be `type: string`.
131146
147+
no-sentinel-files: >
148+
Steps SHOULD NOT use sentinel placeholder files (e.g., writing a `NONE.md` or
149+
`EMPTY.md` file to satisfy a required `file_path` output when the real result is
150+
"nothing to report") to work around the rule that `file_path` outputs cannot be
151+
empty. If a step's output is a list that can legitimately be empty, the output
152+
SHOULD be `type: string` (containing a narrative summary that naturally handles
153+
the empty case) rather than `type: file_path` with a placeholder file. Sentinel
154+
files leave stray artifacts on disk, confuse downstream steps that treat every
155+
output path as a real file, and mislead reviewers. Exception: a sentinel file
156+
MAY be used when the step genuinely needs a filesystem artifact a later step
157+
will read and parse (e.g., a manifest with "no items" semantics baked into its
158+
schema) — but the common "required output can't be empty" workaround is not a
159+
sufficient reason.
160+
132161
step-visibility-boundary: >
133162
A step's instructions MUST NOT reference information from steps that have not yet
134163
run in the same workflow, including steps from other workflows in the same job.

0 commit comments

Comments
 (0)