mirror of
https://github.com/Twigpine/node.git
synced 2026-11-09 05:20:05 -10:00
* docs(node): Phase 3 subtree-withholding plan with Task 0 spike findings * feat(node): resolve withheld blob OIDs for path-scoped visibility * feat(node): filtered upload-pack serve that omits withheld blobs * feat(node): serve filtered pack when caller has withheld subtree blobs * test(node): end-to-end assert served pack omits withheld blob * docs(node): note why info/refs is not gated on subtree visibility * fix(node): frame filtered serve as protocol v0 and prove it with a real clone upload_pack_excluding emitted a v2 packfile section, but info_refs advertises v0, so real clients negotiated v0 and rejected the response with 'expected ACK/NAK, got packfile'. Frame the v0 stateless-rpc shape instead (NAK, then the pack via side-band-64k when offered). Add an end-to-end test that stands up info_refs + upload_pack_excluding and runs a real git partial clone, asserting the withheld blob's bytes never reach the client while its tree entry and SHA stay visible. A stock full clone cannot consume the pack (it is not closed under reachability, so fetch fails the connectivity check); a partial clone is required. * docs(node): correct Phase 3 caveat (full clone refused at fetch, not checkout) * test(node): prove incremental fetch still withholds; document negotiation choice Add a real-git test that partial-clones, pushes a new commit server-side, then fetches: the new object arrives and the withheld blob stays absent. This pins down that ignoring have/want negotiation (always sending a self-contained pack of all refs minus withheld, with NAK) is correct for both clone and fetch; the only cost is a fetch re-sends the full object set. Refactor the real-git tests onto a shared server harness and document the negotiation decision in code and in the plan's follow-ups. * refactor(node): address CodeRabbit review on PR #28 Move the two blocking git shell-outs in the filtered upload-pack path off the async worker thread, matching the tokio::process / spawn_blocking usage already in this file: build_filtered_pack (rev-list + pack-objects) and withheld_blob_oids (per-ref ls-tree) now run inside spawn_blocking so a large repo cannot stall the tokio runtime. Behavior is unchanged. Also fix the Task 0 findings block in the Phase 3 plan: it still recorded v2 packfile framing, which is the exact path that failed against a real client and was corrected to v0. The block now documents the shipped v0 contract. Drop a stray trailing code fence flagged by markdownlint (MD040). The speculative ls-tree timeout and the public/no-rules fast-path from the review are intentionally left out: the timeout guards against adversarial repos we do not yet host, and the fast-path is a micro-optimization not worth the extra branch right now. * chore(node): drop planning doc from PR per maintainer request kevincodex1 asked to keep the superpowers planning docs out of the repo. The Phase 3 plan was scaffolding for this change, not something the project needs to carry. Removing it leaves only the code and tests in the PR. * chore: gitignore local planning docs (docs/superpowers/) * feat(node): replicable_objects filter for replication enforcement * test(node): pin anonymous-caller contract of withheld_blob_oids * feat(node): IPFS pinning skips withheld blob OIDs * feat(node): Pinata pinning skips withheld blob OIDs * feat(node): enforce visibility on push replication (IPFS/Pinata/gossip/Arweave) * test(node): announce gate matches anonymous repo readability * fix(node): run withheld_blob_oids off the async worker on push The receive-pack replication chokepoint called withheld_blob_oids directly on the tokio worker, where its blocking git ls-tree walk can stall the runtime for repos with many refs. Wrap it in spawn_blocking to match the upload-pack serve path. --------- Co-authored-by: Kevin Codex <[email protected]>