docs: dev note for workflow chaining#775
Conversation
|
Fern preview: https://nvidia-preview-pr-775.docs.buildwithfern.com/nemo/datadesigner
|
|
|
||
| In that shape, `quality_gate` is both a normal stage and a contract. Upstream work promises a schema. Downstream work consumes that schema. A reviewer, evaluator, dashboard, or cleanup script only has to preserve the contract. | ||
|
|
||
|  |
There was a problem hiding this comment.
This is GitHub's rendered diff resolving Fern's root-relative /assets/... path against github.com. The tracked image is valid and renders in the Fern preview, so I kept the established Fern asset path.
Signed-off-by: Andre Manoel <amanoel@nvidia.com>
Greptile SummaryThis PR adds a "Pause, Inspect, Resume" developer note and a headless document review gate recipe that demonstrates workflow chaining as a control surface. It also moves
|
| Filename | Overview |
|---|---|
| docs/assets/recipes/workflow_chaining/document_review_gate.py | 825-line recipe implementing the workflow-chaining review gate pattern; one concrete validation gap: --review-pages accepts non-positive integers via plain type=int while the downstream Pydantic model enforces ge=1, causing a confusing crash instead of a clean CLI error. |
| packages/data-designer-config/src/data_designer/config/run_config.py | Adds ResumeMode StrEnum (NEVER, ALWAYS, IF_POSSIBLE) to the config package; clean move from artifact_storage.py. |
| packages/data-designer-config/src/data_designer/config/init.py | Exports ResumeMode via the lazy-import registry and TYPE_CHECKING block; consistent with the existing pattern for other config types. |
| packages/data-designer-engine/src/data_designer/engine/storage/artifact_storage.py | Removes the local ResumeMode definition and replaces it with an import from data_designer.config.run_config; no logic changes. |
| packages/data-designer/src/data_designer/interface/init.py | Updates TYPE_CHECKING import and lazy-import entry for ResumeMode to point to the new canonical location in run_config. |
| packages/data-designer/tests/docs/test_document_review_gate_recipe.py | Comprehensive integration tests covering page generation, metadata schema, box bounds, review artifact writing, end-to-end recipe output, overwrite guard, and CLI rejection of non-positive --num-records; --review-pages validation gap is not yet covered. |
| packages/data-designer-config/tests/config/test_run_config.py | Adds one test asserting dd.ResumeMode is ResumeMode, verifying the public re-export is wired correctly. |
| fern/versions/latest.yml | Adds Workflow Chaining recipe section and Pause, Inspect, Resume devnote to the Fern navigation; no structural issues. |
| fern/versions/latest/pages/devnotes/posts/annotate-hard-pages-review-gates.mdx | 241-line devnote explaining workflow chaining as a control surface with diagrams, comparison tables, and inline code snippets; technically accurate relative to the recipe. |
| fern/versions/latest/pages/recipes/workflow_chaining/document_review_gate.mdx | Recipe page with run instructions and a minimal code excerpt illustrating the pause/resume boundary; content matches the actual recipe script. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant CLI as CLI / main()
participant RR as run_recipe()
participant RS as run_to_review_stage()
participant BW as build_workflow()
participant WF as workflow.run()
participant WS as write_simulated_review_artifact()
participant RF as resume_from_reviewed()
CLI->>RR: count, seed, review_pages, overwrite
RR->>RS: count, seed, review_pages
RS->>BW: build stages (document_pages → review_candidates)
BW->>WF: "targets=review_candidates"
WF-->>RS: WorkflowResults
RS->>RS: results.export_stage(review_candidates, path)
RS-->>RR: review_path
RR->>WS: base_dir
WS->>WS: read review_candidates parquet
WS->>WS: fill human_boxes for selected rows
WS-->>RR: reviewed_path
RR->>RF: count, seed, review_pages
RF->>BW: rebuild stages (same params)
BW->>WF: "resume=ALWAYS, stage_output_overrides"
WF-->>RF: WorkflowResults
RF->>RF: results.export_stage(final_dataset, path)
RF-->>RR: final_path
RR-->>CLI: final_path
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant CLI as CLI / main()
participant RR as run_recipe()
participant RS as run_to_review_stage()
participant BW as build_workflow()
participant WF as workflow.run()
participant WS as write_simulated_review_artifact()
participant RF as resume_from_reviewed()
CLI->>RR: count, seed, review_pages, overwrite
RR->>RS: count, seed, review_pages
RS->>BW: build stages (document_pages → review_candidates)
BW->>WF: "targets=review_candidates"
WF-->>RS: WorkflowResults
RS->>RS: results.export_stage(review_candidates, path)
RS-->>RR: review_path
RR->>WS: base_dir
WS->>WS: read review_candidates parquet
WS->>WS: fill human_boxes for selected rows
WS-->>RR: reviewed_path
RR->>RF: count, seed, review_pages
RF->>BW: rebuild stages (same params)
BW->>WF: "resume=ALWAYS, stage_output_overrides"
WF-->>RF: WorkflowResults
RF->>RF: results.export_stage(final_dataset, path)
RF-->>RR: final_path
RR-->>CLI: final_path
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
docs/assets/recipes/workflow_chaining/document_review_gate.py:807
`--review-pages` uses plain `type=int`, so `--review-pages 0` or `--review-pages -1` passes argparse validation and reaches `_review_candidates_builder(review_pages)`, which immediately instantiates `ReviewSelectionParams(max_review_pages=0)`. Pydantic rejects that value because of `ge=1`, producing a cryptic `ValidationError` instead of the clean exit-code-2 CLI error the codebase already enforces for `--num-records`.
```suggestion
parser.add_argument("--review-pages", type=_positive_int, default=3)
```
Reviews (5): Last reviewed commit: "Merge branch 'main' into andreatgretel/d..." | Re-trigger Greptile
|
Thanks for putting this together, @andreatgretel — this is a genuinely nice dev note, and the runnable recipe makes the workflow-chaining story concrete. SummaryThis is a docs + recipe PR: it adds the "Pause, Inspect, Resume" dev note, a headless FindingsSuggestions — Take it or leave it
What Looks Good
Notes
Structural Impact (graphify, 2.4s)Risk: LOW (localized change)
This confirms a localized, additive change with no god-node or cross-package blast radius — consistent with a docs + standalone-recipe PR that imports the public API surface without modifying it. VerdictShip it (with nits) — Only optional suggestions above; nothing blocking. Worth a quick reply to the two existing inline comments before merge, but the change itself is in good shape. This review was generated by an AI assistant. |
Signed-off-by: Andre Manoel <amanoel@nvidia.com>
|
Addressed the remaining actionable bot feedback:
Validation: 294 tests passed, Ruff passed, and Fern reported 0 errors with 1 existing warning. |
Signed-off-by: Andre Manoel <amanoel@nvidia.com>
|
Following up on the workflow-chaining snippets — one small readability suggestion on the opening example. Not blocking, take it or leave it.
|
nabinchha
left a comment
There was a problem hiding this comment.
Approving — nice work on this one. The dev note is well-written and the runnable recipe backs the story up. I verified the workflow-chaining API in the snippets against the source (compose_workflow, add_stage, run(targets=/resume=/stage_output_overrides=), export_stage, dd.ResumeMode, dd.SkipConfig(when=...)) and ran the recipe tests — all 10 pass against the branch. The ResumeMode move into data_designer.config is a clean, correctly-layered refactor (single definition, engine imports from config, interface re-exports).
My comments above (snippet readability, and the earlier notes on unused image assets + the now-stale "docs only" line in the PR description) are all non-blocking — feel free to take or leave them.
|
@nabinchha thanks! Addressed your comments above. |
| parser.add_argument("--artifact-path", type=Path, default=DEFAULT_ARTIFACT_DIR) | ||
| parser.add_argument("--dataset-name", default="document_review_gate") | ||
| parser.add_argument("--seed", type=int, default=11) | ||
| parser.add_argument("--review-pages", type=int, default=3) |
There was a problem hiding this comment.
--review-pages uses plain type=int, so --review-pages 0 or --review-pages -1 passes argparse validation and reaches _review_candidates_builder(review_pages), which immediately instantiates ReviewSelectionParams(max_review_pages=0). Pydantic rejects that value because of ge=1, producing a cryptic ValidationError instead of the clean exit-code-2 CLI error the codebase already enforces for --num-records.
| parser.add_argument("--review-pages", type=int, default=3) | |
| parser.add_argument("--review-pages", type=_positive_int, default=3) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/assets/recipes/workflow_chaining/document_review_gate.py
Line: 807
Comment:
`--review-pages` uses plain `type=int`, so `--review-pages 0` or `--review-pages -1` passes argparse validation and reaches `_review_candidates_builder(review_pages)`, which immediately instantiates `ReviewSelectionParams(max_review_pages=0)`. Pydantic rejects that value because of `ge=1`, producing a cryptic `ValidationError` instead of the clean exit-code-2 CLI error the codebase already enforces for `--num-records`.
```suggestion
parser.add_argument("--review-pages", type=_positive_int, default=3)
```
How can I resolve this? If you propose a fix, please make it concise.
📋 Summary
Adds a dev note and runnable recipe for workflow chaining as a pause/inspect/resume control surface. The post focuses on what named stage boundaries enable, including human review, reusable intermediate artifacts, downstream resume, and future workflow shapes.
🔗 Related Issue
N/A
🔄 Changes
review_candidates, writes a reviewed artifact, and resumes downstream from that artifact.🧪 Testing
.venv/bin/ruff check ..venv/bin/ruff format --check ..venv/bin/pytest packages/data-designer/tests/docs/test_document_review_gate_recipe.pyenv npm_config_cache=/private/tmp/npm-cache-datadesigner make check-fern-docs(0 errors, 1 existing Fern warning)✅ Checklist