Skip to content

cut-successor: exit-2 collapse, apply_cut rollback gap, role-demotion indent #253

Description

@chrisdpurcell

Outcome

standards cut-successor reports infrastructure failures the same way it reports findings, and apply_cut can leave partial state behind after a docstring claims it cannot.

Context

Found during the pre-merge review of PR #241 (leg relprep, standards cut-successor writer) and deferred as non-blocking. Quoting /tmp/ps529-session/reviews/review-landed.md (lines 69-72):

  • src/project_standards/standards_graph/cli.py (_run_cut_successor, final line) — return 1 if generated else 0 collapses a follow-on writer's exit 2 (load/write error, unsafe output path) into 1. docs/usage.md documents 1 as "the follow-on projection or catalog writer reported findings" and 2 as a load/write error, so an infrastructure failure in sync-payload-projection is reported as a findings result.
  • src/project_standards/package_contract/cut_successor.py apply_cut docstring — "A refused cut leaves nothing behind" holds only inside the try. _predecessor_occurrences and the scaffold write run after it; an OSError there exits 2 with the copied tree, the family index entry, and the catalog entry already written, and plan_cut then refuses the retry ("successor payload directory already exists"). Either move both inside the guarded block or narrow the docstring's claim.
  • src/project_standards/package_contract/cut_successor.py _insert_catalog_entry — the role-demotion replacement writes f'role = "..."' with no indent, although _SCALAR captured indent and _rewrite_payload_manifest preserves it. Harmless for the flat catalogs/*.toml in the tree; it would silently reformat an indented catalog.

Documented exit codes: docs/usage.md.

Scope

  • Fix the exit-2 collapse in _run_cut_successor so an infrastructure failure from sync-payload-projection surfaces as its own code rather than as a findings result.
  • Move _predecessor_occurrences and the scaffold write inside apply_cut's guarded try, or narrow the docstring's "leaves nothing behind" claim to match actual behavior.
  • Fix the role-demotion replacement in _insert_catalog_entry to preserve the captured indent.

Out of scope

Anything not named above; this issue is the three findings quoted, not a broader audit of cut_successor.py.

Acceptance criteria

  • _run_cut_successor's exit code distinguishes a follow-on writer's findings (1) from an infrastructure failure (2), matching docs/usage.md.
  • apply_cut either guards _predecessor_occurrences and the scaffold write inside the same try as the rest of the cut, or its docstring's "leaves nothing behind" claim is narrowed to describe actual behavior.
  • _insert_catalog_entry's role-demotion replacement preserves the original line's indent.
  • A regression test covers at least the exit-code distinction.

Evidence / references

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions