Skip to content

[Sprint] sprint-loop-47 - #45

Merged
scealiontach merged 3 commits into
mainfrom
sprint/2026-06-08-sprint-loop-47
Jun 8, 2026
Merged

scealiontach merged 3 commits into
mainfrom
sprint/2026-06-08-sprint-loop-47

Conversation

@scealiontach

Copy link
Copy Markdown
Owner

Sprint Plan — 2026-06-08-sprint-loop-47

Sprint Goal

Harden three independent bash/ command scripts against silent or brittle
failure modes, each backed by a new Bats regression test. All three selected
issues are High-priority bugs in the shell-scripts project where a command
either reports false success, silently ignores configuration, or crashes with
an opaque nounset error instead of a clear validation message. The sprint
delivers small, reviewable fixes that make these scripts fail loudly and
correctly, with regression coverage so the behaviours cannot silently
regress. The work is deliberately scoped to disjoint files so the issues can
be implemented and reviewed in parallel.

Selected Issues

1. SUR-3644 — Bug: daml-export exits successfully after export command failure

  • Linear ID: SUR-3644
  • Title: Bug: daml-export exits successfully after export command failure
  • Priority: High
  • Description summary: bash/daml-export's exportRange (lines ~70-100)
    runs java ... export script, records the exit code, and prints REDO, but
    it never returns a non-zero status. The main loop (~278-287) then calls
    correct_export and schedules build against an output directory that may
    lack daml.yaml/Export.daml, and the script can still exit 0
    (~335-340). Audit repro: bash/daml-export -d /tmp/daml-audit -e 0000000000000001 -h example.com with the SDK jar absent prints
    missing-file errors yet exits 0. Suggested fix: make exportRange return
    non-zero when the Java export fails or when required output files are
    absent, and gate correct_export/build on that status.
  • Rationale: Release/export automation can report success after a failed
    DAML export, letting CI jobs proceed on missing/partial artifacts — a
    high-impact correctness bug. Small, self-contained fix in one command
    script with a clear, stub-driven regression.
  • Definition of Done:
    • exportRange returns non-zero when the Java export exits non-zero OR when
      required output files (daml.yaml, Export.daml) are absent.
    • Main loop checks that status and does NOT call correct_export or
      schedule build on failure; the script exits non-zero overall.
    • New Bats regression stubs java to fail and asserts the script exits
      non-zero and performs no correction/build step.
    • pre-commit run --all-files (shellcheck + shfmt) passes on the change.
    • make test / the new Bats spec passes locally.
    • Verification evidence (test output) posted as a Linear comment or
      attachment on SUR-3644 — NOT committed under .claude/.
  • Dependencies / ordering: None. No blockers, no sub-issues. Independent
    of SUR-3648 and SUR-3649 (disjoint files).

2. SUR-3648 — Bug: minikube-test-environment ignores the CNI setting

  • Linear ID: SUR-3648
  • Title: Bug: minikube-test-environment ignores the CNI setting
  • Priority: High
  • Description summary: bash/minikube-test-environment defines
    CNI=${CNI:-calico} (~line 7) and documents CNI in help (~176-177), but
    start_or_create_minikube (lines ~53-73) never passes it to minikube start — the command sets k8s version, driver, node count, memory, and
    addons but omits any --cni argument. Existing
    tests/minikube-test-environment.bats only covers help/stop shallowly and
    does not assert create/start argv. Suggested fix: pass --cni="$CNI" to
    minikube start in both start branches and add a Bats test with a stubbed
    minikube asserting the generated start argv includes the CNI value.
  • Rationale: A documented, user-facing setting silently has no effect,
    which is especially risky for test clusters whose network behaviour depends
    on the CNI. Low-risk, localized fix that also closes a real test-coverage
    gap.
  • Definition of Done:
    • start_or_create_minikube passes the configured CNI (e.g.
      --cni="$CNI") to minikube start in BOTH start branches.
    • New/extended Bats test stubs minikube, runs the create/start path, and
      asserts the captured start argv contains the CNI value.
    • Help text and actual behaviour are consistent.
    • pre-commit run --all-files (shellcheck + shfmt) passes on the change.
    • make test / the Bats spec passes locally.
    • Verification evidence (Bats output + stubbed minikube start argv) posted
      as a Linear comment or attachment on SUR-3648 — NOT committed under
      .claude/.
  • Dependencies / ordering: None. No blockers, no sub-issues. Independent
    of SUR-3644 and SUR-3649 (disjoint files).

