Repository navigation
feat: clone Workspaces from Git Server snapshots and deliver Revisions over Git (internal Git line) - #81
Conversation
ef2340f to
5769b5e
Compare
EricWvi
left a comment
There was a problem hiding this comment.
main 已合入 cloud#85:docs/ 按领域整体重建为中英双语,文档地图在 docs/README.md,旧的 docs/*.md 已经全部删除。同时 cloud#62 已合入迁移 0038_agent_workspace_blocked_deadline.sql。请先合并或 rebase 最新 main,再做以下适配:
- 迁移编号:main 上最新的迁移已经是
0038。请把本 PR 新增的迁移顺延到合并时 main 最新编号之后,同步改测试里的文件名、测试名和升级基线,并在internal/core/migrations/README(.en).md末尾追加对应小节(两个文件现在和 main 冲突)。(本 PR 新增0038_retire_tenant_level_clones、0039_git_delivery_refs,两个都要顺延)。 - 旧文档已删除,本 PR 对它们的修改请改到新文档:
docs/runtime-control*.md→docs/runtime/runtime-control(.en).mddocs/execution-contract.md→docs/runtime/workspaces(.en).md(Workspace、clone)docs/core-contract.md→docs/core/persistence(.en).md,或对应领域的文档docs/agent-run-control-plane-review*.md→docs/agent-runs/revisions(.en).md(Revision 交付与续接)docs/development/agent/*不再保留,接口以api/openapi.json为准,数据库结构以迁移为准
- Git 交付路径:请更新
docs/repositories/git-server(.en).md(ref 查询、交付 ref)和docs/agent-runs/revisions(.en).md(Revision 改走 Git、bundle 退役)。新文档目前写的是"Cloud 不调用 ref 查询""Revision 用 bundle",需要按本 PR 的行为改写,同时说明对应 ADR 的状态。 - 冲突:根
README(.en).md已改写成入口页,本 PR 的说明请放进对应文档,不要加回 README;internal/simulator/README(.en).md新增了 Substrate 替身接口表;internal/controlpb/operations.pb.go请在合并后用task proto:generate重新生成,不要手工解冲突。 - 文档规则见
AGENTS.md的 Documentation 一节:中英两版同步修改;只写当前代码能核验的事实;接口字段以api/openapi.json为准;进度和验收记录写在 issue 里,不进仓库。
…e wire
Map the replaced Internal Control contract onto Cloud's durable shapes:
- CloneSpec is the four snapshot fields {repositoryUrl, snapshotRef,
baseCommit, workspaceRef}; the codec rejects a repository URL that is not
plain https ending in .git, a snapshot ref outside the Binding snapshot
namespace or naming another commit, and a Workspace ref outside
refs/heads/workspaces/<id>/ or naming HEAD.
- OperationSnapshot carries the clone step's clone_input; OperationProject
carries only the Project id.
- PriorRevision names the Git repository, delivery ref and base commit;
DeliverRevisionSpec carries gitRepositoryUrl, deliveryRef and
workspaceRef instead of a bundle key; RevisionDelivered has no bundle.
- AgentSessionSpec carries the Workspace directory.
- GrantRevisionDownload is gone.
Add core.GitServer (the repository base URL and ref resolver a Store uses)
and a Git Server double to the simulator: the simulated Controller forwards
the frozen clone input, the simulated Node fetches the snapshot into a
remote-less checkout on the Workspace branch, and a delivery pushes its
final commit to its delivery ref and fast-forwards the Workspace branch.
The integration fixture runs on the double. Cloud starts freezing and
checking these inputs in the following commits.
Add the git_server configuration section (Revision D2): the sandbox-facing repository_base_url written into execution inputs, and the ref query listener Cloud verifies refs through with its own pinned client certificate. Startup validates the section and loads the files without a network call; an empty repository_base_url runs Cloud without a Git Server. Every key has a CLOUD_GIT_SERVER_* override. internal/gitrefquery is the read-only client of GET /internal/v1/refs: it resolves one exact ref, treats a definitive absence as core.ErrGitRefNotFound and every other failure as unavailable, and never follows redirects. The server wires it into store.GitServer, and /healthz reports gitServer configured or unconfigured beside objectStore.
A Workspace's clone step no longer clones the Project's external repository (operation decision "clone step consumes the Binding snapshot"): - D1: the transaction that enters the clone step, and every claim of a step not yet frozen, freezes request.clone from the Binding's current snapshot: the Project's Git Server repository, the snapshot ref, its commit and refs/heads/workspaces/<id>/<branch>. The input is frozen once per operation; every execution, retries included, must carry it verbatim, and the claim snapshot hands it out as cloneInput. The Controller's Project view drops the repository and credential fields. - D2: without a snapshot the claim reads the snapshot and the Binding's latest sync in one statement: an unfinished sync parks the step as retry_wait snapshot_not_ready without spending an attempt; a sync that ended without one fails it as repository_sync_failed, recording the sync and its code, and a failed create_project leaves the Project active. A parked operation never empties a claim. Without a Git Server the step blocks as git_server_unconfigured. Run preparation shows these codes. - D3: a clone_ready result must report exactly the input's base commit, which becomes the Workspace baseline. An isolated Workspace's baseRef may only be omitted, empty, HEAD or the Binding branch (base_ref_not_synced otherwise), and a Project's default branch must be usable in a ref. - D6: delete_project is not handed out to quiesce while a sync or publish of the Project is unfinished (retry_wait repository_operation_running). - No external repository credential gates the clone any more. - The public operation view hides the frozen input and the sync's Operation ID; it keeps the sync's safe error code. git-server-preset completes the Binding's unfinished sync when it records a snapshot, so fixtures stand in for the external line's first sync.
Every clone is now the clone step of a Workspace operation (operation
decision D5, invariant 8). Remove the public /clones routes, their
OpenAPI schemas and the frontend Repositories page, the clone request
registry and its ClaimWork path, and the development store that kept the
retired fixture alive. ClaimWork returns only Agent session and Revision
delivery work, and a dispatch naming no Workspace operation is not found.
Migration 0039 deletes clone executions that belong to no Workspace and
their receipts, drops clone_executions.clone_request_id and its index,
makes clone_executions.workspace_id NOT NULL and drops clone_requests.
BREAKING CHANGE: /api/v1/tenants/{tid}/clones is gone; existing tenant
clone requests are deleted.
Implement the Git-native Revision decisions (cloud/revision 20261017 "Git-native delivery refs and resume", controller-integration 20261016 "snapshot clone input and execution ref grants" D6, D8, D9; both proposed): - A delivery work item fixes its gitRepositoryUrl, its own deliveryRef refs/ora/deliveries/<workId> and the run Workspace's workspaceRef (taken from the checkout's clone input) beside the history key; no bundle key exists any more. Delivery needs both the object store and the Git Server and is skipped with object_store_unconfigured or git_server_unconfigured otherwise. - Cloud verifies a delivered or unchanged result outside the transaction: the delivery ref, queried on the Git Server, must name the final commit, and the history object must match its declared size and digest. Then it registers the Revision with its delivery ref. An unreachable Git Server refuses the takeover as unavailable without writing anything. Upload grants sign only the history key; push_rejected and push_failed are new failure reasons and bundle_failed is refused in new results. - A follow-up run resumes the Issue's latest Revision that has a verified delivery ref and moved off its base commit, only from the repository its checkout was cloned from. Its priorRevision names the Git repository, delivery ref and base commit; a failed fetch of the delivery ref refuses the Revision for later selection unless the run was being cancelled. - Migration 0040 adds revisions.delivery_ref with a shape constraint that keeps Git and legacy bundle rows apart and a unique index per ref. - The public run projection derives `changed` from Cloud's verdict and reports a null bundleSize for Git Revisions; the Issue page no longer shows a bundle size.
Map each execution a sandbox declares to its Git Server grant (contract D5, D6); every granted execution reads the whole Project repository: - A Workspace clone reads, and writes nothing, only while it has no result, its operation is running in the clone step, the actor can still use the runtime, no force stop is pending or has terminated it, its Node is the Workspace's current Node and its input names the requested repository. Main Workspaces clone while their Project is provisioning. - Every live Agent session reads, and may create or fast-forward branches under its own Workspace's refs/heads/workspaces/<id>/ prefix; the prefix comes from the certificate, never the request. - A Revision delivery creates only the delivery ref of its input and may fast-forward the input's workspaceRef when it belongs to the certificate's Workspace. The Git Server integration harness is shared by the clone, session and delivery cases, and the delivery case now verifies the pushed ref through the real ref query before registering the Revision.
A session work item now carries the Project's Workspaces, newest first and at most 100, fixed when the item is released (contract D7): each listing names the Workspace and its kind (main, isolated or run), and a run Workspace also its Issue, title, run and run status. Run Workspaces stay listed after deletion because their branches remain on the Git Server; deleted isolated Workspaces and other Projects' Workspaces are not listed. The directory only helps `ora-git list` find branches and takes no part in authorization.
Bring the documents in line with Workspaces cloned from Binding snapshots, the retired tenant clones and Revisions delivered over Git: - docs/runtime/workspaces: the clone step consumes the Binding's frozen snapshot input, how it waits or fails without a snapshot, baseRef and requested_ref semantics, credentials no longer gating Node work, and the removed tenant clone API. - docs/repositories/git-server: clone, session and delivery grants, and Cloud verifying delivery refs through the ref query. - docs/agent-runs/revisions: delivery over Git, verification by ref query, resume from the prior's delivery ref, and the retired bundles and download grant. - docs/runtime/controller-integration, docs/core/persistence, docs/architecture, docs/operations, docs/development and the run and runtime-control documents: the snapshot clone input, the git_server settings and health report, and the simulator's Git Server double. The decisions behind this are still proposed, and the documents say so. Also bring internal/core's README up to date, list the already merged migration 0037 in the migrations catalog, and describe the new integration tests.
5769b5e to
6c32c69
Compare
Renumber this line's migrations after main's 0039-0042 workflow migrations: 0039_retire_tenant_level_clones -> 0043, 0040_git_delivery_refs -> 0044, with the upgrade test, migration READMEs and docs following. The claim keeps main's claimed_run_id projection for workflow work and drops the retired tenant clone request branch; the public request no longer carries CloneID.
Revision delivery no longer makes bundles, so REVISION_FAILURE_REASON_BUNDLE_FAILED is removed and both its value 4 and its name are reserved, matching how executions.proto retired CLONE_FAILURE_REASON_BRANCH_NOT_FOUND. A Node that still sends 4 is refused like any reason outside the closed set; an integration test pins that at the gRPC boundary.
…irectory A WorkflowRun's Agent session gets no Git Server access in the first phase and the directory has no fields for it (controller-integration D5, D7), so the directory query skips Workspaces owned by a WorkflowRun. The Git Server already denied such sessions because the grant only joins IssueRun executions; an integration test now pins that by moving a granted session to a WorkflowRun and asserting its read and push both get 403. Docs describe both.
Operation D2 now keeps no copy of the failed sync's error code on the operation: awaitSnapshot records just syncOperationId, and a run's preparation.syncErrorCode reads that sync's own error_code from repository_operations, within the Workspace's Project. Without a recorded ID it still falls back to the Binding's latest failed sync. The public operation result therefore carries neither field, so OperationResult drops syncErrorCode; OpenAPI, the generated client, tests and docs follow.
specs#111 merged, so the snapshot clone input and execution ref grants, the clone step consuming the Binding snapshot, and the Git-native delivery refs ADRs are approved (not yet implemented). Drop the proposed and under-review wording in both languages.
Keeps both Store fields (GitServer and main's ModelEgress) and lists both the gitServer readiness field and main's egress headers for Cloud's /healthz in the deployment docs.
Brings in the external Git line (repo-executor, Credential Store, repository sync and explicit publish, migration 0043_external_git_line.sql) and the shared deployment egress policy. - Renumber this branch's migrations after main's 0043: 0044_retire_tenant_level_clones.sql and 0045_git_delivery_refs.sql. - Publishing a Revision uses its verified delivery_ref, never the Node-local revision_ref, and is covered by an integration test. - Keep both git_server.* and repository.* configuration, the executor-slot route parameter and the snapshot-based clone of credentialed Projects. - Regenerate api/openapi.json and the frontend client.
…rojects The internal line's fixture settles every new Project's first sync from its source repository, so a Project is active only after its snapshot exists. Sync and publish cases that need an active Project now race for a sync a member asked for, the delete-waits publish case gives the Binding the credential a publish names, and a route test pins the executor-slot :slot parameter that the merge restored.
The publish ADR (D1) has Cloud confirm through the ref query that the source ref exists and leaves the source commit's reachability to the executor; the code checks existence only. The docs claimed Cloud confirmed the ref named the source commit.
wanglongan587
left a comment
There was a problem hiding this comment.
审查结论:Request changes
审阅 commit:72cfac1(对应 specs#111 已合并的五篇 ADR,状态均为 approved)。
Cloud 侧主体实现与 ADR 一致:clone 输入在进入步骤与领取时冻结一次、snapshot_not_ready 等待不登记/不耗次数、repository_sync_failed 只记同步 ID、领取跳过停放、delete_project 等同步与发布、按执行类型的 Git 授权、交付的 ref 查询核验与续作选取、迁移与前端删除都有对应代码和测试。以下问题需要处理后重新请审。
阻塞
-
落后 main 且有冲突。 当前
mergeable = CONFLICTING,main 已到7cf4cda(含 #92、#93、#94、#56)。- 冲突文件:
internal/api/router/router.go、integration/migration_upgrade_path_test.go、internal/core/migrations/README(.en).md。 - #94 已修复
SlotName绑定;本 PR 的1668ab5是同一修复并新增了integration/executor_slot_route_test.go。解决时保留 main 的修复,删掉重复的测试(或说明为何两边都保留)。 - #93 在
migration_upgrade_path_test.go新增了TestMigration0044ModelAttemptWorkflowRunAppliesFreshAndUpgrades,与本 PR 的 0044 测试在同一位置;合并后两个测试都要保留。 - 合并后重跑
task check、go test -race ./...、task build、task proto:check、task proto:breaking、task frontend:check,并重新跑全栈验收。
- 冲突文件:
-
迁移编号与 main 撞号。 main 已有
internal/core/migrations/0044_model_attempt_workflow_run.sql;本 PR 仍新增0044_retire_tenant_level_clones.sql和0045_git_delivery_refs.sql,不符合“合并前按 main 最新编号顺延”。- 顺延为
0045、0046(合并时再按当时 main 最新编号核对),同步:TestMigration0044…的测试名与基线、internal/core/migrations/README(.en).md、docs/runtime/workspaces(.en).md中写死的0044、PR 描述的 Migrations 段。
- 顺延为
-
落地 specs PR 的时机。 描述写的是“After this PR merges, a follow-up specs PR moves the three ADRs to implemented”。按“三个运行”,实现 PR review 通过后、产品 PR 合并前就应开出运行 3 的 specs PR(五篇 ADR 改为
implemented、同步核心用例证据),产品 PR 合并后再合并它。请在本轮 review 通过后、合并前打开并链接到本 PR 和 #183。
应修
-
internal/gitserver/README(.en).md、cmd/git-server-preset/README(.en).md仍写“proposed的后续决策…”,但该 ADR 已approved,且同 PR 的docs/repositories/git-server(.en).md标了(approved)。本 PR 已改动这些 README,请顺手把四处改成approved。 -
PR 描述与当前 head 不符:head 已是
72cfac1(只改两个 md),实际 20 个提交含 3 个 merge(1750af7、b9f569f、afd6b00);描述只列 18 项,Migrations 段仍写0043。合并 main、顺延迁移后一起重写 Commits / Migrations / 验证结论。
建议(可不动)
revision_delivery_skips只记录run_id,object_store_unconfigured/git_server_unconfigured的原因没有持久化:internal/core/execution_work.go把reason传给deliverySettled后,internal/core/agent_run_delivery.go的 skipped 分支把它丢掉了。ADR D2 写的是“原因…记为…”。如果运维需要区分两种原因,补一列或写进 run result;否则在文档里说明原因只出现在结算事件里。
审查范围基于 72cfac1;上述问题处理后会按新 head 重新审。
Keep main's executor-slot route test from ora-space#94 and drop this branch's duplicate; keep both 0044 upgrade tests.
…'s 0044 main took 0044 for model_attempt_workflow_run, so the tenant-level clone retirement becomes 0045 and the Git delivery refs become 0046.
Keep both sides of the codec helpers, the controller-integration ADR links and the migrations README; regenerate internal/controlpb.
…'s 0045 main took 0045 for agent_configuration_catalog, so the tenant-level clone retirement becomes 0046 and the Git delivery refs become 0047.
wanglongan587
left a comment
There was a problem hiding this comment.
复审结论:Approve(针对 head 6d51cad;合并前仍需机械性追平)
审阅 commit 6d51cad(base main)。本轮为只读复核:重读了上一轮四项意见对应的代码、两次 merge 的解冲突点,并抽查了 router、迁移测试、两份 migrations README、docs、OpenAPI 与 proto;没有重跑 Go 门禁和全栈验收,端到端证据来自 PR 描述与 #183 的汇报。
上一轮意见逐项核对
- 合入 main、解冲突:
4b772e6(#92–#94、#56)与61a1564(#84、#87、#61)都在。internal/api/router/router.go:PublicRequest不再有CloneID,SlotName与 main 一致,/me/executor-slot-mappings/{slot}的 PUT/DELETE 都在。integration/executor_slot_route_test.go已删除,main 的TestExecutorSlotMappingHTTPBindsSlotPath保留。integration/migration_upgrade_path_test.go同时保留了 main 的TestMigration0044ModelAttemptWorkflowRunAppliesFreshAndUpgrades和本线的TestMigration0046RetiresTenantLevelClonesKeepingWorkspaceClones。- 抽查解冲突的代码:
execution_codec.go同时保留本线的invalidInput与 main 的boundedSchemaVersion;execution_work.go保留 main 的claimed_run_id投影;operation result 的syncErrorCode已从 OpenAPI 移除,preparation.syncErrorCode保留。
- 迁移顺延:head 上是
0046_retire_tenant_level_clones.sql/0047_git_delivery_refs.sql,升级测试名与基线、internal/core/migrations/README(.en).md、docs/runtime/workspaces(.en).md、docs/agent-runs/revisions(.en).md都一致;仓库里搜不到这条线旧的 0043/0044/0045 文件名。 - ADR 状态:
internal/gitserver、cmd/git-server、cmd/git-server-preset的中英 README 都已是approved。我按 specs main3bde9f1核对,五篇内部线 ADR 仍都是approved。 - 描述:提交列表 25 项、head、Migrations 段都与实际一致;仅“Before merge”一节的迁移编号已过时(见下)。
上一轮第 6 条(revision_delivery_skips 只记 run_id、原因不落库)仍未处理。我当时标为“建议(可不动)”,本轮不阻塞;如果决定保留现状,请在落地运行的文档里写清原因只出现在结算事件里。
合并前必须满足(不改变本轮 Approve,但会让 head 变化)
- 追平 main 并按规则顺延迁移。 当前
main已到4718aba,本 PR 落后 48 个提交、CONFLICTING;main 的迁移已到0049_thread_commands_workflow_run.sql,所以不是描述里写的 0049/0050,而是 0050/0051,合并时再按当时 main 核一次。测试名/基线、两份 migrations README、docs 与描述一起改。 - 重新锁定契约并重跑验收。
6d51cad的 proto 已含 main 的agent_configuration(PluginAgentConfiguration),而 desktop#681 仍锁a51ee11(没有这个字段),所以本轮全栈验收用的是 cloud3b0a151。cloud#81 合并后 desktop 要改锁并重新生成;最终三仓 head 上重跑门禁与全栈验收,建议补plugin:acceptance与agent:session,因为插件派发正是 #84/desktop#698 改动的地方。 - 落地 specs PR:按“三个运行”,review 通过后、产品 PR 合并前开出五篇 ADR →
implemented的 specs PR(同步核心用例证据),产品 PR 合并后再合并它;owner 合并前确认它已存在。 - 追平并 push 后重新打
status:in-review(会清掉review:lgtm),我按增量复审。不要用本轮 lgtm 合并追平后的 head。
说明
- 本轮的改动(合 main、顺延编号、README 状态)没有引入我在只读复核中能发现的代码缺陷;剩余项都是合并前的机械步骤。
Resolve against main's rewritten module READMEs: take main's code maps, keep this branch's Git-delivery simulator notes and the WorkflowRun Git Server note, report gitServer in the router's health line, and drop main's NewDevelopmentStore mention, which this branch removed with the tenant-level clone path. The public request and router keep main's new fields without CloneID; main's accepted clone signal is gone with the clone route. Migrations move to 0050/0051 after main's 0049, with the upgrade test, the migrations README index and docs renumbered.
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.
Keep both sides of the WorkflowRun session paragraph in the workflow docs: main's node_unavailable and session_turn_deadline_exceeded rules, then this branch's note that the session has no Git Server access. The public request keeps main's AgentPluginID mapping without CloneID. Both upgrade tests stay in migration_upgrade_path_test.go. main took 0050 and 0051, so the tenant-level clone retirement becomes 0052 and the Git delivery refs become 0053, with the upgrade test, the migrations README index and docs renumbered.
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.
main took 0052 for the legacy workflow IssueRun settlement, so the tenant-level clone retirement becomes 0053 and the Git delivery refs become 0054. The migrations README lists main's 0052 before them; the upgrade test, its baseline and the docs are renumbered.
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 Cloud side of the internal Git line (Git Server ⇄ Node) of Ora's Git-native Project code: the clone step consumes the Binding's current snapshot, Git Server grants follow the execution kind, Revisions are delivered and resumed over Git, and tenant-level clones are retired. Bundles and the download grant are removed.
Refs ora-space/circus#183
ADR status —
approvedThis PR implements ADRs that are
approved(ora-space/specs#111 merged), not yetimplemented:decisions/cloud/operation/20261016-clone-step-consumes-binding-snapshot.mddecisions/cloud/controller-integration/20261016-snapshot-clone-input-and-execution-ref-grants.mddecisions/cloud/revision/20261017-git-native-delivery-refs-and-resume.md(supersedes the 20261012 Git Server delivery ADRs)The owner-review changes made to those ADRs before approval are implemented in commits 13–16 below. A landing run (the third of the task's three runs) opens the specs PR that moves the three ADRs to
implementedbefore this PR merges, and that specs PR merges after it; it updates the evidence of their core test cases (test-cases/cloud/controller-integration/snapshot-clone-input-and-execution-grants.md,test-cases/cloud/operation/clone-step-consumes-binding-snapshot.md,test-cases/cloud/revision/git-native-delivery-refs-and-resume.md). The documents indocs/describe the code's behavior and state that the governing ADRs areapproved.Lands together with
The desktop and cluster PRs of the same line and specs#111: the internal control contract, the Controller and the Node change in one breaking switch. Desktop pins
third_party/cloudto the contract commits below and must re-pin to the merged commit after this PR merges.cfd7966(feat(proto): clone from Git Server snapshots and deliver Revisions over Git),0b6a15d(feat(proto): expose frozen snapshot clone inputs on operations), anda51ee11(feat(proto)!: reserve the retired BUNDLE_FAILED revision failure reason), the latest contract commit desktop pins. The contract content is unchanged from before the rebase apart from merging withmain'sRecordProvisioningFactadditions tooperations.proto.proto/buf.yamlkeeps a one-timeignore_onlyexemption for the deleted v1 fields, messages, RPCs and enum values (CLONE_FAILURE_REASON_BRANCH_NOT_FOUND,REVISION_FAILURE_REASON_BUNDLE_FAILED, both nowreserved); it is removed in the next change to that file.Migrations
0053_retire_tenant_level_clones.sqland0054_git_delivery_refs.sql, after the latest migration onmainat the last merge,0052_legacy_workflow_issue_run_settlement.sql. They were added as 0039/0040 (commits 6, 7) and renumbered after each merge ofmain(commit 12: 0043/0044; commit 17: 0044/0045; commit 22: 0045/0046; commit 25: 0046/0047; commit 26: 0050/0051; commit 27: 0052/0053; commit 28: 0053/0054). The upgrade test isTestMigration0053RetiresTenantLevelClonesKeepingWorkspaceClones(baseline: everything before 0053, including main's 0043–0052);TestRevisionShapeKeepsGitAndBundleRowsApartcovers 0054's constraints. This branch's migrations touch tables no migration onmaintouches (0053:clone_requests,clone_executions,clone_event_receipts; 0054:revisions), and every upgrade test runs the later migrations on top of the earlier ones. All are listed ininternal/core/migrations/README(.en).md.Commits
feat(proto):CloneSpec{repository_url, snapshot_ref, base_commit, workspace_ref},PriorRevisionandDeliverRevisionSpecwith Git locations,AgentSessionSpec.workspace_directory,PUSH_REJECTED/PUSH_FAILED,GrantRevisionDownload/DownloadGrantdeleted.feat(proto):OperationSnapshot.clone_input;OperationProjectkeeps onlyid. (Commits 1–2 do not compile alone; the codec follows in 3.)feat(controlgrpc): wire codec for the new shapes, the simulator's Git Server double, integration fixture on the double.feat(config):git_serversettings,internal/gitrefquery, server wiring,gitServerin/healthz.feat(core): clone from the Binding's current snapshot (frozen input, park/fail without a snapshot,base_ref_not_synced,base_commit_mismatch,delete_projectwaits for repository Operations). Parking a run Workspace creation asblockedfreezes its abandonment deadline in the same transaction, like a Controller deferral (TestBlockedCloneParkFreezesDeadlineInClaimTransaction).refactor!: retire tenant-level clones (migration 0039,/tenants/{tid}/clones, OpenAPI, frontend page, clone registry).feat(core): deliver and resume Revisions over Git (migration 0040, ref-query verification, resume from the prior's delivery ref).feat(core): Git Server grants by execution kind (clone read-only during its step, sessions write their own Workspace branches, deliveries create their delivery ref and fast-forwardworkspaceRef).feat(core): Workspace directory in the session input.docs: Git-native Workspaces and Revision delivery.test(revision): keep the Git Server across simulator restarts.main: renumbers the two migrations to 0043/0044; the work claim keeps main'sclaimed_run_idprojection for workflow work and drops the retired tenant clone request branch; the public request no longer carriesCloneID. After the mergetask check(lint, format, full PostgreSQL suite), the full suite under-race,task buildandtask frontend:checkpass, with no proto, OpenAPI or frontend client drift.After ADR approval (specs#111)
a51ee11feat(proto)!:REVISION_FAILURE_REASON_BUNDLE_FAILED = 4removed and both the value and namereserved, matchingexecutions.proto'sBRANCH_NOT_FOUND;buf.yaml'sENUM_VALUE_NO_DELETEexemption addsagent_executions.proto. A Node that still sends 4 is refused asINVALID_INPUTwith nothing recorded (TestNodeMayNotReportTheReservedBundleFailure).task proto:checkandbuf breakingagainstupstream/mainpass.7c1c5abfix(core): the session'sworkspaceDirectoryleaves out WorkflowRun Workspaces (controller-integration D7).TestGitServerDeniesAWorkflowRunSessionpins at the real Git Server that a WorkflowRun'sagent_sessiongets403for reads and pushes (D5); the grant query already joined only IssueRuns.f388862fix(core): a clone step that fails on the Binding's sync records onlysyncOperationId(operation D2); a run'spreparation.syncErrorCodereads that sync's ownerror_codefromrepository_operations(falling back to the Binding's latest failed sync only when no ID was recorded).OperationResult.syncErrorCodeis dropped from OpenAPI and the generated client.fd1936bdocs: the three ADRs areapproved; the proposed / under-review wording is gone (both languages).Merge of the external Git line
b9f569fMerge ofmainwith the external Git line (cloud#76) and the shared egress policy. Both lines are kept:git_server.*(snapshot clone inputs, Revision delivery verification) andrepository.*(repo-executor, Credential Store, sync and publish) configuration coexist. Where they met: a credentialed Project's Workspace clones its snapshot with no credential (operation D1), so the external line'srequireRepositoryAccessguard, which no remaining caller used, is removed; Project creation takes the external line's HTTPS-only repository URL validation; publishing a Revision byrevisionIduses the Revision's verifieddelivery_refinstead of the Node-localrevision_ref(publish ADR, revision ADR D4), covered byTestPublishingARevisionUsesItsVerifiedDeliveryRef;git-server-presetcompletes a Project's own unfinished sync with the external line's operation shape. No proto change comes frommain; the OpenAPI document and frontend client are regenerated.afd6b00Merge ofmain(no conflicts).1668ab5test(integration): the internal line's fixture settles each new Project's first sync from its source repository, so a Project is active only once its snapshot exists. The external line's sync and publish tests that need an active Project now race for a sync a member asked for; the delete-waits publish case gives the Binding the credential a publish names.72cfac1docs(repository): publish only confirms that the source ref exists.Second review round
4b772e6Merge ofmainat7cf4cda(feat(core): evaluate conditions with desktop's semantics #92–fix(api): 补回执行器槽位路径参数绑定 #94, fix: 提前校验开发登录并验证 Gateway 认证授权边界 #56).router.gokeeps this branch's public request withoutCloneID, withSlotNameas onmain. fix(api): 补回执行器槽位路径参数绑定 #94 fixed the same dropped:slotbinding this branch had restored, so this branch's duplicateintegration/executor_slot_route_test.gois deleted andmain'sTestExecutorSlotMappingHTTPBindsSlotPathis kept. Both 0044 upgrade tests are kept inintegration/migration_upgrade_path_test.go, and the migrations README keeps main's 0044 section before this branch's.e721cc0fix(migrations): renumber this branch's migrations to 0045/0046 after main's 0044 (file names, upgrade test name and baseline,internal/core/migrations/README(.en).md,docs/runtime/workspaces(.en).md,docs/agent-runs/revisions(.en).md).3b0a151docs:internal/gitserver,cmd/git-serverandcmd/git-server-presetREADMEs (both languages) call the Git Server code-hub decisionsapproved, matching specs anddocs/repositories/git-server.61a1564Merge ofmainat0f4e60b(feat(pluginmarket): agent configuration catalog snapshot and frozen install associations (P2, preflight) #84, feat(protocol): 声明可选 Thread 正文投影与实时预览契约 #87, fix: 阻止收尾后的 Run 工作继续领取和新登记 #61). The codec keeps this branch'sinvalidInputnext to main'sboundedSchemaVersion;docs/runtime/controller-integration(.en).mdlists both ADRs; the migrations README keeps main's 0045 section before this branch's;internal/controlpbis regenerated (task proto:checkclean).6d51cadfix(migrations): renumber to 0046/0047 after main's 0045.Final catch-up with
main6468f01Merge ofmainat4718aba(feat: 任务持续对话、串行交接与可选实时预览 #86, feat(core): persist the run kickoff in the Start variable pool #95–fix: pass the desktop default agent config through the publish gate #99). Takes main's rewritten module READMEs and code maps, keeps this branch's Git-delivery simulator notes and the WorkflowRun Git Server note, reportsgitServerin the router's health line, and drops main'sNewDevelopmentStoremention, which this branch removed with the tenant-level clone path. The public request keeps main's new fields withoutCloneID. Migrations move to 0050/0051 after main's 0049.4e5e00fMerge ofmainatb7e1801(feat(workflows): start a run from the selected version's own form #70, feat(workflows): 让运行详情与历史随运行状态更新(有界轮询 + 单调合并) #82, test: cover workflow asset import fan-out, user edits and fetch bounds #83, feat(core): settle an in-flight workflow session whose Node is gone #91, feat(core): record agent run cancellation requests #100–feat(model-gateway): support pinned Claude Messages requests #102, feat(core): declare and resolve workflow globals and sys.* variables #104, fix(core): keep unset workflow run timestamps null #105, fix(core): omit the agent declaration association for undeclared plugins #107–fix: 发布期把 file/array[file] global 的遗留路径字符串规范化为 workspace_file 引用 #110).docs/workflows/workflows(.en).mdkeeps main'snode_unavailableandsession_turn_deadline_exceededrules for a WorkflowRun session, followed by this branch's note that the session has no Git Server access. The public request keeps main'sAgentPluginIDmapping withoutCloneID. Both upgrade tests stay inintegration/migration_upgrade_path_test.go.maintook 0050 and 0051, so the two migrations become 0052/0053, with the upgrade test, the migrations README index and the docs renumbered. No proto change since6468f01; the OpenAPI document and frontend client regenerate with no drift.7a1a2afMerge ofmainat9814cac(feat(core): settle legacy workflow IssueRuns and prove scheduler crash recovery #113).maintook 0052 for the legacy workflow IssueRun settlement, so the two migrations become 0053/0054; the migrations README lists main's 0052 before them, and the upgrade test, its baseline and the docs are renumbered. No proto change.Verification
7a1a2af(current head):go build ./...,go vetonintegrationandinternal/core,task format:check, theintegrationmigration and upgrade tests (now including main'sTestMigration0052LegacyWorkflowIssueRunSettlementAppliesFreshAndUpgradesandTestMigration0053RetiresTenantLevelClonesKeepingWorkspaceClones) and main's newinternal/corerecovery tests pass on real PostgreSQL. The merge only adds main's feat(core): settle legacy workflow IssueRuns and prove scheduler crash recovery #113 (one migration and its tests) and renumbers, so the remaining gates below were not rerun locally; CI covers the full suite.4e5e00f(unit-level only):task format:check,task lint(0 issues),task proto:lint,buf generatewith nointernal/controlpbdrift,buf breakingagainstupstream/main,go run ./cmd/openapiandnpm run api:generatewith no drift,go build ./...andgo vet ./...,go test ./internal/... ./cmd/...on real PostgreSQL (REQUIRE_POSTGRES=1, 33 packages), theintegrationpackage's migration and upgrade tests (-run 'TestMigration|TestRevisionShapeKeepsGitAndBundleRowsApart|TestRevisionUpgrade|PersonalAgentConfigurationsUpgrade', 25 tests, includingTestMigration0052RetiresTenantLevelClonesKeepingWorkspaceClones), and the frontend'sformat:check,lint,typecheck, unit tests with coverage (140 files, 1180 tests),check:modulesagainstupstream/main,check:docs,check:dead,check:dupandbuildpass. The rest of theintegrationpackage and the-racesuite are left to CI on this head; the full-stack acceptance has not been rerun on it yet (see "Before merge").6d51cad:task format:check,task lint,task proto:lint,task proto:check,task build,task proto:breakingagainstupstream/main,task frontend:check, the full suite on real PostgreSQL (go test ./..., 1027 s) and the full suite under-race(1200 s) pass.3b0a151: the same gates pass (integration package 744 s;-racefull suite, no data race).--internalsandbox networks), built from feat: clone Workspaces from Git Server snapshots and deliver Revisions over Git (internal Git line) #81 at3b0a151, feat(node): clone from Git Server snapshots, collaborate through ora-git and deliver Revisions over Git desktop#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 #84 frommain. #84 freezesagentConfigurationinto plugin install inputs, and a Controller built against an older contract drops it, so Cloud refuses the plugin dispatch (dispatch ownership conflict). ora-space/desktop#698 fixed this on desktopmain, and desktop#681 now carries it.Before merge
The three PRs have caught up with
maintogether: #81 at7a1a2af, ora-space/desktop#681 atc08770ed(pinsthird_party/cloudto7a1a2af) and 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.maintakes another migration number before this merges, the two migrations move after it again.Then cloud#81, desktop#681 (re-pinned to the merged cloud commit) and cluster#29 merge in that order.
Documentation
Written into the current docs (both languages):
docs/runtime/workspaces,docs/repositories/git-server,docs/agent-runs/revisions,docs/runtime/controller-integration,docs/core/persistence,docs/architecture,docs/operations/configuration,docs/operations/deployment,docs/development/local-development,docs/agent-runs/issue-runs,docs/runtime/runtime-control. The root README is unchanged.Breaking switch
No feature flag and no migration of business state: Workspaces only clone from snapshots after this lands. Snapshots come from the external line's syncs (
repository.enabled) or, in development and acceptance, fromgit-server-preset. Development data is rebuilt.Not in this PR
main(cloud#76) and merged here (commit 17).