Repository navigation
Fresh-mark gate for paper settlement, CI on PRs, README refresh - #1
Merged
Merged
Conversation
A DATED_FUTURE expiry close books fee-free realized P&L into lots, journal, drawdown and strategy capital at the last mid. That mid had no age check, so a book left behind by a contract that stopped being quoted (or a feed/worker outage across expiry) became permanent realized P&L. settle() now books the expiry only at a two-sided book observed no more than the matcher's book_max_age (the bound a resting paper order needs to fill) before now. Otherwise nothing is booked, the event stays unsettled and is retried every call, and a PAPER_EXPIRY_DEFERRED record with reason PAPER_EXPIRY_MARK_STALE or PAPER_EXPIRY_MARK_MISSING is returned once per reason, so it shows in automation.status.settlements. No mark is substituted; commit rollback also restores the reported-deferral state. The subscription keep list already carries every held instrument first and is not re-planned mid-run, so it is not the cause and is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Synthetic PAPER_FUNDING was charged against the last mid with no age check, so a book left behind by a dropped feed set a permanent collateral debit or credit. Each funding boundary the clock crosses is now recorded as due, with the quantity held at the crossing, and charged only at a fresh mark (a two-sided book no older than the matcher's book_max_age), the same rule as expiry settlement. Until then it stays due across calls and is reported once per reason as PAPER_FUNDING_DEFERRED (PAPER_FUNDING_MARK_STALE / _MISSING). A due boundary whose position closed before a fresh mark priced it cannot be charged by the margin book; it is dropped and reported as PAPER_FUNDING_NOT_CHARGED (PAPER_FUNDING_POSITION_CLOSED). Expiry and funding now share one mark helper and one deferral report. Funding events also carry the quantity and mark they were charged at. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The validation workflow only ran on manual dispatch, so no change was ever checked remotely. It now runs on pushes to main, on pull requests and on demand, and superseded pull-request runs are cancelled. - actions/checkout v5 -> v7 without persisted credentials. - astral-sh/setup-uv v7 -> v10; caching follows the action's safer default instead of being forced on. - uv 0.12.15 -> 0.13.1 and Python 3.14.7 -> 3.14.8 (the local toolchain), pinned once at workflow level. - Named jobs and steps; the checks themselves are unchanged. Docs and the Makefile no longer describe the workflow as manual-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Header with icon and CI/license/Python/platform badges, a warning callout, highlights, a pipeline diagram with a stage table, a status table, getting started, development and CI, and documentation links. Claims are carried over from the previous README; detailed caveats stay in docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
setup-uv stopped publishing floating major tags in v8, so `setup-uv@v10` could not be resolved and every job failed at set-up. Pin it and checkout to the commit SHAs of their exact releases (v10.3.0, v7.0.1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Windows job resolved Python 3.14.8 to the runner's preinstalled python.org build, which links SQLite 3.50.4, below the 3.51.3 minimum, so the SQLite gate failed. uv prefers an existing system interpreter over a download; UV_MANAGED_PYTHON makes every runner use uv's managed CPython, which bundles a current SQLite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mypy checks Windows runners as sys.platform == "win32". With warn_unreachable, the POSIX code after an `if sys.platform == "win32": return` block was reported unreachable, and resource.getrusage does not exist in the Windows stubs. Put the POSIX paths in explicit platform else-branches (which mypy treats as platform checks) in native_user_home, development_socket and _max_rss_bytes. Behavior is unchanged; mypy --platform win32/linux/darwin all pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found by the first Windows CI run: - Check text out with LF everywhere (.gitattributes). A CRLF checkout on Windows changed the bytes behind pinned digests, so the schema and manifest identity checks failed. No committed content changes. - Dataset preparation fsynced graph files through read-only handles; Windows flushes only writable ones (EBADF). Open them r+b. - The source archive took launcher execute bits from the filesystem, which Windows does not record; shell launchers are now always 0o755. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The network guard now allows loopback: Windows asyncio wakes its event loop through a loopback socket pair. Internet addresses and DNS stay blocked. - Worker RPC fixtures identify the caller with tests.support.local_peer() (coinfly.ipc.auth.current_uid) instead of POSIX-only os.getuid/getgid. - Read sources as UTF-8, use a platform socketpair, and expect coinfly-worker.exe for the packaged worker on Windows. - Skip on Windows only what is inherently POSIX, each with its reason: Unix-domain socket IPC tests (Windows uses named pipes) and the macOS release tooling's rename-over-empty-directory test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
Paper settlement refuses stale marks (
src/coinfly/worker/paper_engine.py)DATED_FUTUREexpiry andPAPER_FUNDINGare booked only at a fresh mark: a two-sided book observed no more than the matcher'sbook_max_age(5 s, the bound a resting paper order needs to fill) before the settlement check.automation.status.settlementsasPAPER_EXPIRY_DEFERRED/PAPER_FUNDING_DEFERRED(..._MARK_STALEor..._MARK_MISSING). No substitute mark is ever used.PAPER_FUNDING_NOT_CHARGED(PAPER_FUNDING_POSITION_CLOSED).docs/runbooks/paper-startup.mdsection 4.CI runs on pushes and pull requests (
.github/workflows/ci.yml)main, pull requests and on demand, and superseded PR runs are cancelled.actions/checkoutv5 → v7 (no persisted credentials) andastral-sh/setup-uvv7 → v10 (default cache policy).README: restructured into a concise landing page (badges, warning, highlights, pipeline diagram, status, getting started, development, docs). Claims are carried over; detailed caveats stay in
docs/.Tests
tests/worker/test_paper_settlement.py. Each failed before its fix because the stale mark was booked:ruffandmypy src/coinflyclean. The one local failure istests/test_macos_build_profile.py, which requires the interpreter to be<checkout>/.venv. That doesn't hold in a worktree using the main checkout's venv; the test passes in the main checkout.Paper-only: no live credentials, orders or transfers involved.
🤖 Generated with Claude Code