3. SUR-3649 — Bug: replace-validator crashes when a requested node has no matching pod

  • Linear ID: SUR-3649
  • Title: Bug: replace-validator crashes when a requested node has no
    matching pod
  • Priority: High
  • Description summary: bash/replace-validator enables set -euo pipefail in main, then reads node2pod[$FROM_NODE] /
    node2pod[$TRGT_NODE] directly (lines ~131-132). If the label selector
    yields no pod for a requested node, Bash treats the missing
    associative-array element as an unbound variable and aborts with an opaque
    nounset error rather than a clear validation message. mapPods populates
    the map around lines 46-58; tests/replace-validator.bats does not exercise
    missing-node validation. Suggested fix: validate the populated map (e.g.
    ${node2pod[$FROM_NODE]+set}) before dereferencing, emit a clear error
    naming the missing node/selector, and exit before any key copy or label
    mutation; add Bats coverage by extracting/sourcing main or factoring the
    validation into a testable helper.
  • Rationale: This script mutates Kubernetes node labels and copies
    validator keys; a typo in -f/-t/-l or a missing pod should fail
    cleanly BEFORE any destructive action. Replacing a brittle nounset crash
    with a precise pre-flight check is a safety-critical, contained fix.
  • Definition of Done:
    • Validation checks presence of both FROM_NODE and TRGT_NODE keys in
      node2pod before any dereference.
    • On a missing node, the script emits a clear error naming the missing
      node/selector and exits non-zero BEFORE any key copy or label mutation.
    • Validation is factored so it is unit-testable (helper or sourced main).
    • New Bats regression drives the missing-node path with a controlled map and
      asserts the clear error + early non-zero exit (no mutation attempted).
    • pre-commit run --all-files (shellcheck + shfmt) passes on the change.
    • Verification evidence (Bats output + missing-node failure) posted as a
      Linear comment or attachment on SUR-3649 — NOT committed under .claude/.
  • Dependencies / ordering: None. No blockers, no sub-issues. Independent
    of SUR-3644 and SUR-3648 (disjoint files).

Scope Preference Note

All three selected issues are small, equal-priority (High), and independent;
none were deferred for size. The sprint holds exactly 3 items, within the
1–4 cap, and was kept reviewable by choosing issues with disjoint file
footprints.

Risks + Mitigations

  • Risk: daml-export (SUR-3644) is hard to test end-to-end because it
    shells out to java and a real SDK jar.

    Mitigation: Stub java in the Bats test (PATH shim) to force a non-zero
    exit / absent output files; assert exit status and that
    correct_export/build are not invoked, rather than running a real export.
  • Risk: Changing exportRange return semantics could mask the existing
    REDO/retry behaviour or alter the main loop's control flow.

    Mitigation: Preserve the REDO retry path; only add a terminal non-zero
    return when retries are exhausted/required files are missing. Review the
    main-loop wait/exit handling (~335-340) carefully.
  • Risk: The exact minikube CNI flag may differ by minikube version
    (--cni vs --network-plugin).

    Mitigation: Follow the issue's suggested --cni="$CNI", but assert on the
    configured value appearing in the stubbed argv rather than hard-coding a
    brittle full-string match; note any version caveat in the PR.
  • Risk: replace-validator main is monolithic and may resist unit
    testing without refactor.

    Mitigation: Factor the node-presence validation into a small helper that
    can be sourced/called with a controlled node2pod map, per the issue's
    suggestion; keep the refactor minimal to stay reviewable.
  • Risk: shellcheck/shfmt (pre-commit) may flag style on edited lines.
    Mitigation: Run pre-commit run --all-files locally before pushing and fix
    findings; respect the repo's -i 2 -ci shfmt config and package::name
    namespacing rules.
  • Risk: Accidentally committing verification evidence under .claude/.
    Mitigation: Each issue explicitly forbids this; post evidence to Linear as a
    comment/attachment only. Called out in IMPLEMENTATION_PLAN.md.
  • Risk: Branch-name hook rejects commits. Mitigation: Use a hook-compliant
    branch (feature/..., fix/..., refactor/..., or sprint/...).

