Repository navigation
Export every page and window into one file - #42
Open
fedealconada wants to merge 1 commit into
Open
fedealconada wants to merge 1 commit into
fedealconada wants to merge 1 commit into
Conversation
`proofline export --all --output FILE` follows every cursor, splits a longer range into adjacent 31-day windows, writes one CSV header, and replaces FILE only after every page succeeded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Who this helps
People who run the CLI from a shell or a cron job and want one complete file for a range, such as a quarter of review data for a spreadsheet or a warehouse load. Today
proofline exportreturns one page of one window of at most 31 days. A full export means scripting cursor loops and window math, then joining pages, and the README warns that partial output from several invocations must never be treated as complete.--all --output FILEdoes this safely in one command.What changed
proofline exporthas two new flags,--alland--output FILE.--allrequires--output,--outputrequires--all, and--allconflicts with--cursor. These are clap attributes, so clap reports the errors.--all,--from/--tocan span any length. The range[from, to)is split into consecutive windows of at most 31 days. Each window's exclusive end is exactly the next window's inclusive start. A span that already fits in one window is sent exactly as typed. Generated boundaries are UTC RFC3339.--to <= --frombefore it sends any request.X-Proofline-Export-Next-Cursoruntil the header is absent. The per-page checks stay the same: format and version headers, a settled horizon, and UTF-8. The page fetch and its checks now live in one shared function,export_page, which both paths use.settled-until: <earliest horizon across windows>goes to stderr throughterminal_safe.--all --output.Decisions
src/tools.rshas a small RFC3339 parser and a UTC formatter built on Howard Hinnant'sdays_from_civilandcivil_from_days. It refuses leap seconds (:60) and fractions finer than a nanosecond instead of rounding them.Two small side effects:
tempfilecreates the file with mode 0600, so the exported FILE ends up 0600, including when it replaces an existing file.How it was verified
Rebased on main at 14c8f4f.
cargo fmt --checkandcargo clippy --locked --all-targets -- -D warningspass.cargo test --locked --no-fail-fastpasses excepttests/agent_install.rsunattended_registration_preserves_settings_and_uses_the_installed_binary, which fails the same way on main at 14c8f4f on my machine, so it looks environment specific and unrelated to this change.New tests:
tests/http.rsexport_all_follows_every_cursor_into_one_ndjson_file: three pages, one without a final newline. Checks the exact file content, the cursors sent (including one that needs URL encoding), empty stdout and the stderr horizon.export_all_splits_a_long_range_into_adjacent_windows_with_one_csv_header: 2026-08-01 to 2026-10-10. Checks the exact(from, to, cursor)queries sent, a single header, and that the earliest window horizon is reported.export_all_failure_leaves_no_file_and_an_existing_file_untouchedexport_all_refuses_inconsistent_pages: horizon change within a window, repeated cursor, empty cursor, different CSV headerexport_all_stops_at_the_page_cap: exactly 1000 requests, then a refusalexport_all_needs_output_conflicts_with_cursor_and_checks_the_range_first: the clap refusals, plus malformed and empty ranges refused with zero requestssrc/tools.rsDeliberate breaks. Each one made at least one test fail, and the code was then restored byte-for-byte:
windows_share_each_exclusive_end_as_the_next_startand…splits_a_long_range…fail.…splits_a_long_range…fails.…failure_leaves_no_file_and_an_existing_file_untouchedfails, along with four other export tests.export_all_refuses_inconsistent_pagesfails.Manual run against the mock server (
manual-test/export_mock.py) athttp://127.0.0.1:8788, usingexport reviews --from 2026-08-01T00:00:00Z --to 2026-10-10T00:00:00Z --format csv --all --output reviews.csv:08-01→09-01,09-01→10-02,10-02→10-10), 2 pages each. The file has 12 rows and one header, and stderr showssettled-until: 2026-11-05T09:55:00Z.FAIL=1(HTTP 500 on the second page of window 2): exit 1 withreturned HTTP 500. The existingreviews.csvhas the same checksum as before, and no temporary file is left in the directory.I prototyped this earlier and rebuilt it in a fresh session so the prompts below are complete.
🤖 Generated with Claude Code