Skip to content

fix(web): resume an epic whose budget runs a year or more - #525

Open
LYMDLUT wants to merge 3 commits into
humanfia:mainfrom
LYMDLUT:fix/web-resume-year-long-budget
Open

LYMDLUT wants to merge 3 commits into
humanfia:mainfrom
LYMDLUT:fix/web-resume-year-long-budget

Conversation

@LYMDLUT

@LYMDLUT LYMDLUT commented Oct 27, 2026 •

Copy link
Copy Markdown

What and why

On hmz web, Resume on an epic whose budget allowed a year or more opened on no time limit at all, so every flow but chat refused to start: rlar needs at least one limit on what it may spend. pydantic writes a timedelta of 365 days or more in years (P1Y, P68Y180D), and the page's secondsOf read days and less only. It now reads years too, as the 365 days pydantic writes one as.

Fixing that turned up two places where a budget's duration is written otherwise than the specs say:

  • The epic record. specs/api/files/epics.md §5.1 says budget.duration is a number of seconds or null; Runner wrote it with Budget's own JSON, in ISO 8601. It now writes seconds. Every reader validates it as a Budget or hands it to the page, which reads both, so epics written before still read.
  • A flow's setup saved from the page. specs/api/http.md §11.4.2 and §8.3.5 say a save or a start writes it as specs/api/settings.md defines it, and §5.2.7 there says an ISO 8601 duration beside every limit, as the terminal interface writes one. The page's seconds were written as sent. They are now written that way; a duration that is not one is left as sent, so a start with it is still refused by its host (§8.3.4). hmz.web does this with pydantic alone, since its layer may not import hmz.flows.

How it was tested

  • tests/system/web/test_web_page.py::test_an_epic_given_a_year_or_more_is_resumed_on_its_budget (new), on Chromium and WebKit: an epic whose record says P1Y is resumed from its page on 525600 minutes and picked up, and a new epic of the flow then opens on that year from the saved setup. Without the dom.js change it fails at the minutes field.
  • tests/integration/test_web_site.py::test_the_budget_saved_for_a_flow_says_its_duration_as_settings_does (new) and tests/integration/test_core_exec.py::test_a_spent_duration_ends_a_loop_as_an_ordinary_stop (now checks the seconds): each fails without its change.
  • The new secondsOf agrees with pydantic on 616 durations, from none to over a thousand years.
  • uv run pre-commit run --all-files passes, and uv run pytest on macOS: 6729 passed, 33 skipped. That was with two things of this machine kept out of the suite, which it does not keep out itself: the grok, pi and qwen installed in /opt/homebrew/bin, which Humanize looks in off PATH, and an inherited NODE_COMPILE_CACHE. test: hide agents installed off PATH, and an inherited NODE_COMPILE_CACHE #526 closes both.

Checklist

  • The title is a Conventional Commit, with ! if it breaks something.
  • New and changed tests are in the right tier: tests/unit/, tests/integration/ or tests/system/ (where a test goes).
  • The docs say what the code now does, and the code matches specs/. A spec changed only where an issue asked for it.
  • uv run pre-commit run --all-files and uv run pytest pass.

convliu and others added 3 commits October 27, 2026 16:30
…rd says

The epic record (specs/api/files/epics.md §5.1) says `budget.duration` is a
number of seconds or null; the record was written with `Budget`'s own JSON,
which says it in ISO 8601 -- `P68Y180D` for a long one.

Co-authored-by: Cursor <cursoragent@cursor.com>
…8601

A page says a budget's duration in seconds, and a start or a save from it
wrote that into the settings as it was, where `api/settings.md` §5.2.7 says
an ISO 8601 duration beside every other limit, as the terminal interface
writes one.

Co-authored-by: Cursor <cursoragent@cursor.com>
pydantic writes a duration of 365 days or more in years, `P1Y`, which the
page could not read: Resume opened on no time limit at all, and every flow
but chat refused to start without one.

Co-authored-by: Cursor <cursoragent@cursor.com>

This branch has not been deployed

No deployments
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