Repository navigation
feat(node): clone from Git Server snapshots, collaborate through ora-git and deliver Revisions over Git - #681
Conversation
58325d5 to
c1cd3a6
Compare
EricWvi
left a comment
There was a problem hiding this comment.
desktop 的 docs/ 已在 #686 按主题重建,旧路径都已删除。新结构和维护规则见 docs/README.md,要点:
- 每个主题有英文
x.md和中文x.zh.md两版,同一个改动里一起更新,英文只链接英文、中文只链接中文; - 新主题放进对应目录,并在
docs/README.md和docs/README.zh.md的地图里各加一行; - 行为变化在同一个 PR 里更新对应文档;
- 不写进度、计划和验收结果,
proposed或尚未实现的决策不写成已实现。
本 PR 需要按新结构适配:
本 PR 没有改文档,但改变了 Node 的 clone 来源和 Revision 交付方式:从 Git Server 快照 clone,经 ora-git 协作,交付改走 Git,并删除 bundle。现在的文档描述的还是旧行为,需要在同一个 PR 里一起更新:
- docs/node/repository-clone.md:clone 来源;
- docs/node/revisions.md:交付、上传与恢复前序 Revision,目前写的是 bundle 和对象存储上传;
- docs/controller/agent-relay.md、docs/controller/cloud-contract.md、docs/node/protocol.md 中 Revision 交付、上传授权和 bundle 的部分;
apps/ora-git如果是新程序,需要在合适的目录写文档,并加进两份地图。
以上都要中英两版。相关 ADR decisions/node/revision/20261012-push-delivery-ref-and-fetch-prior-revision.md 目前是 proposed,PR 描述里请写明 ADR 状态。
…shots Point third_party/cloud at the contract commit that replaces CloneSpec with the snapshot input, delivers Revisions over Git without bundles, and adds the session Workspace directory; regenerate the controller client. The commit sits on current Cloud main, so the client also gains main's WorkspaceOperationService.RecordProvisioningFact; the Controller does not call it yet, and the Workspace test Cloud answers it as unimplemented.
… Git
Replace the clone input with the snapshot input {repository_url,
snapshot_ref, base_commit, workspace_ref}, validated when decoded; a
snapshot ref must be named after the base commit and CloneReady must
report exactly that commit. Add snapshot_unavailable and
base_commit_mismatch; branch_not_found only remains in history.
Deliveries push to a delivery ref and fast-forward the Workspace branch:
DeliverRevision drops the bundle key and carries the repository, the
delivery ref and the Workspace ref; RevisionDelivered drops its bundle;
push_rejected and push_failed replace bundle_failed. A resumed session's
prior Revision names its delivery ref and base commit instead of a bundle,
the download grant exchange is removed, and sessions carry the Project's
Workspace directory for ora-git list.
…cate TLS Serve smart HTTP through git http-backend behind TLS that requires a client certificate, enforce the Git Server's update rules for Workspace branches and delivery refs, and let tests inject HTTP statuses, pause the listener and inspect the Ora-Execution-Id of every request.
…values Split clone progress into the Node's snapshot fetch, whose passes are counted before each starts, and the workload's fixed checkout sequence, one recorded command at a time; completion attributes success, failure or interruption to the current command after the earlier ones exited 0. Schema v10 adds the ledger of each checkout's last known own Workspace branch values and exposes a successful clone's checkout with its input. Records of the earlier clone and delivery shapes are not migrated.
Forward the clone step's frozen clone_input verbatim to RecordDispatch and the Node, and stop the step without dispatching when it is missing or the Node protocol refuses it. Take over a ready clone only when its commit is the input's base commit. Remove the tenant-level ClaimWork clone branch and the local CloneIntake and ControllerHandle intake. Map the Git-delivery inputs and results, forward the session's prior Revision and Workspace directory, remove the download grant relay, request upload grants for the history key only, and check delivery terminals against the base, Revision ref and history key.
Runners with time budgets pick one per command intent. A caller whose limit differs (a 30-minute delivery push, a shared restore deadline) now states it on the command; runners without budgets ignore it.
A session stops running for work done on its behalf as soon as an EndSession is accepted, not only once its terminal result is written, so ora-git can refuse requests of a session that is being ended.
ora-git is the Agent's only way to reach the Git Server: info, list, fetch upstream, fetch workspace and push, with no options, refspecs or URLs. It sends one JSON line on the session socket named by ORA_GIT_SOCKET and maps the Node's answer to stable stderr codes and exit statuses. A socket that is gone, or that closes before answering, means the session is no longer running (no_session).
…ver Git The Node reaches the Git Server only as itself, from private bare transport repositories under <repository_root>/.ora-transport/ that borrow a checkout's objects as data; the git-access certificate and the execution header exist only on each command line. - Clone fetches the frozen snapshot ref, checks it is base_commit, and builds the checkout as the workload user with init, a local fetch from the transport and a reset: no remote, full history, the Workspace branch at base_commit. Fetch passes are durable and capped at three across restarts; a clone whose workload sequence still reads its transport keeps it over a restart. SSH and deployment credentials are gone (clone.ssh is no longer a configuration field). - Delivery pushes the frozen final commit to its delivery ref (also when unchanged), then fast-forwards workspace_ref with the ledger's old value without ever failing the delivery, and uploads only the session JSONL; each push attempt may take 30 minutes. Bundles are no longer built, uploaded or downloaded. - Restore fetches the prior delivery ref within one five-minute deadline, moves the Workspace branch to the prior final commit, and notes a prior base outside this snapshot's history. A Node stop or an EndSession during the restore cancels it and waits for its Git before the session ends. - Clone, delivery and restore are declared only with git_access, which a Cloud Node must have (git_access_required).
With agent.ora_git_directory set (and git-access configured) the Node clears that directory at start and opens one random socket per running session, exported to the agent plugin as ORA_GIT_SOCKET. A request belongs to the session of the socket it arrived on; the peer must be the workload UID, and one request per session runs at a time (busy). - info, list (with the session's Workspace directory), fetch upstream, fetch workspace and push run as the Node from a per-request transport repository that borrows the checkout's objects; the checkout is only touched by the workload user's hardened Git, which writes nothing but refs/remotes/ora/** and objects. - Pushes declare the ledger's last known value of the session's own Workspace branch, refuse a non-fast-forward locally, report conflict with the remote value, and treat a stale lease already at the pushed commit as a replay that succeeded. - Requests fail as no_session once the Node stops, an EndSession is accepted or the session ended. When the session leaves the runtime the socket refuses new requests at once but waits for a running one and its answer before the session is recorded as ended.
[write], [commit], [push] and [fetch <ws>] run in task order, only from the first prompt's task (never from appended context): commit as the fixed echo identity, push and fetch through ora-git, and report each result in the reply. The host-spawned commit marker becomes [commit-host]. A standalone test drives the markers through the real session socket and Git Server double.
Node clones now come only from Git Server snapshots through a transport repository, so nothing builds a single-branch clone of an external repository any more.
The Node image builds ora-git with the Node and installs it at /usr/local/bin/ora-git, where the Agent's processes find it; the socket directory comes from the Node configuration (agent.ora_git_directory). The container image docs say so.
The client used std::os::unix::net unconditionally, so the workspace stopped compiling on Windows. The Node serves the socket only in Linux Agent sandboxes: on other platforms send() now reports internal without connecting, and the socket tests run only on Unix. The request, reply and error types stay portable for the protocol crates.
The double uses Unix file modes, so enabling git-server broke the Windows build, and on macOS Git refused the push made with the PEM client identity it issues. Its only consumers are the Node's Linux-only tests, so the module is compiled for Linux alone instead of half-working elsewhere.
The echo agent exec'd the ora-git binary beside it, but cargo test builds only the tested package's binaries, so on a clean runner target/debug/ ora-git did not exist and the collaboration marker test got no reply. The CLI entry point moves into the ora_git library, the binary only calls it, and the fixture runs it as `<fixture> ora-git <args>`, so the test runs the same CLI in whatever order Cargo builds.
Rewrite the repository clone and Revisions pages in both languages for the Git-native line: the Git Server snapshot input, the private transport repository and the workload checkout without a remote, fetch passes and failure codes, delivery to the delivery ref with a best-effort Workspace branch fast-forward, the history-only upload and restore from the prior delivery ref. Add an ora-git page (sockets, verbs, pushes, exit codes) to both documentation maps, and bring the Controller, Agent relay, Cloud contract, protocol, Node, Agent session, testing and architecture pages in line: no local clone intake, the frozen clone input, no bundles or download grants, schema v10 and the Git Server test double.
c1cd3a6 to
9de7649
Compare
A 401 only says the Node's own git-access material failed to authenticate; it says nothing about whether the prior delivery ref exists. Restore now reports it as prior_revision_unavailable instead of prior_revision_base_unavailable, without retrying within the deadline, since the same material cannot pass. 403, other 4xx and a missing delivery ref stay base_unavailable. Git never prints a 401 as a status: with no credential helper and prompts disabled it stops at "could not read Username", which the classifier did not recognize, so every caller retried a 401 as an unavailable server. GitServerFailure gains Unauthenticated for that wording; snapshot clone (SnapshotUnavailable), delivery pushes (push_rejected, no retry) and ora-git (denied) map it as they map a refusal.
Git prints a 404 on the ref advertisement as "repository '...' not found" rather than as a status, so the classifier took it for an unreachable server and retried it. It is a 4xx other than 401 and 429, which Node delivery push ADR D6 files with refusals: restore reports prior_revision_base_unavailable, and the other callers stop at once as they do for a 403.
Each fetch pass was counted durably, up to three, but every pass also retried an unreachable Git Server three times on its own, so a clone could fetch nine times before failing. Node clone ADR D4 now has the in-run retries and the refetches after a restart share one persisted count capped at 3. The clone state machine makes the retries itself: a fetch step makes one attempt through single-attempt Git Server access, an unavailable server hands out a backoff step (5 s, then 30 s), and the next attempt is counted in the Fetching phase before it leaves the database owner. The wait itself is not recorded, so a restart starts the next attempt at once. 401, 403 and a missing ref still end the clone without a retry; delivery pushes and restores keep retrying within their calls.
Cloud now reserves REVISION_FAILURE_REASON_BUNDLE_FAILED like BRANCH_NOT_FOUND (cloud a51ee11): under the breaking switch to Git-native delivery no Node can report it, and old records are not migrated. third_party/cloud moves to that commit, the controller client is regenerated, and RevisionFailureCode::BundleFailed goes with its Controller mapping, the retired-failure validation error and their tests; a result naming bundle_failed is now an unknown code.
The Node ADRs behind snapshot clone, ora-git and Git delivery are now approved, not yet implemented; the Revisions, repository clone and ora-git pages say so next to their links. Revisions file a restore-time 401 under the retryable prior_revision_unavailable while 403, other 4xx and a missing delivery ref stay base_unavailable; repository clone describes the single durable count of three fetch attempts shared by in-run retries and restarts; ora-git notes that a WorkflowRun's Agent session gets denied from every verb that reaches the Git Server.
wanglongan587
left a comment
There was a problem hiding this comment.
审查结论:Request changes
审阅 commit:bdc81880(对应 specs#111 已合并的 Node/Controller ADR,状态均为 approved)。
clone 输入与传输仓库、ora-git 的固定动词与 socket 身份、交付推送与恢复、Controller 原样转交、node-db v10 与账本都与 ADR 一致;测试使用真实 Git 与自签客户端证书的 Git Server 替身,没有替换生产实现。以下两处需要修正:
阻塞
-
恢复前序时没有核对仓库地址。
apps/ora-node/src/revision/restore.rs:133直接使用prior.git_repository_url发起 fetch;apps/ora-node/src/session/resume.rs:38-45只构造请求,协议也只校验地址形状。- ADR
decisions/node/revision/20261017-push-delivery-ref-and-restore-from-git-server.mdD5 第 1 步要求该地址“等于本 checkout clone 记录中的仓库地址”;ci-snapshot不变量 10 也要求两份输入指向同一仓库。 - 影响:Cloud/Controller 缺陷或
repository_changed后仍带前序时,Node 会向另一个 https 仓库发起携带 git-access 客户端证书与Ora-Execution-Id的请求;Git Server 通常返回 403,被归为prior_revision_base_unavailable,永久标记该 Revision 不可续作,而不是在本地拒绝。 - 修正:在创建传输仓库/发起 fetch 之前比较
prior.git_repository_url == checkout.spec.repository_url,不等时按RestoreFailure::Unavailable结束且不访问 Git Server;补一个测试。
-
agent.ora_git_directory未校验就递归删除。apps/ora-node/src/ora_git.rs:123对该配置目录执行remove_dir_all(失败时逐个删除子项),随后set_permissions(0711)并重建;apps/ora-node/src/service.rs:114-115只是配置字段,apps/ora-node/src/service/agents.rs:65-116只校验workload_directory。- 影响:部署把该值误配为
/run、Node home、clone root 的父/子路径或属主不对的目录时,Node 会以 Node/root 身份删除并重建不属于它的目录树。仓库对workload_directory的规则(绝对路径、属主是 Node、其他人不可写、不与 Node state/host/clone root 重叠)应同样适用于它。 - 修正:在
agents::validate中校验该字段,并尽量只清理本 Node 创建的 socket 文件,不对未知树调用remove_dir_all;补测试。
合并与流程
- 当前 head 落后 main 5 个提交;PR 描述里的单测结论是
1ce9a17,不是bdc81880。修完后合并 main、重跑task test:crates,并在描述里更新验证范围。 - cloud#81 合并后按描述把
third_party/cloud改锁到合并后的 commit 并重新生成;这会改变 head,需要重新请审。 - 落地 specs PR(五篇 ADR →
implemented+ 核心用例证据)在 review 通过后、合并前开出。
建议(不阻塞)
DestinationConflict在目标目录已存在时不会产生(apps/ora-node/src/repository/drive.rs:287-289走 unknown),这是 main 已有行为,但与本 ADR D3 的失败码表不一致;如果本 PR 不处理,请在描述里注明。- 交付 ref 推送成功后 Workspace 快进仍共用 3 次 × 30 分钟重试,且在上传 JSONL 之前;ADR D2/D4 要求沿用同一分类与时限,但最坏情况可能挤压放弃窗口,请在描述里说明该取舍。
审查范围基于 bdc81880;上述两条修正后会按新 head 重新审。
…toring Node delivery push ADR D5 step 1 requires the prior Revision's repository to equal the checkout's clone record; any other address now ends the session as prior_revision_unavailable without contacting the Git Server.
…sockets The directory is checked like the workload directory before the Node starts (absolute, Node-owned, unreadable and unwritable by others, under a trusted parent, overlapping no managed directory), and startup no longer deletes the tree: it removes only sockets named as the Node names them.
wanglongan587
left a comment
There was a problem hiding this comment.
复审结论:Approve(针对 head b2962ccd;合并前仍需追平与改锁)
审阅 commit b2962ccd。本轮只读复核上一轮三项意见和合并 main 的结果,没有重跑 task test:crates。
逐项核对
- 恢复前核对仓库地址(
c4821bc0):apps/ora-node/src/session/resume.rs在构造RestoreRequest之前比较prior.git_repository_url与checkout.spec.repository_url,不等时以agent_failed{prior_revision_unavailable}结束,不调用恢复器。测试a_prior_revision_from_another_repository_is_refused_before_any_restore断言恢复器请求 0、无插件进程、无 ledger 事件、租约 0;中英docs/node/revisions同步。Cloud 侧selectPriorRevision已保证前序与本 checkout 来自同一 Git Server 地址(不同时以repository_changed跳过),这个 Node 侧检查是有效的纵深防御。 agent.ora_git_directory校验(d05029f5):绝对 UTF-8、无..;已存在时要求 Node 属主且 group/other 不可读写(/run、/tmp会被拒);不存在时要求父目录由可信属主控制;与 Node home、host 目录、clone root、workload 目录的双向重叠都拒绝。启动不再remove_dir_all,只删“确实是 socket 且名字为<32 位小写 hex>.sock”的项,其他内容保留。底层ora_utils::path::open_trusted_path使用O_NOFOLLOW,release 构建还要求祖先不被 group/other 写入。serve_refuses_an_ora_git_directory_that_is_not_the_nodes_alone覆盖七种拒绝与两种接受,the_socket_directory_loses_only_the_sockets_an_earlier_node_left证明非 Node 命名的文件与 socket 都保留;中英docs/node/ora-git同步。校验在serve启动时(agents::validate)执行,早于OraGitService::new;没有 git-access 时不会创建或清理该目录。- 合并 main:
07ec7a08合入3fa5fc03,没有冲突;third_party/cloud仍按描述锁a51ee11。描述里的单测结论已更新到b2962ccd。
合并前必须满足
- 改锁与重新生成:cloud#81 合并后的 proto 含 main 的
agent_configuration,而a51ee11没有——这正是本轮全栈验收只能用 cloud3b0a151的原因。cloud#81 合并后把third_party/cloud锁到合并后的 commit、重新生成 client,并合并 main(当前落后 23 个提交)。 - 重跑门禁与最终三仓验收:改锁后的 head 上重跑
task test:crates(含lint:crates、云契约检查);最终三仓 head 上重跑 workspace-git、revision、revision:resume、agent:session、runtime、cross-line,建议补plugin:acceptance(插件派发受 #84/desktop#698 影响)。 - 追平并 push 后重新打
status:in-review(会清掉review:lgtm),我按增量复审;不要用本轮 lgtm 合并追平后的 head。
说明
- 一处可选观察:
prior_revision_unavailable在 Cloud 的refuseResumedRevision里仍按可重试处理,而本 Node 的“仓库地址不一致”是确定性失败。因为 Cloud 已保证地址一致,这只会出现在防御路径上;若希望不再重复选中,可让 Cloud 也把该原因当作需要拒绝的原因,或在 Node 侧记录告警。不阻塞。 - 没有发现新的代码缺陷;其余都是合并前的机械步骤。
Re-pin third_party/cloud to ora-space/cloud#81 6468f01, which carries main's contract (agent_configuration, Thread previews) next to the Git line's, and regenerate the client. Main's new Thread-preview code drops the retired download-grant relay; its preview tests use the Git Server fixture and the session spec's workspace directory; the duplicate record_provisioning_fact stub keeps main's.
Move third_party/cloud from 6468f01 to 4e5e00f, the head of ora-space/cloud#81 after its last merge of Cloud main. The proto is unchanged between the two, so the generated client is identical.
Move third_party/cloud from 4e5e00f to 7a1a2af, the head of ora-space/cloud#81 after its latest merge of Cloud main. The proto is unchanged, so the generated client is identical.
Implements the Node and Controller side of the internal Git line (Git Server ⇄ Node) of Ora's Git-native Project code: Workspaces clone from a Git Server snapshot, Agents collaborate through
ora-git, and Revisions are delivered and resumed over Git. Bundles are removed.Refs ora-space/circus#183
Status and merge order (please read first)
The governing ADRs are
approved(ora-space/specs#111 merged), not yetimplemented:decisions/node/repository/20261016-clone-from-git-server-snapshot-and-ora-git.mddecisions/node/revision/20261017-push-delivery-ref-and-restore-from-git-server.md; it supersedesdecisions/node/revision/20261012-push-delivery-ref-and-fetch-prior-revision.md, so this PR does not implement the 20261012 onedecisions/cloud/controller-integration/20261016-snapshot-clone-input-and-execution-ref-grants.md, which supersedescloud/controller-integration/20261012-git-delivery-inputs-without-bundle-grants.mddecisions/cloud/revision/20261017-git-native-delivery-refs-and-resume.mdA landing run opens the specs PR that moves these ADRs to
implementedbefore the product PRs merge; it merges after them.The foundation has merged (feat: Git Server foundation for the Project code hub (rule sets, Bindings and Operations, service listener, preset tool) cloud#75, ora-space/cluster#26, contract ADR ora-space/specs#107).
Lands together with the cloud and cluster PRs of the same line (feat: clone Workspaces from Git Server snapshots and deliver Revisions over Git (internal Git line) cloud#81, ora-space/cluster#29). Node protocol, Controller and Cloud contract change in one breaking switch; old and new Nodes/Controllers cannot be mixed.
Contract pin:
third_party/cloudpins cloud7a1a2af, the head of feat: clone Workspaces from Git Server snapshots and deliver Revisions over Git (internal Git line) cloud#81 after its final catch-up with Cloudmain; it carriesmain's contract (agent_configuration, Thread previews) next to the Git line's. It exists only on the forkObsisMc/clouduntil cloud#81 merges; after that, re-pin to the merged commit on ora-space/cloud main (proto identical) and regenerate.This round (after the ADR review)
New commits on top of
9de7649, nothing rewritten:47c5ffbfix(node): a restore-time 401 ends the session asprior_revision_unavailable(resumable), not retried within the deadline; 403, other 4xx and a missing delivery ref stayprior_revision_base_unavailable(node/revision D6).GitServerFailuregainsUnauthenticated; clone (SnapshotUnavailable), delivery push (push_rejected, no retry) and ora-git (denied) map it like a refusal. Git never prints a 401 as a status here (it stops atcould not read Username ... terminal prompts disabled), so before this every caller retried a 401 as an outage.fcc69fffix(node): Git prints a 404 asrepository '...' not found; it is now a refusal instead of a retried outage.2a15c4afix(node): clone snapshot fetch retries within a run and refetches after a restart share one persisted count, capped at 3 (node/repository D4; was up to 9). The state machine makes the retries itself (5 s, 30 s backoff steps); a restart starts the next attempt at once.2d02addfeat(protocol)!: deleteRevisionFailureCode::BundleFailed, its Controller mapping and the retired-failure validation error; re-pinthird_party/cloudtoa51ee11and regenerate the client.1ce9a17docs(node): Revisions, repository clone and ora-git pages (both languages) mark the ADRsapprovedand describe the 401 rule, the shared fetch count and that a WorkflowRun's Agent session getsdeniedfrom Git Server verbs.The ora-git socket permissions were already
0711(directory) and0666(socket), as node/repository D5 requires.Second review round
New commits on top of
bdc81880, nothing rewritten:c4821bc0fix(node): a session'sprior_revision.git_repository_urlmust equal the repository in the checkout's clone record (node/revision 20261017 D5 step 1). Any other address ends the session asagent_failed{prior_revision_unavailable}before the restorer runs, so the Git Server is never contacted and no plugin starts (a_prior_revision_from_another_repository_is_refused_before_any_restore). Docs:docs/node/revisions(both languages).d05029f5fix(node):agent.ora_git_directoryis validated before the Node starts, with the workload directory's rules: an absolute UTF-8 path below the root without..; either missing (the Node creates it, under a parent only trusted owners control) or a Node-owned directory nobody else can read or write, so/runor/tmpare refused; and overlapping neither the Node home, the host directory, the clone root nor the workload directory. Startup no longer runsremove_dir_all: it removes only entries that are sockets named as the Node names them (<32 hex>.sock) and leaves everything else (serve_refuses_an_ora_git_directory_that_is_not_the_nodes_alone,the_socket_directory_loses_only_the_sockets_an_earlier_node_left). Docs:docs/node/ora-git(both languages).07ec7a08merge ofmain(no conflicts);b2962ccdpins the tempdir mode in the new refusal test.The
third_party/cloudpin stays ata51ee11until ora-space/cloud#81 merges; its contract is unchanged by this round.Final catch-up with
main2f828ed6merge ofmain: re-pinsthird_party/cloudto feat: clone Workspaces from Git Server snapshots and deliver Revisions over Git (internal Git line) cloud#816468f01and regenerates the client (main'sagent_configurationand Thread-preview contract). Main's new Thread-preview code drops the retired download-grant relay; its preview tests use the Git Server fixture and the session spec's workspace directory; the duplicaterecord_provisioning_factstub keeps main's.c580d27cmerge ofmainat3eaeddf9(no conflicts).f3fd0ebcre-pinsthird_party/cloudto cloud#814e5e00f. The proto is identical to6468f01, so the generated client does not change.e45416bfmerge ofmainatb7f98e4f(feat(plugin-sdk): add confirmed model adapter startup contract #703, fix(process): wake coordination when scope close is accepted #709; no conflicts).c08770edre-pinsthird_party/cloudto cloud#817a1a2af, its head after the latest catch-up; proto identical again, client unchanged.What changes
Clone from a snapshot.
CloneExecutionSpecis{repository_url, snapshot_ref, base_commit, workspace_ref}(old shape rejected). The Node fetches the snapshot ref into a private transport repository with its git-access certificate (material only on the command line, hardened config, https only), then builds the checkout as the workload user from that repository. The checkout has no remote and no credential configuration; HEAD must equalbase_commit. New failure codesSnapshotUnavailableandBaseCommitMismatch. The fetch phase is redone after a restart (at most 3 passes); clone transports still in use survive a Node restart.ora-git. A fixed-verb command (info,list,fetch upstream,fetch workspace <id> [<branch>],push [<branch>]) on the workloadPATH. Each Agent session gets its own Unix socket (ORA_GIT_SOCKET); identity comes from the socket andSO_PEERCRED, never from the request. Pushes only reachrefs/heads/workspaces/<own workspaceId>/, with the old value from the Node ledger, a local non-fast-forward check and stable exit codes (usage2 …internal11).listannotates branches with the session's Workspace directory.Delivery over Git. The final commit is pushed to the delivery ref (also for unchanged runs), then the Workspace branch is fast-forwarded best-effort (never fails the delivery); only the session JSONL is uploaded. 30-minute limit per push attempt; 3 attempts with 5 s / 30 s pauses for 5xx and network errors.
Resume over Git. The prior final commit is fetched from its delivery ref (5-minute shared deadline, stops on cancel), the Workspace branch is moved onto it, and a hint is appended when the prior base is not in the snapshot's history.
Controller. Forwards the frozen
clone_inputverbatim, refuses aCloneReadywhose commit is notbase_commit, no longer claims tenant-level clones, and dropsCloneIntake, the local clone intake and the download-grant relay.Removed: bundle generation, upload and download; SSH clone configuration; the unused branch clone builder.
Platforms:
ora-git's socket client and the Node features using it are Unix/Linux-only (on other targetsora-gitanswersinternal); the client-certificate Git Server test double builds only on Linux.Config: Cloud mode requires
git_access(git_access_required);agent.ora_git_directory(e.g./run/ora-git) enablesora-gitsockets.Docs (both languages, in the rebuilt
docs/structure): rewrittendocs/node/repository-cloneanddocs/node/revisions; newdocs/node/ora-git, added to both documentation maps; updateddocs/controller/agent-relay,cloud-contract,controller,docs/node/protocol,node,agent-sessions,docs/operations/container-images,docs/development/testinganddocs/architecture.Breaking switch
No feature flag and no migration of Node data: clone records use a new schema version, old checkouts are not reused, development Workspaces are recreated. A
revision-restores/directory left by an older Node is not cleaned.Verification
c08770ed(cloud pin7a1a2af):task proto:check(pin, cleanproto/, regenerated client with no drift) andcargo fmt --all -- --checkpass locally.task test:cratesis left to this PR's CI (pr-tests.yml); the full-stack acceptance has not been rerun on this head yet (see "Before merge").b2962ccd(cloud pina51ee11):task test:cratespasses: 2506 passed, 0 failed, 5 ignored across 138 suites.--internalsandbox networks), built from feat: clone Workspaces from Git Server snapshots and deliver Revisions over Git (internal Git line) cloud#81 at3b0a151, feat(node): clone from Git Server snapshots, collaborate through ora-git and deliver Revisions over Git #681b2962ccdand ora-space/cluster#293645159; 59 checks, all PASS:workspace-git:acceptancerevision:acceptancerevision:resume:acceptanceagent:session:acceptanceruntime:acceptancecross-line:acceptance(base + agent fixture + external Git + cross-line overlays)The acceptance uses cloud#81
3b0a151, the head before its merge of ora-space/cloud#84 frommain. ora-space/cloud#84 freezesagentConfigurationinto plugin install inputs, and a Controller built against an older contract drops it, so Cloud refuses the plugin dispatch (dispatch ownership conflict). #698 fixed this on desktopmain, and this PR now carries it.Before merge
The three PRs have caught up with
maintogether: ora-space/cloud#81 at7a1a2af, #681 atc08770edand ora-space/cluster#29 atb59d700. Still to do before the owner merges:workspace-git,revision,revision:resume,agent:session,runtime,cross-line,plugin:acceptanceandopencode:m4:acceptance.implemented, core test case evidence) is open.Then cloud#81, desktop#681 (re-pinned to the merged cloud commit and regenerated) and cluster#29 merge in that order.
Not in this PR