Skip to content

feat(pipeline-run): fall back to file stem for a nameless submit spec#33

Merged
Silin144 merged 2 commits into
TangleML:masterfrom
Silin144:feat/submit-name-fallback
Jul 18, 2026
Merged

feat(pipeline-run): fall back to file stem for a nameless submit spec#33
Silin144 merged 2 commits into
TangleML:masterfrom
Silin144:feat/submit-name-fallback

Conversation

@Silin144

Copy link
Copy Markdown
Collaborator

What

Relaxes OSS submit-time validation so a pipeline spec with no declared name falls back to the pipeline file stem instead of hard-failing with name must be a non-empty string. A declared, non-empty name always wins; only the genuinely-nameless case is filled.

This restores the long-standing tangle-deploy behaviour (submitting my_pipeline.yaml with no name produces a run named my_pipeline) after submit-time validation was consolidated upstream (#28/#30).

Approach — resolve-then-validate

Rather than loosening the schema (which would let genuinely-invalid specs through), the fallback name is resolved into the spec first, and then the fully-resolved spec is validated. Everything else stays strict.

A single shared helper does the resolution:

@staticmethod
def _resolve_fallback_pipeline_name(pipeline_spec, fallback_name):
    # A declared non-empty name always wins.
    # No-op when the spec is not a mapping or no fallback is available.

It is wired into both submit code paths so OSS CLI and downstream (tangle-deploy) submits behave identically:

  1. PipelineRunner.prepare_pipeline_for_run (pipeline_runner.py) — validates first in the run lifecycle; passes the hook-resolved pipeline_name (which already honours any initial_pipeline_name override) so it can't reject a nameless-but-otherwise-valid spec before path 2.
  2. PipelineRunManager.prepare_submit_payload_from_spec (pipeline_run_manager.py) — the shared submit chokepoint; resolves after apply_run_name_template, before validation.

The run name flows from the spec's name (root_task.componentRef.spec.name), so injecting name into the spec is the correct mechanism — the resulting run is named after the stem.

Worked example

my_pipeline.yaml:

implementation:
  graph:
    tasks: {}

tangle pipeline-runs submit my_pipeline.yaml --no-hydrate → submitted spec name = "my_pipeline" (file stem). If the file instead declares name: Demo Pipeline, the run is named Demo Pipeline (declared name wins over the config stem).

Changes

  • pipeline_run_manager.py — shared _resolve_fallback_pipeline_name helper + resolve step in the submit chokepoint.
  • pipeline_runner.py — resolve step before first-path validation.
  • tests/test_pipeline_runs_cli.py — two tests: stem fallback when nameless, and declared-name-wins-over-stem.

Testing

  • Full OSS suite green (774 standalone); ruff clean.

🤖 Generated with Claude Code

A file-based submit whose spec omits a usable top-level `name` is now
resolved to the source-file stem before submit-time validation runs,
rather than being rejected outright. This restores the long-standing
downstream behavior where `submit my_pipeline.yaml` runs under the name
`my_pipeline` when the spec itself declares no name.

The fallback is applied at the single shared submit chokepoint
(`PipelineRunManager.prepare_submit_payload_from_spec`) and in the
higher-level `PipelineRunner.prepare_pipeline_for_run` (which validates
first in the full run lifecycle), via a small shared helper
`_resolve_fallback_pipeline_name`. A declared non-empty `name` always
wins; only the genuinely-nameless case is filled, so specs that are
malformed for any other reason (missing/!object `implementation`, etc.)
still fail validation exactly as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Silin144
Silin144 requested review from Ark-kun and Volv-G as code owners July 17, 2026 14:05
if not isinstance(pipeline_spec, dict):
return pipeline_spec
name = pipeline_spec.get("name")
if isinstance(name, str) and name:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(AI-assisted) [nit] A whitespace-only declared name skips the fallback. isinstance(name, str) and name treats " " as a valid declared name, so a blank-ish name is kept and the file-stem fallback isn't applied. Matches the literal "non-empty" contract, but a whitespace-only name arguably should also fall back to the stem (name.strip()). Trivial.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 45353fc — switched to name.strip() so a whitespace-only name is treated as nameless and takes the stem fallback, plus a regression test covering the " " case.

@Volv-G Volv-G left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(AI-assisted) Correct resolve-then-validate approach — injects the file-stem fallback into the spec and keeps validation strict rather than loosening the schema. Verified the shared _resolve_fallback_pipeline_name on PipelineRunManager is reached from both submit paths (PipelineRunner inherits it), and declared-name-wins vs stem-fallback are both tested end-to-end. One trivial nit inline (whitespace-only name). LGTM.

@Silin144 Silin144 self-assigned this Jul 18, 2026
Address review nit: `isinstance(name, str) and name` accepted a
whitespace-only `name` (e.g. "   ") as a declared name, skipping the
file-stem fallback and submitting a blank run name. Switch to
`name.strip()` so a blank-ish name is treated as genuinely nameless and
takes the stem, matching the "non-empty name" intent. Add a regression
test covering the whitespace-only case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Silin144
Silin144 merged commit 6ab0c02 into TangleML:master Jul 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants