You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix: execute review: blocks on type: string step outputs (#350)
Previously, review: blocks declared on type: string outputs were silently
dropped because the review pipeline only matched ReviewRule patterns against
file paths. Authors got no warning and the review appeared correctly
configured. This was especially problematic given that the job_yml
DeepSchema directs authors toward type: string for transient inter-step data.
String outputs with review blocks now produce synthetic ReviewTask objects
with the value carried on a new ReviewTask.inline_content field. The value
is rendered into the instruction file as a "Content to Review" section and
mixed into the review_id content hash so each distinct value gets its own
pass-cache key (cache invalidates on value change, persists when unchanged).
Adds:
- ReviewTask.inline_content field
- build_string_output_review_tasks() in quality_gate, wired into run_quality_gate
- Shared _build_preamble() helper to deduplicate common_job_info+inputs logic
- Requirements: JOBS-REQ-004.8, REVIEW-REQ-005.1.8, REVIEW-REQ-009.1.7
- 18 new tests (unit + end-to-end via run_quality_gate)
Fixes#350
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: format inline-content review tasks as "inline content" (not "0 files")
Follow-up to the issue #350 string-output review fix. The formatter's
_task_name() used len(files_to_review) to describe task scope, which fell
through to the multi-file branch for inline-content tasks and produced
"review of 0 files" — cosmetic wart visible in the parallel-task listing.
Also adds a bespoke test_job (.deepwork/jobs/test_job/) that exercises the
full quality gate end-to-end with four outputs covering every review-level
combination: file_path + output-ref review, string + output-ref review
(NEW), string + arg-level review (NEW, inherited), and string + no review
(control). Used as a manual smoke test when verifying the fix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: apply ruff format to satisfy CI format check
CI runs `ruff format --check`, which my local `uv run ruff check` calls
did not exercise (check runs the linter, not the formatter). Two lines
I had manually broken up were re-joined by ruff format.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: split Makefile lint target into lint (check) and lint-fix (auto-fix)
Previously `make lint` ran `ruff format` and `ruff check --fix` — both in
auto-fix mode — so it silently mutated files instead of reporting issues.
CI, on the other hand, runs `ruff format --check` and `ruff check` in
check-only mode, which is what actually fails a PR. That asymmetry meant a
clean local `make lint` gave no guarantee that CI would pass: running it
would just reformat files in-place, and the developer might miss the
uncommitted changes.
Splits into two targets:
- `make lint` now mirrors CI (ruff format --check, ruff check, mypy).
A clean run guarantees the CI Lint job will pass.
- `make lint-fix` is the previous behavior (auto-fix formatter + linter)
for convenient local cleanup.
Caught while working on #350 — my local `ruff check` calls did not run the
formatter at all, and even `make lint` would have only silently reformatted
the files, leaving a surprise CI failure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
summary: "Exercise the DeepWork quality-gate review system with string and file_path outputs to verify string-output reviews run"
3
+
4
+
step_arguments:
5
+
- name: report_file
6
+
description: "A short markdown report file produced by the step — exercises the file_path review path."
7
+
type: file_path
8
+
9
+
- name: summary_text
10
+
description: "A 1-2 sentence narrative summary of the step's work — exercises a string output review defined at the step output-ref level."
11
+
type: string
12
+
13
+
- name: metrics_text
14
+
description: "A concise metrics blurb containing at least one numeric value — exercises a string output review defined at the step_argument level (inherited by any step that outputs it)."
15
+
type: string
16
+
review:
17
+
strategy: individual
18
+
instructions: |
19
+
Verify the value is a concise metrics summary of 1-3 sentences that contains at
20
+
least one numeric value. Flag it if the value is empty, a placeholder, or does
21
+
not mention any numbers.
22
+
23
+
- name: notes_text
24
+
description: "A freeform notes string with no review attached — control case that should produce no review task."
25
+
type: string
26
+
27
+
workflows:
28
+
test_review_system:
29
+
summary: "Produce four outputs of mixed types and review levels to verify the quality gate reviews them correctly."
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
25
25
### Fixed
26
26
27
27
- DeepSchema PostToolUse hook (`deepschema_write`) no longer reports `File is not valid JSON` for YAML files whose name has no extension (e.g. `.deepreview`). The hook now parses target files and the referenced JSON Schema as YAML, which is a superset of JSON, so both formats are accepted regardless of file extension. DW-REQ-011.7.3 updated to match. (Mirrors the fix shipped in #338 for the workflow quality gate.)
28
+
-`review:` blocks declared on `type: string` step outputs are now actually executed. Previously they were silently dropped because the review pipeline only matched against file paths, leaving authors with misconfigured-but-silent quality gates. String output reviews now produce synthetic `ReviewTask` objects with the string value carried on a new `ReviewTask.inline_content` field and rendered into the instruction file as a "Content to Review" section. New requirements: JOBS-REQ-004.8, REVIEW-REQ-005.1.8, REVIEW-REQ-009.1.7. (#350)
Copy file name to clipboardExpand all lines: specs/deepwork/jobs/JOBS-REQ-004-quality-review-system.md
+10-1Lines changed: 10 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ The quality review system evaluates step outputs against defined quality criteri
29
29
4. Each rule's `instructions` MUST be prefixed with a preamble containing workflow `common_job_info` and input context (if available).
30
30
5. Outputs with no review blocks MUST be skipped.
31
31
6. Outputs with `None` values MUST be skipped.
32
-
7. Only `file_path` type arguments with actual file paths MUST generate `ReviewRule` objects.
32
+
7. Only `file_path` type arguments with actual file paths MUST generate `ReviewRule` objects. Reviews declared on `type: string` outputs are handled separately per JOBS-REQ-004.8.
33
33
34
34
### JOBS-REQ-004.4: Process Requirements
35
35
@@ -64,3 +64,12 @@ The quality review system evaluates step outputs against defined quality criteri
64
64
3. For `string` inputs, values MUST be shown inline.
65
65
4. Inputs with no value MUST be shown as "not available".
66
66
5. If the step has no inputs, an empty string MUST be returned.
67
+
68
+
### JOBS-REQ-004.8: String Output Review Tasks
69
+
70
+
1. When a step output has `type: string` and a review block (either on the `StepOutputRef` or inherited from the `StepArgument`), `run_quality_gate()` MUST produce a synthetic `ReviewTask` whose content-to-review is the string value itself. Such reviews MUST NOT be silently ignored.
71
+
2. The synthetic task MUST bypass file-pattern matching; the string value MUST be carried on `ReviewTask.inline_content` so the reviewer agent sees it inlined in its instruction file (per REVIEW-REQ-005.1.8).
72
+
3. If a string output has reviews at both the `StepOutputRef` level and the `StepArgument` level, both MUST produce separate synthetic tasks, suffixed `_arg` for the argument-level task to match the file_path naming convention.
73
+
4. The synthetic task's instructions MUST be prefixed with the same preamble used for file-based reviews (workflow `common_job_info` and input context).
74
+
5. String outputs with `None` values MUST be skipped.
75
+
6. The synthetic task's `review_id` MUST incorporate the string value into its content hash so that distinct string values produce distinct cache keys (per REVIEW-REQ-009.1.7).
Copy file name to clipboardExpand all lines: specs/deepwork/review/REVIEW-REQ-005-instruction-generation.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,10 +11,11 @@ For each `ReviewTask`, the system generates a self-contained markdown instructio
11
11
1. Each instruction file MUST be a valid markdown document.
12
12
2. The file MUST begin with a heading identifying the review rule and scope (e.g., `# Review: python_file_best_practices — src/app.py`).
13
13
3. The file MUST contain a "Review Instructions" section with the rule's resolved instruction text.
14
-
4. The file MUST contain a "Files to Review" section listing the file paths to examine.
14
+
4. The file MUST contain a "Files to Review" section listing the file paths to examine when the task has at least one file to review. Inline-content tasks (see REVIEW-REQ-005.1.8) MUST NOT include a "Files to Review" section.
15
15
5. File paths in the "Files to Review" section MUST be relative to the repository root.
16
16
6. When the task has `additional_files` (unchanged matching files), the file MUST contain an "Unchanged Matching Files" section listing those file paths.
17
17
7. When the task has `all_changed_filenames`, the file MUST contain an "All Changed Files" section listing every changed filename for context.
18
+
8. When the task has `inline_content` set (used for `type: string` step outputs — see JOBS-REQ-004.8), the file MUST contain a "Content to Review" section whose body is the inline content verbatim. The review heading scope MUST read `inline content` when the task has `inline_content` and no `files_to_review`.
Copy file name to clipboardExpand all lines: specs/deepwork/review/REVIEW-REQ-009-review-pass-caching.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,6 +20,7 @@ The mechanism relies on a deterministic `review_id` that encodes the rule name,
20
20
4. The content hash MUST be the first 12 hex characters of the SHA-256 digest of the concatenated contents of all files to review, with files sorted alphabetically before concatenation.
21
21
5. Files that cannot be read MUST contribute the placeholder string `MISSING` instead of their contents.
22
22
6. The same inputs (rule name, file paths, file contents) MUST always produce the same `review_id`.
23
+
7. For inline-content tasks (where `files_to_review` is empty and `inline_content` is set — used for `type: string` step outputs per JOBS-REQ-004.8), the file paths component MUST be the literal `inline` and the content hash MUST be derived from the inline string value so that distinct string values produce distinct `review_id`s.
0 commit comments