Skip to content

Commit a8e7cf0

Browse files
sansariclaude
andauthored
feat(review): review_depth: lightweight annotation to skip preamble for low-risk steps (#411)
* feat(review): add review_depth: lightweight to suppress preamble for low-risk steps Adds a `review_depth: lightweight` annotation to review blocks in job.yml step outputs and .deepreview rules. When set, the workflow's common_job_info preamble (## Job Context) is omitted from review instruction files, reducing token overhead for trivial or reversible intermediate steps. Step inputs and review criteria are always included regardless of depth. - Parser: ReviewBlock gains review_depth field - Config: ReviewRule and ReviewTask carry review_depth through the pipeline - Matcher: review_depth threaded from rule to task for all three strategies - QualityGate: _build_preamble() conditionally omits Job Context when lightweight - Schemas: review_depth enum ["lightweight"] added to job.schema.json and deepreview_schema.json - Tests: 1299 passing, coverage at 98.07% Closes #86 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add changelog entry for review_depth: lightweight Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(review): clarify review_depth no-op in .deepreview and add string-output test - deepreview_schema.json: note that review_depth has no effect in .deepreview rules since they are not associated with a workflow and receive no common_job_info - test_quality_gate.py: add test for build_string_output_review_tasks with review_depth: lightweight to confirm common_job_info is suppressed on string outputs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * style: apply ruff formatting to quality_gate and test_quality_gate --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 0a3b168 commit a8e7cf0

10 files changed

Lines changed: 397 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- `review_depth: lightweight` annotation for review blocks in `job.yml` step outputs and `.deepreview` rules — when set, the workflow's `common_job_info` preamble is omitted from review instruction files, reducing token overhead for trivial or reversible intermediate steps (closes #86)
13+
1214
### Changed
1315

1416
### Fixed

src/deepwork/jobs/job.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@
120120
"description": "If true, includes matching files that were not produced as outputs but exist on disk. Useful for document freshness reviews where the reviewer needs to see the doc even when only source files changed."
121121
}
122122
}
123+
},
124+
"review_depth": {
125+
"type": "string",
126+
"enum": ["lightweight"],
127+
"description": "Optional review depth hint. When set to 'lightweight', the workflow's common_job_info preamble is omitted from the review instruction file, reducing token usage for low-risk or reversible intermediate steps. Step inputs and review criteria are always included. Omit this field for standard depth (default)."
123128
}
124129
}
125130
},

