Skip to content

feat(node): clone from Git Server snapshots, collaborate through ora-git and deliver Revisions over Git - #681

Merged
EricWvi merged 35 commits into
ora-space:mainfrom
ObsisMc:feat/183-internal-git-line
Oct 21, 2026
Merged

EricWvi merged 35 commits into
ora-space:mainfrom
ObsisMc:feat/183-internal-git-line

Conversation

@ObsisMc

@ObsisMc ObsisMc commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

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 yet implemented:

    • decisions/node/repository/20261016-clone-from-git-server-snapshot-and-ora-git.md
    • decisions/node/revision/20261017-push-delivery-ref-and-restore-from-git-server.md; it supersedes decisions/node/revision/20261012-push-delivery-ref-and-fetch-prior-revision.md, so this PR does not implement the 20261012 one
    • the Controller parts of decisions/cloud/controller-integration/20261016-snapshot-clone-input-and-execution-ref-grants.md, which supersedes cloud/controller-integration/20261012-git-delivery-inputs-without-bundle-grants.md
    • consumed from Cloud: decisions/cloud/revision/20261017-git-native-delivery-refs-and-resume.md

    A landing run opens the specs PR that moves these ADRs to implemented before 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/cloud pins cloud 7a1a2af, 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 Cloud main; it carries main's contract (agent_configuration, Thread previews) next to the Git line's. It exists only on the fork ObsisMc/cloud until 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:

  • 47c5ffb fix(node): a restore-time 401 ends the session as prior_revision_unavailable (resumable), not retried within the deadline; 403, other 4xx and a missing delivery ref stay prior_revision_base_unavailable (node/revision D6). GitServerFailure gains Unauthenticated; 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 at could not read Username ... terminal prompts disabled), so before this every caller retried a 401 as an outage.
  • fcc69ff fix(node): Git prints a 404 as repository '...' not found; it is now a refusal instead of a retried outage.
  • 2a15c4a fix(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.
  • 2d02add feat(protocol)!: delete RevisionFailureCode::BundleFailed, its Controller mapping and the retired-failure validation error; re-pin third_party/cloud to a51ee11 and regenerate the client.
  • 1ce9a17 docs(node): Revisions, repository clone and ora-git pages (both languages) mark the ADRs approved and describe the 401 rule, the shared fetch count and that a WorkflowRun's Agent session gets denied from Git Server verbs.

The ora-git socket permissions were already 0711 (directory) and 0666 (socket), as node/repository D5 requires.

Second review round

New commits on top of bdc81880, nothing rewritten:

  • c4821bc0 fix(node): a session's prior_revision.git_repository_url must equal the repository in the checkout's clone record (node/revision 20261017 D5 step 1). Any other address ends the session as agent_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).
  • d05029f5 fix(node): agent.ora_git_directory is 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 /run or /tmp are refused; and overlapping neither the Node home, the host directory, the clone root nor the workload directory. Startup no longer runs remove_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).
  • 07ec7a08 merge of main (no conflicts); b2962ccd pins the tempdir mode in the new refusal test.

The third_party/cloud pin stays at a51ee11 until ora-space/cloud#81 merges; its contract is unchanged by this round.

Final catch-up with main

What changes

  • Clone from a snapshot. CloneExecutionSpec is {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 equal base_commit. New failure codes SnapshotUnavailable and BaseCommitMismatch. 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 workload PATH. Each Agent session gets its own Unix socket (ORA_GIT_SOCKET); identity comes from the socket and SO_PEERCRED, never from the request. Pushes only reach refs/heads/workspaces/<own workspaceId>/, with the old value from the Node ledger, a local non-fast-forward check and stable exit codes (usage 2 … internal 11). list annotates 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_input verbatim, refuses a CloneReady whose commit is not base_commit, no longer claims tenant-level clones, and drops CloneIntake, 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 targets ora-git answers internal); 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) enables ora-git sockets.

  • Docs (both languages, in the rebuilt docs/ structure): rewritten docs/node/repository-clone and docs/node/revisions; new docs/node/ora-git, added to both documentation maps; updated docs/controller/agent-relay, cloud-contract, controller, docs/node/protocol, node, agent-sessions, docs/operations/container-images, docs/development/testing and docs/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

Suite Result Time
workspace-git:acceptance 26/26 401 s
revision:acceptance 2/2 110 s
revision:resume:acceptance 3/3 170 s
agent:session:acceptance 9/9 70 s
runtime:acceptance 8/8 126 s
cross-line:acceptance (base + agent fixture + external Git + cross-line overlays) 11/11 90 s

The acceptance uses cloud#81 3b0a151, the head before its merge of ora-space/cloud#84 from main. ora-space/cloud#84 freezes agentConfiguration into 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 desktop main, and this PR now carries it.

Before merge

The three PRs have caught up with main together: ora-space/cloud#81 at 7a1a2af, #681 at c08770ed and ora-space/cluster#29 at b59d700. Still to do before the owner merges:

  1. Rerun the full-stack acceptance on these heads: workspace-git, revision, revision:resume, agent:session, runtime, cross-line, plugin:acceptance and opencode:m4:acceptance.
  2. The landing specs PR (ADRs to implemented, core test case evidence) is open.
  3. A re-review of the catch-up.

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

  • Syncing external repositories into snapshots and publishing back (the external line); the acceptance uses the foundation's preset tool instead.

@EricWvi EricWvi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 里一起更新:

以上都要中英两版。相关 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.
@ObsisMc
ObsisMc force-pushed the feat/183-internal-git-line branch from c1cd3a6 to 9de7649 Compare October 19, 2026 02:50
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 wanglongan587 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:Request changes

审阅 commit:bdc81880(对应 specs#111 已合并的 Node/Controller ADR,状态均为 approved)。

clone 输入与传输仓库、ora-git 的固定动词与 socket 身份、交付推送与恢复、Controller 原样转交、node-db v10 与账本都与 ADR 一致;测试使用真实 Git 与自签客户端证书的 Git Server 替身,没有替换生产实现。以下两处需要修正:

阻塞

  1. 恢复前序时没有核对仓库地址。

    • 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.md D5 第 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;补一个测试。
  2. 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;补测试。

合并与流程

  1. 当前 head 落后 main 5 个提交;PR 描述里的单测结论是 1ce9a17,不是 bdc81880。修完后合并 main、重跑 task test:crates,并在描述里更新验证范围。
  2. cloud#81 合并后按描述把 third_party/cloud 改锁到合并后的 commit 并重新生成;这会改变 head,需要重新请审。
  3. 落地 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 wanglongan587 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

复审结论:Approve(针对 head b2962ccd;合并前仍需追平与改锁)

审阅 commit b2962ccd。本轮只读复核上一轮三项意见和合并 main 的结果,没有重跑 task test:crates。

逐项核对

  1. 恢复前核对仓库地址(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 侧检查是有效的纵深防御。
  2. 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 时不会创建或清理该目录。
  3. 合并 main:07ec7a08 合入 3fa5fc03,没有冲突;third_party/cloud 仍按描述锁 a51ee11。描述里的单测结论已更新到 b2962ccd。

合并前必须满足

  1. 改锁与重新生成:cloud#81 合并后的 proto 含 main 的 agent_configuration,而 a51ee11 没有——这正是本轮全栈验收只能用 cloud 3b0a151 的原因。cloud#81 合并后把 third_party/cloud 锁到合并后的 commit、重新生成 client,并合并 main(当前落后 23 个提交)。
  2. 重跑门禁与最终三仓验收:改锁后的 head 上重跑 task test:crates(含 lint:crates、云契约检查);最终三仓 head 上重跑 workspace-git、revision、revision:resume、agent:session、runtime、cross-line,建议补 plugin:acceptance(插件派发受 #84/desktop#698 影响)。
  3. 追平并 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.

@EricWvi EricWvi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

10-18 的意见已在 10-19 处理;owner 增量复审了追平 main 的冲突处理(b2962ccd..c08770e)。

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.

3 participants