Skip to content

Post private contribution bases from a local checkout - #1098

Merged
jbojcic1 merged 2 commits into
mainfrom
feat/post-contribution-from-local-checkout
Oct 5, 2026
Merged

jbojcic1 merged 2 commits into
mainfrom
feat/post-contribution-from-local-checkout

Conversation

@maxie-agent

@maxie-agent maxie-agent commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

What this does

Adds base_local_path to post_job. It is an absolute checkout, linked-worktree or bare-repo path on the buyer daemon machine, and is accepted only with the four contribution pins. For private posts, the buyer stages the pinned commit and its entire reachable history from that repository, then runs the existing quota/type checks, uploads, and keeps the collect seed.

If no path is supplied, it cannot be opened, the commit is missing, or its history cannot be staged, one plain log line explains the fallback and the existing target_repo_url download runs. Relative paths are rejected. Public contribution posts do not upload a base. There is no CLI post command to extend; MCP forwards the new field through the daemon params into PostJobRequest.job / ContributionSpec.

Why unrelated code stays private

  • Start a revision walk at only base_oid. Build a new pack from that walk; never copy source packs, refs, working files, or enumerate all source objects for upload.
  • Borrow the source object database into a fresh repository view. Source config, refs and shallow boundaries do not control the walk. Missing ancestors fail local staging and trigger download.
  • Build and index in a temporary directory. Only a completed pack directory is moved into empty base staging; failed local attempts cannot pollute a fallback download.
  • The resulting staging repository has one pack, no loose objects or alternates, so pack_forward can send it unchanged into the empty job repository. The original quota and symlink/submodule checks still run before provisioning/upload.
  • The path is local-only: not a wire pin, offer tag, task field or relay parameter. Tests compare public event drafts and inspect the private offer and plaintext task.
  • The pinned hash binds the content. No remote comparison, credential helpers, hooks or subprocesses. The git CLI is used only by benchmark/test fixtures.

Measurements

8-core Linux VPS; public MakePrisms/agicash at 89cda15345f4113d2be9962a37bea9c4d80483c6; 14,922 reachable objects. Release-mode standalone Rust probe using git2 0.19.0 / libgit2 1.8.1. Wall times below cover selecting objects, packing and indexing for libgit2; CLI rows are pack creation only. They exclude clone, HTTP upload and relay processing. Sizes are decimal MB. All libgit2 outputs were checked against git rev-list --objects <pin>: exact set, no extras.

Method Wall time Pack size
git CLI pack-objects --stdout --revs --delta-base-offset (reuse) 0.81 s 74.15 MB
git CLI, --no-reuse-delta --threads=8 4.96 s 73.53 MB
libgit2 default, 1 thread 27.98 s 73.80 MB
libgit2 set_threads(0), default delta window 19.47 s 73.88 MB
libgit2 1 thread, pack.windowMemory=1 12.95 s 79.97 MB
libgit2 auto threads, pack.windowMemory=1 11.11–11.67 s 79.94–79.95 MB
libgit2 auto threads, pack.windowMemory=65536 10.63 s median (3 quiet runs: 9.96–10.80 s) 78.27–78.42 MB
Selected: auto threads, pack.windowMemory=1048576 10.42 s median (3 quiet runs: 10.34–11.34 s) 77.49–77.50 MB

libgit2 1.8.1 pack-objects.c reads pack.windowMemory, but ignores pack.window / pack.depth and does not reuse deltas. The selected limited-search option is the fastest measured supported option by the three-run median of the two leading candidates and adds about 3.7 MB versus the default. It changes config only in the temporary view. It is not a claimed universal optimum or a Mac result. Buyer-input fallback pushes also get the isolated packbuilder_parallelism(0) setting; seller pushes keep their current setting.