src/deepwork/jobs/mcp/quality_gate.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,23 @@ def _build_preamble(
9191
job: JobDefinition,
9292
workflow: Workflow,
9393
input_values: dict[str, ArgumentValue],
94+
review_depth: str | None = None,
9495
) -> str:
9596
"""Build the preamble prefixed to every dynamic review's instructions.
9697
9798
Combines workflow ``common_job_info`` and the rendered step inputs.
9899
Returns an empty string when neither is available.
100+
101+
When ``review_depth`` is ``"lightweight"``, the ``## Job Context`` block
102+
(common_job_info) is omitted to reduce token usage for low-risk steps.
103+
Step inputs are always included regardless of depth.
99104
"""
100105
input_context = _build_input_context(step, job, input_values)
101-
common_info = workflow.common_job_info or ""
102106
preamble_parts: list[str] = []
103-
if common_info:
104-
preamble_parts.append(f"## Job Context\n\n{common_info}")
107+
if review_depth != "lightweight":
108+
common_info = workflow.common_job_info or ""
109+
if common_info:
110+
preamble_parts.append(f"## Job Context\n\n{common_info}")
105111
if input_context:
106112
preamble_parts.append(input_context)
107113
return "\n\n".join(preamble_parts)
@@ -160,7 +166,6 @@ def build_dynamic_review_rules(
160166
targets.
161167
"""
162168
rules: list[ReviewRule] = []
163-
preamble = _build_preamble(step, job, workflow, input_values)
164169

165170
# Process each output
166171
for output_name, output_ref in step.outputs.items():
@@ -191,6 +196,9 @@ def build_dynamic_review_rules(
191196
file_paths = []
192197

193198
for i, review_block in enumerate(review_blocks):
199+
# Build preamble, respecting review_depth on this block
200+
preamble = _build_preamble(step, job, workflow, input_values, review_block.review_depth)
201+
194202
# Build full instructions with preamble
195203
full_instructions = (
196204
f"{preamble}\n\n{review_block.instructions}"
@@ -225,10 +233,11 @@ def build_dynamic_review_rules(
225233
source_dir=project_root,
226234
source_file=job.job_dir / "job.yml",
227235
source_line=0,
236+
review_depth=review_block.review_depth,
228237
)
229238
rules.append(rule)
230239

231-
# Process requirements review
240+
# Process requirements review — always uses standard preamble (no review_depth suppression)
232241
if step.process_requirements and work_summary is not None:
233242
attrs_list = "\n".join(
234243
f"- **{name}**: {statement}" for name, statement in step.process_requirements.items()
@@ -249,7 +258,8 @@ def build_dynamic_review_rules(
249258

250259
output_context = "\n".join(output_context_parts)
251260

252-
pqa_instructions = f"""{preamble}
261+
pqa_preamble = _build_preamble(step, job, workflow, input_values)
262+
pqa_instructions = f"""{pqa_preamble}
253263
254264
## Process Requirements Review
255265
@@ -315,7 +325,6 @@ def build_string_output_review_tasks(
315325
``_arg`` to distinguish it (matching the file_path rule naming).
316326
"""
317327
tasks: list[ReviewTask] = []
318-
preamble = _build_preamble(step, job, workflow, input_values)
319328

320329
try:
321330
source_rel = (job.job_dir / "job.yml").relative_to(project_root)
@@ -345,6 +354,7 @@ def build_string_output_review_tasks(
345354
inline_value = value if isinstance(value, str) else str(value)
346355

347356
for i, review_block in enumerate(review_blocks):
357+
preamble = _build_preamble(step, job, workflow, input_values, review_block.review_depth)
348358
full_instructions = (
349359
f"{preamble}\n\n{review_block.instructions}"
350360
if preamble
@@ -364,6 +374,7 @@ def build_string_output_review_tasks(
364374
agent_name=agent_name,
365375
source_location=source_location,
366376
inline_content=inline_value,
377+
review_depth=review_block.review_depth,
367378
)
368379
)
369380

src/deepwork/jobs/parser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class ReviewBlock:
2626
instructions: str
2727
agent: dict[str, str] | None = None
2828
additional_context: dict[str, bool] | None = None
29+
review_depth: str | None = None # "lightweight" | None (standard)
2930

3031
@classmethod
3132
def from_dict(cls, data: dict[str, Any]) -> "ReviewBlock":
@@ -35,6 +36,7 @@ def from_dict(cls, data: dict[str, Any]) -> "ReviewBlock":
3536
instructions=data["instructions"],
3637
agent=data.get("agent"),
3738
additional_context=data.get("additional_context"),
39+
review_depth=data.get("review_depth"),
3840
)
3941

4042

src/deepwork/review/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class ReviewRule:
4949
source_file: Path # Path to the .deepreview file
5050
source_line: int # Line number of the rule name in the .deepreview file
5151
reference_files: list[ReferenceFile] = field(default_factory=list)
52+
review_depth: str | None = None # "lightweight" | None (standard)
5253

5354

5455
@dataclass
@@ -65,6 +66,7 @@ class ReviewTask:
6566
precomputed_info_bash_command: str | None = None # Resolved command to run
6667
inline_content: str | None = None # Inline string value for type: string outputs
6768
reference_files: list[ReferenceFile] = field(default_factory=list)
69+
review_depth: str | None = None # "lightweight" | None (standard)
6870

6971

7072
def parse_deepreview_file(filepath: Path) -> list[ReviewRule]:
@@ -150,6 +152,8 @@ def _parse_rule(
150152

151153
reference_files = _parse_reference_files(review_data.get("reference_files", []), source_dir)
152154

155+
review_depth = review_data.get("review_depth")
156+
153157
return ReviewRule(
154158
name=name,
155159
description=description,
@@ -165,6 +169,7 @@ def _parse_rule(
165169
source_file=source_file,
166170
source_line=source_line,
167171
reference_files=reference_files,
172+
review_depth=review_depth,
168173
)
169174

170175

src/deepwork/review/matcher.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def match_files_to_rules(
246246
all_changed_filenames=all_filenames,
247247
precomputed_info_bash_command=precompute_cmd,
248248
reference_files=task_refs,
249+
review_depth=rule.review_depth,
249250
)
250251
)
251252

@@ -264,6 +265,7 @@ def match_files_to_rules(
264265
all_changed_filenames=all_filenames,
265266
precomputed_info_bash_command=precompute_cmd,
266267
reference_files=rule.reference_files,
268+
review_depth=rule.review_depth,
267269
)
268270
)
269271

@@ -278,6 +280,7 @@ def match_files_to_rules(
278280
all_changed_filenames=all_filenames,
279281
precomputed_info_bash_command=precompute_cmd,
280282
reference_files=rule.reference_files,
283+
review_depth=rule.review_depth,
281284
)
282285
)
283286

src/deepwork/schemas/deepreview_schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@
136136
"description": "If true, pulls the full contents of files that match the include patterns even if they weren't modified in this diff."
137137
}
138138
}
139+
},
140+
"review_depth": {
141+
"type": "string",
142+
"enum": ["lightweight"],
143+
"description": "Optional review depth hint. When set to 'lightweight' on a job.yml review block, the workflow's common_job_info preamble is omitted from the review instruction file, reducing token usage for low-risk or reversible intermediate steps. Note: this field has no effect in .deepreview rules — those rules are not associated with a workflow and do not receive common_job_info. Omit for standard depth (default)."
139144
}
140145
}
141146
}

0 commit comments

Comments
 (0)