Replace the current PreFlightStep "god step" with three single-purpose setup steps while keeping the rest of the grading pipeline behavior stable:
FileCheckStepfor required file validationAssetInjectionStepfor sandbox asset copy-inSetupCommandsStepfor setup/compilation command execution
Also add step categorization, allow templates to contribute setup requirements, and update every consumer that still assumes one monolithic PreFlightStep.
The current flow is:
LOAD_TEMPLATE -> BUILD_TREE -> SANDBOX -> PRE_FLIGHT -> AI_BATCH -> STRUCTURAL_ANALYSIS -> GRADE -> FOCUS -> FEEDBACK -> EXPORTER
Relevant code paths:
autograder/autograder.pybuilds the pipeline order.autograder/steps/step_registry.pydecides which steps are included.autograder/steps/pre_flight_step.pycurrently handles:- required file validation
- asset injection
- setup commands
autograder/services/pre_flight_service.pyresolves language-specific setup config and executes setup commands.autograder/serializers/pipeline_execution_serializer.pystill special-casesPRE_FLIGHT.autograder/utils/feedback_generator.pyandweb/service/grading_service.pystill look forPreFlightStep.
LOAD_TEMPLATE -> BUILD_TREE -> FILE_CHECK -> SANDBOX -> ASSET_INJECTION -> SETUP_COMMANDS -> AI_BATCH -> STRUCTURAL_ANALYSIS -> GRADE -> FOCUS -> FEEDBACK -> EXPORTER
Step inclusion rules:
| Step | Include when | Notes |
|---|---|---|
FileCheckStep |
merged required files are non-empty | Must run before sandbox allocation |
SandboxStep |
any template requires sandbox OR any merged setup assets/commands exist | Sandbox is needed for asset injection and setup commands |
AssetInjectionStep |
merged assets are non-empty | Runs only after sandbox exists |
SetupCommandsStep |
merged setup commands are non-empty | Runs only after sandbox exists |
Add a category/step_type attribute to Step and expose a shared enum:
| Category | Intended steps |
|---|---|
SETUP |
bootstrap, load template, build tree, file check, sandbox, asset injection, setup commands |
GRADING |
AI batch, structural analysis, grade, focus |
REPORTING |
feedback, exporter |
The category is primarily metadata, but it should be available on every step and registered centrally so later pipeline tooling can filter by phase.
Templates should be able to contribute setup requirements in addition to assignment-level setup_config.
The merged setup payload should:
- keep assignment
setup_configas the base - merge template-provided
required_files - merge template-provided
setup_commands - preserve assignment-level
assets - keep language-specific resolution behavior unchanged
Important: merge raw config before step construction, but keep language resolution inside the existing SetupConfig / PreFlightService flow so the runtime still picks the correct language block from the submission.
Files:
autograder/models/dataclass/step_result.pyautograder/models/abstract/step.pyautograder/steps/step_registry.py
Required changes:
- Add
StepCategoryenum withSETUP,GRADING,REPORTING. - Add a
categoryproperty toStep. - Update every existing step class to return a category.
- Teach
StepRegistryto build the new setup steps and to stop registeringPRE_FLIGHT.
Files to add:
autograder/steps/file_check_step.pyautograder/steps/asset_injection_step.pyautograder/steps/setup_commands_step.py
Behavior:
- Reads the merged required files for the current submission language.
- Fails fast before sandbox creation.
- Emits structured error data for missing files.
- Should reuse the existing file-check logic from
PreFlightServicerather than duplicating resolution rules.
- Requires an existing sandbox.
- Resolves assets with
AssetSourceResolver. - Injects resolved assets with
SandboxContainer.inject_assets(...). - Fails with a distinct structured error type for asset injection failures.
- Requires an existing sandbox.
- Runs commands sequentially.
- Stops on the first failing command.
- Reuses the current command execution/error formatting logic from
PreFlightServiceandSandboxService.
Files:
autograder/autograder.pyautograder/models/abstract/template.pyautograder/services/template_library_service.pyif template metadata is surfaced
Required changes:
- Add optional template-level setup requirement accessors to
Template. - Keep default behavior empty so existing templates do not need changes beyond the interface.
- Merge all template contributions into the assignment
setup_configbefore step construction. - If multiple templates contribute the same file or command, de-duplicate while preserving order.
Recommended merge rules:
- assignment config wins for shared structure
- template values are appended
- duplicates are removed
- empty values are ignored
Files:
autograder/serializers/pipeline_execution_serializer.pyautograder/utils/feedback_generator.pyweb/service/grading_service.py
Required changes:
- Stop special-casing
PreFlightSteponly. - Treat any of the three setup steps as preflight/setup failures.
- Update
failed_at_step, step messages, anderror_detailsmapping. - Replace the hard-coded
total_steps_planned = 7with a value derived from the actual registered steps. - Add category-aware success messages for:
FILE_CHECKASSET_INJECTIONSETUP_COMMANDS
Files:
autograder/steps/pre_flight_step.pyautograder/models/dataclass/step_result.py- docs under
autograder/docs/
Required changes:
PreFlightStepshould no longer be part of the pipeline.StepName.PRE_FLIGHTshould not be emitted by new runs.- Keep compatibility shims only if needed for imports or old tests, but new orchestration must use the split steps.
Keep the existing structured error approach, but extend it so the new steps are distinguishable.
Suggested mapping:
| Failure source | Structured type |
|---|---|
| missing required file | FILE_CHECK |
| asset copy failure | ASSET_INJECTION |
| setup command failure | SETUP_COMMAND |
| missing sandbox for setup work | SANDBOX_CREATION or a dedicated setup/sandbox type |
The serializer and feedback generator should read these types instead of parsing step names.
Update docs that currently describe PreFlightStep as a single stage:
autograder/docs/pipeline/04-pre-flight.mdautograder/docs/pipeline/README.mdautograder/docs/architecture/pipeline_execution_tracking.mdautograder/docs/architecture/core_structures.mdautograder/docs/features/setup_config_feature.mdautograder/docs/API.mdautograder/web/README.md
tests/unit/test_language_specific_setup_config.py- new tests for
FileCheckStep,AssetInjectionStep,SetupCommandsStep - serializer tests for the new setup step names and failure details
- feedback generation tests for all setup failure types
- pipeline builder tests that verify sandbox inclusion when assets/commands exist
- full local-sandbox pipeline test covering:
- assignment creation
- submission creation
- file check failure
- asset injection success
- setup command success/failure
- final submission result payload
- grading service tests updated for new setup step names
- submission result serialization tests updated for new pipeline summary shape
- Add step category metadata and new step names.
- Split
PreFlightStepinto the three setup steps. - Merge template-level setup requirements into the pipeline config.
- Update registry and pipeline ordering.
- Update serializer, feedback, and web service consumers.
- Refresh tests and docs.
After implementation, the code should still satisfy:
pytestpasses- local autograder API runs in local sandbox mode
- assignment creation and submission grading still work end-to-end
- pipeline logs show the new step breakdown
- submission result payloads expose the full execution trail, including step-by-step setup failures and command output