Tests and mutation evidence

  • New real smart-HTTPS posting fixture: 1 test, ten cases passed. Checkout, linked worktree and bare repo succeed with an unfetchable source URL. The uploaded object set equals the pin's full history; unrelated branch/unreachable objects in a shared source pack and uncommitted files stay out. Normal download works for absent, missing and non-repo paths, a missing commit, and incomplete shallow history. Symlinks and submodules are refused before upload. Checks forwarding, seed creation and private wire/plaintext privacy.
  • Core parameter tests: 2 passed (contribution-only RPC wiring; absolute path and unchanged public offer/tags).
  • Ten intentional red failures confirmed in a disposable checkout, then restored: bypass local import → unfetchable checkout post fails; add unrelated source refs to the walk → exact uploaded-set assertion fails; disable fallback separately for missing path, non-repo, and absent commit → each named posting case fails; bypass check_objects_after → forbidden symlink post unexpectedly succeeds; remove contribution-only guard → from-scratch refusal assertion fails; add base_local_path to offer tags → event equality fails; remove MCP schema field → expected string schema becomes null; allow only submodule mode through the existing policy → the submodule refusal assertion fails. Every case compiled and failed at its intended assertion, not a compiler/fixture error.
  • Clean-head suites: buyer_private_preparation 1, local_contribution_base 1 (ten cases), no_system_git 1, private_repo_transport 9, core local_base 2, private_content 65, pack_forward 3, MCP schema 1: 83 passed, zero failures. Both cargo clippy -p maxplayer-core --features acp,gateway,git-delivery,wallet --no-deps and cargo clippy -p maxplayer --features acp,wallet --no-deps completed; pre-existing repository warnings remain. Only touched Rust files were formatted, with no workspace-wide cargo fmt.
  • No relay code was changed. This uses the existing Git HTTP fixture rather than changing relay behaviour.

Limits

A checked-out private upstream can now be posted to a targeted seller, which reads the uploaded job base. Without a usable checkout the old downloader still needs to read the URL and can fail on a private upstream.

Open pool is not fixed end to end. The buyer can post using a local copy, but seller_node/privacy.rs::preflight rewrites the base URL to the private job repo only for targeted discovery. Open-pool sellers still fetch the original upstream before claiming. No seller/preflight behaviour changed.

Uncommitted changes are not inputs. Existing quotas and symlink/submodule refusal remain. Mac, production, and a real seller's full award/deliver/collect cycle are unverified. No merge or deployment is requested.

Advisor review

Independent read-only advisor verdict: approve, no actionable defects, at exact head 7b84495586f527cb9517c6a953963ec65ceebc84. Job eed31a5f9efb9ca2a79af7278067fdecf3106ee7f64288cb200da58f4b86f203 was posted with the requested seat and amount_sats=0, payment=none, visibility=public, output=text/markdown; result was read through get_job(wait_for=result) and collected successfully for 0 sats.

The reviewer inspected surrounding code and pinned libgit2 source; it did not rerun tests or timings. Optional further coverage noted: a non-repo subdirectory inside a checkout, a merge's second parent, forbidden modes only in ancestor trees, and an over-object-quota local history. These were not findings or approval conditions; the existing guards cover them by code inspection. No fixes or re-review were needed.

CI: all eight jobs passed in run 37244326981, verified against head 7b84495586f527cb9517c6a953963ec65ceebc84. Vercel checks also passed. No CI failures or reruns. PR remains OPEN / CLEAN; no merge or production deployment performed.

Open-pool refusal (e495ba3)

An open-pool (untargeted=true) post with base_local_path is now refused at post time, before any staging or upload, with a message pointing at seller_pubkey. Open-pool sellers fetch the base from target_repo_url before claiming, so a base read from a local checkout would never reach them and the job would silently get zero claims. Test post_job_refuses_local_base_on_open_pool fails with the check disabled (confirmed locally). Docs and MCP schema updated to match.

Note: cargo clippy --all-targets reports unused_io_amount at git_transport.rs:2129 (test code). It is identical on main (:2122) and not touched here.

@vercel

vercel Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
maxplayer Ready Ready Preview Oct 5, 2026 12:14am UTC

Request Review

Open-pool sellers fetch the base from target_repo_url before any seller is
picked, so a base read from a local checkout would never reach them and the
job would silently get zero claims. Refuse it at post time, before staging
or upload, with a message pointing at seller_pubkey. Test fails with the
check disabled.
@jbojcic1
jbojcic1 merged commit 98ea3f5 into main Oct 5, 2026
10 checks passed
@jbojcic1
jbojcic1 deleted the feat/post-contribution-from-local-checkout branch October 5, 2026 14:42

This branch was successfully deployed

1 active deployment
Preview — e495ba3d Deployed Oct 5, 2026 by vercel[bot]
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.

2 participants