Out of Scope

  • Any redesign of daml-export's overall export/retry architecture beyond the
    exit-status fix.
  • Broader minikube configuration plumbing (driver, addons, memory) beyond
    wiring the CNI flag.
  • Refactoring replace-validator beyond what is needed to make the
    missing-node validation testable.
  • Touching any issue not listed above, any Triage/Todo/In Progress/Blocked/Done
    issue, or any issue carrying a manual label.
  • Changes to other bash/ scripts, libraries, packaging, or CI workflows.

Linear Evidence

  • Linear team verified: Surinis (id ce9ebfde-ff2b-4f54-90f1-c388591ca110,
    key SUR)
  • Linear project used: shell-scripts (id
    a43901a0-b02b-4009-aae1-a6e8903d127d) — confirmed to belong to team Surinis
  • Query/filter used: list_issues with team=Surinis,
    project=shell-scripts, state=7e43e7b1-8a35-4fe0-83a1-62726c462941
    (Backlog state UUID), limit=100; then per-issue get_issue includeRelations=true, list_comments, and list_issues parentId=<ID> for
    sub-issue checks.
  • Approx count of Backlog issues reviewed: 3
  • Approx count of manual-labelled Backlog issues skipped: 0
  • Issues skipped due to unmerged blockers: 0 []
  • Issues skipped due to open-PR file overlap: 0 [] (OPEN_PR_FILES was
    empty; Filter B was a no-op)

Sub-issue Status

N/A — none of the candidate issues (SUR-3644, SUR-3648, SUR-3649) has any
sub-issues (list_issues parentId=<ID> returned empty for all three). No
parent gate applied; no parent was skipped or deferred for active sub-issues.

Parent Issue Sub-issue Sub-issue Status Eligible?
SUR-3644 (none) — Yes
SUR-3648 (none) — Yes
SUR-3649 (none) — Yes

Linear State Transitions

Issue ID Previous State New State
SUR-3644 Backlog Todo
SUR-3648 Backlog Todo
SUR-3649 Backlog Todo

All three transitions were applied via save_issue using the Todo state UUID
196ea437-817f-416c-8f85-f5aea570c6e8 and verified in the response payloads
(status: "Todo", statusType: "unstarted").

exportRange now returns non-zero when the Java export exits non-zero or
when the required output files (daml.yaml, Export.daml) are absent. The
main loop gates correct_export/build on that status and the script exits
non-zero overall, instead of reporting false success on missing/partial
artifacts.
start_or_create_minikube documented and defaulted CNI but never passed
it to minikube start, so the setting silently had no effect. Add
--cni="$CNI" to both start branches so the documented, user-facing
setting actually takes effect.
…r (SUR-3649)

main enabled set -euo pipefail then dereferenced node2pod[$FROM_NODE] /
node2pod[$TRGT_NODE] directly, so a requested node with no matching pod
aborted with an opaque nounset error. Add validateNodesMapped, a
testable helper that checks both keys are present and emits a clear
error naming the missing node and selector, exiting non-zero before any
key copy or label mutation.
@scealiontach
scealiontach marked this pull request as ready for review June 8, 2026 19:16
@scealiontach
scealiontach merged commit f31d499 into main Jun 8, 2026
3 checks passed
@scealiontach
scealiontach deleted the sprint/2026-06-08-sprint-loop-47 branch June 8, 2026 19:19
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.

1 participant