You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Push to a URL that doesn't exist yet → JSS materializes a fresh git repo, hands you back the clone URL, auto-cleans it up after the TTL expires. Authenticated by your existing Solid identity. No pre-provisioning, no dashboards, no tokens to mint.
$ git remote add scratch https://alice.solidweb.app/git/scratch/feature-x.git
$ git push -u scratch main
# JSS materialized the repo on first push.# Repo will auto-delete in 24h unless you bump the TTL or persist it.
That's the whole feature.
Why
AI agents and pipeline tooling want disposable git remotes that exist only for as long as the work does. Today the options are:
GitHub/Gitea: heavyweight to provision per task; agents need API tokens; cleanup is manual.
gitfork.app: nails the ergonomics, but uses Basic Auth and lives outside the user's pod.
A self-hosted git server: works but every team rolls their own, no persistence story, no integration with the user's identity.
JSS sits in a sweet spot: it already speaks git smart-HTTP (src/handlers/git.js), already has Solid auth, already has per-pod storage and quotas. Adding "auto-materialize on first push, auto-expire on TTL" turns every JSS pod into a personal disposable-git endpoint that Just Works for any Solid-authenticated agent.
What it would look like
Use cases
Agent workspaces: an autonomous agent clones, mutates, pushes, walks away. No cleanup script, no leaked branches, no token rotation.
CI scratch repos: pipelines build a temporary repo from artefacts, point Snapshotting / e2e tooling at it, let it expire.
Share-and-forget: drop a snapshot of a work-in-progress for a peer to clone over IRC/Matrix; expires in 24 hours.
Reproducible bug reports: minimal-repro repo materialized on the spot with a one-week TTL.
Solid-native ephemeral state: stores that need git semantics (history, branches, refs) but don't deserve permanent storage in the pod.
URL shape
https://<pod>.solidweb.app/git/scratch/<name>.git
Lives under a fixed /git/scratch/ namespace per pod — segregated from regular pod data.
<name> is whatever the agent chooses on first push.
The pod owner authenticates as themselves; agents authenticate with their Solid token.
Lifecycle
Event
Behaviour
First git push to a nonexistent scratch URL
Repo is created, push proceeds, TTL clock starts.
Subsequent operations (clone, fetch, push)
Behave like any git remote, optionally extend TTL on activity.
TTL expiry
Repo deleted in the next sweep (configurable cadence).
Manual persistence
POST /git/scratch/<name>.git/persist flips the repo to permanent — pod-owner only.
Auto-create only under /git/scratch/ — never on arbitrary pod paths. Prevents typo-squatting, keeps the feature contained.
No upstream seeding by default — the gitfork "seed from URL" feature is nice but is an SSRF vector. Add later behind an allow-list config.
Anonymous push: opt-in only — by default agents must identify with a Solid token (auditability). Operators who want true gitfork-style anonymity flip a flag.
TTL sweeps as a background pm2-friendly task — periodic, not per-request, so push latency stays unaffected.
TL;DR
Push to a URL that doesn't exist yet → JSS materializes a fresh git repo, hands you back the clone URL, auto-cleans it up after the TTL expires. Authenticated by your existing Solid identity. No pre-provisioning, no dashboards, no tokens to mint.
That's the whole feature.
Why
AI agents and pipeline tooling want disposable git remotes that exist only for as long as the work does. Today the options are:
JSS sits in a sweet spot: it already speaks git smart-HTTP (
src/handlers/git.js), already has Solid auth, already has per-pod storage and quotas. Adding "auto-materialize on first push, auto-expire on TTL" turns every JSS pod into a personal disposable-git endpoint that Just Works for any Solid-authenticated agent.What it would look like
Use cases
URL shape
/git/scratch/namespace per pod — segregated from regular pod data.<name>is whatever the agent chooses on first push.Lifecycle
git pushto a nonexistent scratch URLPOST /git/scratch/<name>.git/persistflips the repo to permanent — pod-owner only.DELETE /git/scratch/<name>.git— owner only.Configuration
{ "gitOnDemand": true, "gitScratchDefaultTtl": "24h", "gitScratchMaxTtl": "30d", "gitScratchMaxRepos": 100 }Identity & access
Solid auth all the way down. No HTTP Basic. Three rules:
Design choices worth getting right
/git/scratch/— never on arbitrary pod paths. Prevents typo-squatting, keeps the feature contained..quota.jsonmachinery (Intermittent 500 on concurrent PUTs to different trackers (pilot drag-drop) #309 work).Why this fits JSS
JSS already has the building blocks:
src/handlers/git.js): clone, fetch, push, pull all work today.src/auth/middleware.js): one identity story across HTTP, WebSocket, and git.src/storage/quota.js): atomic, race-safe (post Intermittent 500 on concurrent PUTs to different trackers (pilot drag-drop) #309).src/notifications/events.js): could emitgit.scratch.created/git.scratch.expiredevents for tooling that wants to subscribe.Adding scratchpads turns those primitives into a feature with a clear elevator pitch:
Acceptance criteria
git pushtohttps://<pod>/git/scratch/<name>.gitmaterializes the repo on first push, with the pushing identity recorded as creator.POST /git/scratch/<name>.git/persist(owner-only) prevents expiry.DELETE /git/scratch/<name>.git(owner-only) removes immediately.Related
Status
This issue is exploratory — opening it to capture the design before momentum builds. Happy to iterate before any implementation begins.