Repository navigation
feat: archived_file output binding for composite model runs - #404
Merged
Merged
Conversation
Nullable modelcatalog_configuration_output.archived_file (migration
1771300000038) names the archived file a declared output is in that
configuration: a file name, an fnmatch glob, or a {param:<parameter id>}
reference. Exposed as hasOutput[].archivedFile through the catalog API
(junction column, field maps, OpenAPI) and readable by the anonymous role
like app_input_name.
/workflows/submit accepts model_task.output_file (422
MODEL_OUTPUT_FILE_INVALID on a value outside the archive-root whitelist,
a tapisjob* name or an unresolved {param:} reference). The model task
pages the job archive listing, drops directories and tapisjob* files, and
selects the bound file literally or by glob without falling back to the
label: zero matches is the new MODEL_OUTPUT_MISSING (with same-extension
candidates and a re-register hint), several is MODEL_OUTPUT_AMBIGUOUS.
Unbound outputs keep the name/extension rule. The result manifest records
output_file and selected_by.
…e bridge; order outputs by position
buildCompositeWorkflowModelTask resolves the catalog output's archived_file
({param:<id>} references take the seed execution's parameter value, else the
parameter default; 422 MODEL_OUTPUT_FILE_UNRESOLVED when that fails the
archive-root rules) and the composite submit sends it as
model_task.output_file. A configuration's inputs and outputs are sorted by
position (ties by id) when the Model is built, so the default output of a
run is the first declared one rather than database row order.
A {param:<id>} reference must be the whole value (the EM rejects a malformed
or embedded one as MODEL_OUTPUT_FILE_UNRESOLVED). The model task pages the
archive listing until an empty page rather than a short one, since Tapis may
cap limit below the requested size; truncated now means five non-empty pages.
MODEL_OUTPUT_MISSING lists same-extension candidates for literal bindings
only. Test harnesses answer skip>0 with an empty page; golden regenerated.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Composite model runs (Ensemble Manager -> SVO adapter -> Tapis job) picked the model output file by the catalog output's label. With three GeoTIFFs in the WERC archive that failed
MODEL_OUTPUT_AMBIGUOUSon the first OPERA job to finish on ls6 (ue_3a5901b2, 2026-11-06). A second bug on the same path: a configuration's outputs were never ordered by position, so the default "first output" was database row order (runue_63132569got "Reference anchor JSON").This is the output-side mirror of the app-input binding (#390-era,
app_input_name). Design:docs/design/2026-11-07-output-file-binding.md(approved rev 2; architect, skeptic and QA reviews recorded under Decisions).modelcatalog_configuration_output.archived_file(migration1771300000038): a file name, an fnmatch glob, or{param:<parameter id>}. Exposed ashasOutput[].archivedFile(junction column on the three resource types, field maps, OpenAPI);userinsert/select andanonymousselect, likeapp_input_name.position(ties by id) when the Model is built.buildCompositeWorkflowModelTaskresolves the binding ({param:…}takes the seed execution's parameter value, else the default; 422MODEL_OUTPUT_FILE_UNRESOLVEDwhen it cannot) and the composite submit sendsmodel_task.output_file.output_uriunchanged./workflows/submitvalidatesmodel_task.output_file(422MODEL_OUTPUT_FILE_INVALID: archive-root whitelist, notapisjob*, no unresolved reference). The model task pages the archive listing (limit=1000, until an empty page, at most 5 pages,truncatedrecorded), drops directories andtapisjob*, and selects the bound file literally or by glob without falling back to the label: zero matches is the newMODEL_OUTPUT_MISSING(same-extension candidates, re-register hint), several isMODEL_OUTPUT_AMBIGUOUS. Unbound outputs keep the name/extension rule. Manifest recordsoutput_fileandselected_by.No format-guessing fallback and no subdirectory bindings (both rejected in review as silent-wrong-file risks).
Rollout
register_subside_to_mint.py --only-output-binding(modflow-executables PR) as the end user, dry run first.opera_disp_s1_cumulative.tifselected by binding.Until the ui-react follow-up carries the column on re-insert, editing a configuration's outputs in the MINT UI nulls its bindings (re-run step 2).
Tests
pytest tests39 passed (+1 pre-existing failure,test_hydraulic_head_inference_metadata::test_public_inference_relationships_are_readable_anonymously, fails on develop too)npm test149 passedtsc --noEmitclean; jest 197 passed inclasses/tapis,classes/graphql,unifiedExecutionService.test.ts; eslint error counts unchanged on touched filespytest519 passed (+4 pre-existingtest_demo_api.pyfailures, fail on develop too); golden regenerated🤖 Generated with Claude Code