Skip to content

Private task copies (opt-in), frame hints through the Raft relay, and two-computer fixes - #1944

Merged
AbirAbbas merged 39 commits into
devfrom
docs/workspace-relay-architecture
Oct 26, 2026
Merged

AbirAbbas merged 39 commits into
devfrom
docs/workspace-relay-architecture

Conversation

@santoshkumarradha

@santoshkumarradha santoshkumarradha commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Takeover note (2026-10-26). Abir asked me to land this PR. Since Santosh's last push, the private task copies,
multi-root workspaces and Review/Apply below are opt-in
. They need CODEAF_PROTOTYPE_WORKSPACE_OWNERSHIP=1 and an
absolute CODEAF_HOME, on Linux or macOS. Ordinary chats keep landing delegated work exactly as dev does. See
Takeover changes at the end.

Summary

Delegated work now owns its private folder layout instead of relying on a model to place files correctly. A chat can use several working roots, exact cooperating tasks share one admitted layout, and unrelated work keeps separate copies. Each receiver maps roots explicitly before taking over.

chat/
  .cell/                    portable truth and task carriers
  trees/<run>/
    app/                    private primary copy
    library/                private sibling copy
  logs/                     owned history
profile/
  workspace-identities/     local URI bindings and ownership
  workspace-runtime/        owned temporary data
  workspace-caches/         explicitly shared project caches
  workspace-apply/          reviewed snapshots and receipts

These paths describe ownership roles. Opaque identities survive relocation; equal names or Git remotes do not combine roots or grant write authority. New conversations persist the private-task policy; legacy conversations retain their placement. Foreground editing keeps the explicitly opened folder, and home/reference tasks do not clone a home directory.

Relay verifies complete carriers, resolves each missing root through the actual folder picker, checks destination conflicts, and acquires against the displayed holder before adoption. Recovery distinguishes immutable incoming provenance from receiver-local checkpoint paths. Forking preserves results/history while detaching inherited execution. Reopened task cards recover their local worker transcript and recorded model, including completed runs without a local plan database.

/task review <number> <root> freezes one root; /task apply <number> <root> applies that snapshot to the admitted destination. The filesystem/Git transaction preserves supported raw bytes, CRLF, permissions, literal links and empty directories, checks affected-path/ref/index conflicts, and preserves unrelated staged/dirty work. Explicit reviewed Apply may target main; automatic protected-branch landing stays blocked. Unsupported metadata refuses before destination writes.

Evidence

Latest synchronization: ca7ede171 includes dev e88e49af2 (device-pairing UI). It merged without conflicts; local quick checks and focused pairing regressions pass. The live workflow evidence below remains pinned to d689b1621; it was not rerun for this synchronization. Latest-head CI passes all checks.

  • Before: nested worker history could be present after transfer while its task card reported no transcript/model. After: public history/roster regressions and genuine resident task-card readback show the retained journal and recorded model. A non-Unix redirected-parent regression also went RED → GREEN; ordinary history remains readable.
  • Scripted terminal: complete two-root work, restart, Take, independent fork/full history, second Take, Review/Apply, another restart, cross-platform transfer and genuine resident transcript/model readback passed in 170.87 seconds on d689b1621.
  • Actual model: the complete workflow passed in 207.49 seconds. All 27 completed OpenRouter responses independently reported deepseek/deepseek-v4.1-flash: 336,137 input + 14,664 output tokens, with $0.02407027 known upstream cost. An additional request was canceled before any response/model/usage metadata; this is not an independently audited account total. The worker built the two-root feature; restart, fork, both actual terminal Review/Apply operations and the received resident task card all passed.
  • Checks: implementation GitHub checks passed on d689b1621; the documentation-only follow-up b1d3caf34 passes local quick/link checks and its GitHub gate passes all checks. Quick/focused checks, the full Windows application cross-build and independent Standards/Spec reviews pass. Local session/TUI suites passed all eight shards each. Two command-fixture native teardown failures passed isolated diagnostic retries; they remain a local validation limitation. Native Windows runtime remains untested.
  • Dependency: ordinary builds embed released Furrow v0.3.2. All six artifacts were verified; four plain/Git × closed/quiescent-WAL cases preserve original source families. Capture stages private database/journal bytes; independently changing live writers are not an atomic-snapshot guarantee.

The acceptance matrix separates actual-model work from deterministic replay and platform checks:

User workflow Verification Result
Build across two admitted roots Actual model edits both private roots; independent feature check; original folders checked before Apply Pass; requested roots explicitly present in the tool proposal
Restart and receive Genuine engine restart, per-root folder selection and Take, retained task identity, full file/metadata readback Pass
Fork and continue independently Settled history/results retained, inherited execution detached, second Take Pass
Review and Apply each root Actual terminal Review/Apply, unrelated staged/dirty changes retained, another restart and recorded outcomes checked Pass
Cross-platform reopen Received archive reopened in a separate process; genuine resident task card displays retained worker transcript and model Pass; Take 4.17 s, reopen 0.10 s, no additional model requests

