Skip to content

feat(schedules): PR-5a hardening — lean-image guard + clearable schedule fields#569

Merged
philmerrell merged 2 commits into
developfrom
feature/scheduled-runs-pr5a-hardening
Jul 6, 2026
Merged

feat(schedules): PR-5a hardening — lean-image guard + clearable schedule fields#569
philmerrell merged 2 commits into
developfrom
feature/scheduled-runs-pr5a-hardening

Conversation

@philmerrell

Copy link
Copy Markdown
Contributor

PR-5a hardening for scheduled runs (follow-up to the #566/#567 lean-image fixes and #563 B1 CRUD). Two independent commits.

1. Lean-image import guard (test-only)

An AST test asserts the modules bundled into Dockerfile.scheduled-runs (harness/, scheduled_prompts/, sessions_bff/, sessions/ + both lambda handlers) never import agents/strandstop level or lazy (a deferred import still crashes at call time in the lean image, as we saw live). This is the guard that would have caught the ModuleNotFoundError: No module named 'agents' that shipped in the first worker cut. Deliberately narrower than forbidding all apis.shared → agents (e.g. quota.py legitimately imports agents and is not in the lean image).

2. Clearable schedule fields (B1 gap)

update_scheduled_prompt skipped None, so a PATCH could never detach a schedule's assistant or reset its tool restriction — the SPA's clear checkboxes were inert (a bare null reads as "leave unchanged").

  • Service: an UNSET sentinel distinguishes "omitted" (leave) from None (clear → REMOVE the attribute).
  • API: UpdateScheduleRequest gains clearAssistant/clearTools booleans, rejected (422) if combined with a value. clearAssistant reverts to the default agent; clearTools re-snapshots the caller's current RBAC-allowed tools (mirrors creation — a schedule never stores an unresolved None).
  • SPA: the existing clear checkboxes now send the flags; updated the two specs that asserted the old "documented gap".

Verification

  • Backend: 213 tests pass (scheduled_prompts service + routes incl. new clear/validator cases, import boundaries, all lambdas).
  • Frontend: 46 schedule specs pass via ng test.

Deferred (noted, not in this PR)

  • Prod GA-gating check: confirm prod's default role grant before releasing scheduled runs to main (dev-ai's default has *, so it's effectively GA there).
  • apis/shared/quota.py has the same apis.shared → agents coupling (not in the lean-image path).

🤖 Generated with Claude Code

philmerrell and others added 2 commits July 6, 2026 09:09
…trands imports

Add an AST-based test asserting the modules bundled into
backend/Dockerfile.scheduled-runs (harness/, scheduled_prompts/,
sessions_bff/, sessions/ + the two lambda handlers) never import agents/
or strands — top level OR lazy, since a deferred import still crashes at
call time in the lean image. This is the guard that would have caught the
ModuleNotFoundError shipped in the first cut of the worker.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
B1's update_scheduled_prompt skipped None, so a PATCH could never detach a
schedule's assistant or reset its tool restriction — the SPA's clear
checkboxes were inert (a bare null reads as 'leave unchanged').

Add an explicit clear contract: an UNSET sentinel in the service
distinguishes 'omitted' (leave) from None (clear -> REMOVE the attribute).
UpdateScheduleRequest gains clearAssistant/clearTools booleans (rejected if
combined with a value). clearAssistant reverts to the default agent;
clearTools re-snapshots the caller's current RBAC-allowed tools, mirroring
creation so a schedule never stores an unresolved None. SPA sends the flags.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@philmerrell philmerrell force-pushed the feature/scheduled-runs-pr5a-hardening branch from 27b6f78 to 794014e Compare July 6, 2026 15:12
@philmerrell philmerrell merged commit 0dd0cda into develop Jul 6, 2026
4 checks passed
@philmerrell philmerrell deleted the feature/scheduled-runs-pr5a-hardening branch July 6, 2026 15:22
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