feat: a joined client node keeps its user's files in the pool #503
Labels
Clear labels
accessibility
all-platforms
area:agents
area:ai
area:chain
area:ci
area:client
area:daemon
area:p2p
area:project
area:protocol
area:runtime
area:storage
bug
chore
community
dependencies
discussion
discussion/Announcements
discussion/General
discussion/Ideas
discussion/Q&A
discussion/Show and tell
discussion/answered
documentation
duplicate
enhancement
good first issue
help wanted
i18n
infra
invalid
needs:decision
needs:hardware
paired
question
research
security
status:in-review
test
testing
tracking
wontfix
Barrier affecting people with disabilities
Run every platform's packaging and checks on this pull request, not only the three main ones
MCP server, skill, and thinking on the pool
Planner and model providers
Blockchain, SISY, verification
Continuous integration and build workflows
Desktop and web clients
sisyphusd coordinator, worker, scheduler
libp2p hosts, relays, discovery, connections between nodes
Project planning, roadmap, and governance
Protobuf schemas and RPC contracts
Workload execution and environments
Content-addressed storage, IPFS, Kubo, Cluster, S3, names, pinning
Something isn't working
Repository health, templates, Discussions, contributor experience
Updates to actions, Go modules or npm packages
Migrated from GitHub Discussions
GitHub Discussions category: Announcements
GitHub Discussions category: General
GitHub Discussions category: Ideas
GitHub Discussions category: Q&A
GitHub Discussions category: Show and tell
Q&A discussion with an accepted answer
Improvements or additions to documentation
This issue or pull request already exists
New feature or request
Good for newcomers
Extra attention is needed
Translations and right-to-left layouts
Build, CI, releases
This doesn't seem right
Waits on a decision from both owners
Waits on a machine we do not have yet
Built together by both maintainers, with co-authored commits
Further information is requested
Needs investigation or a design decision
Sealing, keys, access control, tokens, the security model
Built and in an open pull request; closes when it merges
Tests, test harnesses and the rehearsal
Roadmap and meta issues
This will not be worked on
type
Feature
A request, idea, or new functionality (GitHub issue type)
type
Task
A specific piece of work (GitHub issue type)
Milestone
No items
No Milestone
First release
Projects
Clear projects
No projects
Sisyphus roadmap
Done
No Assignees
rvnminers-A-and-N
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Sisyphus/Sisyphus#503
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of #500.
A node that has joined another's pool as a client can now keep its user's files there through its own local API, the way it already submits jobs there (#474).
What changes
poolFiles(apps/sisyphusd/pool_files.go) is the local API's file store on a worker+client node. It stores and reads blobs through the worker's existing link to the coordinator, and pins the user's files there as this node's client pins. The file names stay in the node's own list.Available()first, the same rule as jobs. A worker alone getsFAILED_PRECONDITION("not a client"); a node that is away getsUNAVAILABLE.attemptOfno longer refuses an upload from a node that is both worker and client. Such a node uploads as a client, and is held to the client's share.StoreFileand in the assistant, with a clearFAILED_PRECONDITION. They belong to other owners with their own retention, which is slice 2.Tests
TestAJoinedClientNodeKeepsItsFilesInThePoolcovers a worker-only refusal, then a client invitation. After it, the test stores, lists and fetches a file, checks the coordinator's client pin, and runs awordcountjob on the CID. It also checks that a private file is not held in the clear, that a chat attachment is refused, and that removing the file releases the pin.TestAJoinedNodesFileStoreKeepsOnlyTheUsersFilesandTestAnAssistantThatKeepsNoAttachmentsRefusesThem.make cover: every statement is covered. gofmt and vet are clean.Docs
docs/desktop-backend.md: files on a joined node.@excho0, feel free to push to this branch if anything reads wrong to you.
I added a focused regression test for the worker+client quota edge case: a node holding both roles cannot upload beyond the client's share. The focused Go test passes locally, and I recorded this as a pending checklist item on #500; I’ll leave it unchecked until the PR lands. Austin, please include the test when you squash-merge once CI is green, preserving my authorship for this contribution in the squash commit.
/cc @rvnminers-A-and-N
Thanks @excho0, that's exactly the edge the
attemptOfchange opened up: a worker+client node uploading past the client's share. Good to have it pinned down. I'll keep you as co-author in the squash commit once CI is green. I'll also carry your test onto the stacked follow-up for slice 2 (chat attachments on a joined node), which is about to open.@@ -0,0 +80,4 @@}var errs []errorfor _, c := range cids {_, err := f.client.Unpin(context.Background(), &pb.UnpinBlobRequest{Cid: c.String()})Potential failure-path consistency issue:
localService.RemoveFiledeletes the local catalogue row before this remoteUnpincall. If the coordinator becomes unreachable afterstoreAvailable()but before this RPC completes, the API returns an error after the file has disappeared fromListFiles, while the coordinator can retain its permanent client pin (TtlSeconds: 0) and quota usage. Could we preserve a retry path (for example, unpin before deleting the row after verifying it exists, or keep a pending release) and cover a failed remote Unpin? This also applies to the stacked #505 path. /cc @rvnminers-A-and-NI requested one retryability fix on the remote Unpin failure path. A temporary coordinator disconnect can currently drop the local file catalogue row while leaving the permanent client pin/quota behind; please preserve a recoverable release path and test it. The CI rerun itself is green. /cc @rvnminers-A-and-N