Deterministic replay covers the same complete workflow separately; it is not counted as live-model proof. Compatibility and special-metadata limits remain below.

Measurement Result Limit
Historical copied-workspace corpus: 131 roots, 118 safely compacted, 13 retained 20.60 → 11.67 GB allocated; 8.93 GB / 43.34% lower Isolated volume; originals untouched; original-host free-space reclamation is not claimed
Actual cold Take 5.355 seconds, 34,203 request-body bytes + 1,702,864 response-body bytes across 115 requests Two-root fixture; excludes headers/TLS and has no matched savings baseline
Matched warm transfer 55.17% lower materialization latency; 5.33% fewer HTTP body bytes About 11% more encrypted payload; distinct from terminal paint and storage size

These measurements do not establish a new multi-root savings percentage or a four-month automatic reclamation guarantee. The longer growth experiment was deferred. Generated test fixtures, task worktrees and task-specific build/download caches were removed; originals and shared caches were preserved. Genuine terminal captures and detailed receipts remain local: direct PR media attachment upload was unavailable, so no substitute evidence branch or repository directory was published.

Merge Danger

Door: One-way for new portable metadata.

New records require supported readers at both ends; rolling back the executable does not migrate them. Legacy records are preserved. Guaranteed early refusal by older clients remains unfinished, so mixed-version operation is not claimed safe.

Blast Radius: Storage.

This touches delegated placement, portable history, relay adoption and explicit application to working files. A model can omit a requested root from its proposal; omitted roots are not silently granted. One earlier incomplete proposal was canceled after the sibling-write guard refused it; it is not counted as a passing live run. URI association is separate from application permission. Shell placement is not an OS sandbox. Originals and uncertain writers remain protected; multi-root retirement stays excluded until whole-layout writer fencing and recovery are verified. External-process continuation and every filesystem's special metadata are not guaranteed.

Agent workspace, relay and migration contract.

Takeover changes

Merged current dev, so this now sits on top of the Raft relay (#1950) and the two-computer fixes (#1967). Seven
conflicts were resolved:

  • In the move path, every take records the send lease, including the workspace-set and identity-adopting restores.
  • A removed computer can't take through the folder mapping.
  • The typed words and the pending send survive the root chooser.

Frame hints ride the Raft relay. After Raft, the directory record types are aliases of the replicated state
machine's types, which decode a device's signed body strictly. So FrameHint and frame_hints now live on
clusterstate Cell, CellInit and Publish:

  • the set is bounded deterministically, and an invalid set is dropped rather than refusing the head;
  • listings omit the hints, and single-cell reads keep them;
  • existing canonical bytes are unchanged, and no schema or protocol version moves;
  • they stay off by default.

A critical review found three problems with the new default for every new chat:

  • Every delegated task stayed in a private copy until /task apply.
  • Apply always refuses on Windows.
  • An older build taking such a chat drops its tasks.

So the policy is now opt-in. A new chat persists it only with the switch on, on a platform where Apply works. An
identity alone no longer enables ownership. Without the switch, chats keep version-1 checkpoints and carriers. The
manual sections about private copies say they need the switch.

Other fixes:

  • Apply refuses before any write when the profile and the project's Git index are on different disks.
  • A removed computer keeps working on chats it held or never shared. This was a regression from Two computers: continue a moved chat, clean leader quit, removed-device wording #1967.
  • A move that fails because the other machines are unreachable now says, in the chat and on Home, that the chat stayed
    where it was and the words are still in the box.
  • The activity page lists a chat once, and a finished task no longer reads incomplete.
  • A moved task's worker transcript reopens.
  • ApplyTaskWorkspaceRoot was split to stay under the task engine's decision ceiling.

Verification:

  • CI is green on this head.
  • Two full real two-computer rounds (Windows PC under WSL plus a Mac, a LAN relay, real models) covered:
    • pairing and moves both ways;
    • a take after a kill, and leadership plus a clean quit while leading;
    • revoke, and a forced failed move with the relay stopped;
    • a delegated task in an ordinary chat landing on its own branch with no slash command, and the moved chat
      reopening on the other computer.

Follow-ups filed: #1982, #1984, #1985, #1986.

@santoshkumarradha
santoshkumarradha marked this pull request as ready for review October 25, 2026 21:43
@santoshkumarradha
santoshkumarradha marked this pull request as draft October 25, 2026 21:48
@santoshkumarradha
santoshkumarradha removed the request for review from AbirAbbas October 25, 2026 21:48
@santoshkumarradha santoshkumarradha changed the title docs: workspace storage, relay architecture and migration Own task layouts and transfer multi-root chats safely Oct 25, 2026
@santoshkumarradha
santoshkumarradha marked this pull request as ready for review October 26, 2026 05:41
santoshkumarradha and others added 10 commits October 26, 2026 01:58
…urrow v0.3.4

Brings the workspace-ownership branch up to dev cf282dd, which adds the
Raft relay (#1950), the two-computer fixes (#1967), #1972, #1974 and #1976.

- directory record types are now clusterstate aliases, so frame hints move
  into the replicated state machine: FrameHint and the frame_hints field on
  Cell, CellInit and Publish, bounded deterministically in the shared rules,
  dropped from listings and kept on single-cell reads. Signed v1 publishes
  with hints are accepted; unknown fields are still refused; existing
  canonical bytes are unchanged and no schema or protocol version moves.
- every take path records the send lease, including the workspace-set and
  identity-adopting restores; an already-held chat keeps its hold when the
  record fails.
- a removed computer cannot take through the folder-mapping road either, and
  unsent words and the pending send survive the root chooser.
- the seal refuses a folder holding home before taking the checkpoint lock.
- furrow pin follows dev at v0.3.4, which contains v0.3.2's non-mutating
  SQLite capture.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d in

New conversations persisted the private-task policy unconditionally, so every
delegated task ran in a private copy that only /task apply could bring home,
Apply refused on Windows, and older builds that took such a chat dropped its
tasks. A new conversation now persists the policy only with
CODEAF_PROTOTYPE_WORKSPACE_OWNERSHIP=1, an absolute CODEAF_HOME and a platform
whose Apply works; a saved workspace identity alone no longer enables private
placement; and a saved policy keeps working on Linux and macOS. In a chat with
no private copies, /task review and /task apply say so and change nothing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…write

Apply hard-links its owned Git index from the profile's transaction folder
into the project's .git, which fails as a busy index when the two live on
different filesystems. Apply now compares the devices first and refuses with a
plain sentence before staging, locking or touching the destination.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every manual section about private task copies, Review/Apply, workspace roots
and the folder mapping on a move now opens by saying it applies only with the
experiment switch on Linux or macOS, so the ordinary landing pages stay the
answer for ordinary chats. The relay and architecture references agree that
private workspaces are implemented and opt-in, and name their compatibility,
cost and platform limits. Source comments describe behaviour, not tools.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A window that learned its computer had been removed refused every send before
looking at the chat, so even a new chat opened with /new could not reach the
model. Removal now decides like an unreachable service: a chat this window
held, or one never shared, goes on here only; a chat another computer took
stays read-only with the removal sentence.

A move that failed because the other machines could not be reached said only
"other machines unreachable". It now says the chat could not be continued
here and that the words are still in the box, as every other failed move does.

Also rewrites the #1944 change entry against dev rather than against the
branch's own earlier default.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…pply

The ordinary-chat explanation pushed ApplyTaskWorkspaceRoot past the task
engine's decision ceiling. Review and Apply now share one door check, and the
read-root and already-applied refusals live in their own function. Also
shortens the change entry's title to one line.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…reachable

A move that failed because the other machines could not be reached put the
full sentence in the chat's own tab, but the window lands on Home, and Home
said only "other machines unreachable". Home now carries the same sentence:
the chat stayed where it was and the words are still in the box.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The activity page took a chat's own row identity from the folder holding its
transcript, which in the cell layout is the chat's internal state folder, so a
chat with a finished task appeared twice and one row read the stale index as
"incomplete". The row now uses the chat's own folder. A transferred run whose
worker journal kept the fixed worker name could not reopen its transcript;
history lookup now accepts that verified journal too. The worker manual no
longer claims finished runs stay on the sidebar: they live in Tasks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AbirAbbas AbirAbbas changed the title Own task layouts and transfer multi-root chats safely Private task copies (opt-in), frame hints through the Raft relay, and two-computer fixes Oct 26, 2026

@AbirAbbas AbirAbbas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took over for Abir: the merge with dev, the opt-in gate and the review fixes are in. CI is green, and two real two-computer rounds pass.

@AbirAbbas
AbirAbbas merged commit ff5543f into dev Oct 26, 2026
9 checks passed
@AbirAbbas
AbirAbbas deleted the docs/workspace-relay-architecture branch October 26, 2026 23:52
AbirAbbas added a commit that referenced this pull request Oct 27, 2026
…and six rough edges (#1990)

Fixes everything the real two-computer relay tests found after #1944, and what three further real PC + Mac rounds found on the way.

- A take-back after a kill reaches its first acquire in about a second; ordinary chats restore once, after the lease. A copied chat can move back and forth any number of times, and a killed computer takes its chat back on the first try.
- /quit waits for the final publish and release. Only a live hold sends without asking the relay; a displaced window raises the continue card on the next Enter and can never fork the chat. A removed computer keeps working in its own chats.
- Words typed while /new opens, sent through a card, or left by a failed take land exactly once in the right box; drafts are keyed per chat.
- Sealing recovery is claimed only when this chat's turns are saved, a stuck store gets a plain sentence, a failed final save names where the turns are kept, and closing never freezes the window. Embedded furrow 0.3.5 removes only its own socket.
- A moved finished task opens read-only with its steps and worker transcript.
- Plain sentences for cluster status, devices and pairing when the relay is down or slow; the holder says when it is not syncing; Home never offers this computer's own chat.

Closes #1982, #1984, #1985, #1986.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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