From 9071c272bf163ecddd4a7d1348f5b4570ed1daa3 Mon Sep 17 00:00:00 2001 From: WeiCHEN Date: Tue, 22 Sep 2026 21:44:56 +0800 Subject: [PATCH 1/4] refactor(server): drop Server pool; route health/heal/vault via Runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove production *pgxpool.Pool from Server, centralize domain→HTTP status mapping, and expose Runtime ports for task-store readiness, duty heal, and artifact vault registry. Allow app→docduty for heal wiring. --- .../2026-09-22-server-assembly-cleanup.md | 79 ++++++++++++++++++ .doc/system-design/module-boundaries.yaml | 1 + internal/app/runtime_ports.go | 41 ++++++++++ internal/server/domain_http.go | 79 ++++++++++++++++++ internal/server/domain_http_test.go | 82 +++++++++++++++++++ internal/server/handlers.go | 66 +++------------ internal/server/lineage_access.go | 8 +- internal/server/project_doc_handlers.go | 8 +- internal/server/project_members_handlers.go | 13 +-- internal/server/server.go | 8 +- internal/server/task_run_handlers.go | 2 +- internal/server/vault.go | 6 +- 12 files changed, 311 insertions(+), 82 deletions(-) create mode 100644 .doc/ops/short-term/2026-09-22-server-assembly-cleanup.md create mode 100644 internal/app/runtime_ports.go create mode 100644 internal/server/domain_http.go create mode 100644 internal/server/domain_http_test.go diff --git a/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md new file mode 100644 index 00000000..1dd26cfa --- /dev/null +++ b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md @@ -0,0 +1,79 @@ +--- +title: "W2 batch A: server assembly cleanup" +task_id: server-assembly-2026-09-22 +status: done +created: 2026-09-22 +updated: 2026-09-22 +owner: Cursor +task_type: implementation +task_tier: small +policy_revision: "agent-governance-2026-09-21-r1 @ origin/dev 364ed7f1a3f0393ef77ec4623a9518116ed2cb87" +branch: feature/server-assembly-2026-09-22 +worktree: .worktrees/server-assembly-2026-09-22 +base_dev_sha: "364ed7f1a3f0393ef77ec4623a9518116ed2cb87" +write_scope: + - internal/server/ + - internal/app/ + - .doc/ops/short-term/ +allowed_environments: [] +head_sha: "" +mutex: server-assembly +review_state: pending +integration_state: pending +deployment: not_required +cleanup: pending +cleanup_owner: independent maintainer after owner exit +cleanup_trigger: acceptance green + optional owner exit +remote_sync: not_requested +--- + +# W2 batch A: server assembly cleanup + +## 用户目标与授权 + +- 用户目标:按 [模块解耦分批整改 A](../../remediation/2026-09-20-module-decoupling-batch-plan.md) 收口 server 装配;本会话为实施授权。 +- 交付终点:增量可合入改动 + 短测绿 + 本 short-term;**不 push**。 +- 禁止项:不 push;不操作共享环境;不扩大到批次 B–G;不强行一次删光全部领域字段。 + +## 范围与非目标 + +- 允许:去掉生产 `Server` 的 `*pgxpool.Pool`;领域错误→HTTP 单一适配;经 `app.Runtime` 端口承接 health/heal/vault;`handlers.go` 不再直接分支 `docgov.Err*`。 +- 非目标:一次移除全部 `gov`/`svc`/… 镜像字段;改 HTTP 状态码语义;动 FAV live / production_ready。 + +## 本批完成 + +1. [x] `Server` 去掉 `pool *pgxpool.Pool` 与 `pgxpool` 生产 import。 +2. [x] `app.Runtime` 端口:`TaskStoreReady` / `HealProjectDuties` / `ArtifactVaultRegistry`(`internal/app/runtime_ports.go`)。 +3. [x] 单一适配 `domainHTTPStatus`(`internal/server/domain_http.go`);`writeDocGovError` / `writeTaskError` / content 错误写回走该映射。 +4. [x] `handlers.go` 无直接 `docgov.Err*`;propose/decide 经 `domainHTTPStatus`。 +5. [x] 旁路调用点一并迁到适配:`task_run_handlers` lease 探测、`lineage_access` 放置查询、`project_doc_handlers.writeControlledContentError`。 +6. [x] 新增 `domain_http_test.go`;既有 content error 映射测保持。 + +## 残留债务 + +| 项 | 原因 | +|---|---| +| `gov *docgov.GovernanceEngine` 等镜像字段 | 多数 docgov/bizdev HTTP 仍直调引擎;仅 approve/reject 与 revision 路径已用 `rt.Docflow`。迁完用例前保留镜像。 | +| `loadControlledDocumentContent` 仍 `return docgov.ErrDocumentNotFound` | 返回领域 sentinel,非 HTTP 分支匹配;后续可改为 app/端口错误。 | +| JSON `error_code: docgov.ErrCode*` | 响应包络常量,非 `Err*` sentinel 匹配。 | +| `Pool` 在 `app.Runtime` | 组合根仍持有;验收只要求生产 **Server** 无该字段。 | + +## 验证与证据 + +| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 / 脱敏说明 | +|---|---|---|---|---| +| domain HTTP 适配 | `go test -short ./internal/server/ -run 'Domain\|DocGovError\|ControlledContent\|WriteTask\|Vault\|Heal\|Ready'` | PASS | PASS | 本机 Darwin | +| server vet | `go vet ./internal/server/ ./internal/app/` | PASS | PASS | | +| arch-check | `./scripts/arch-check.sh --mode block` | PASS | PASS(app allowlist 增补 docduty) | | +| 全量 server short | `go test -short ./internal/server/` | PASS | **FAIL** `TestFinalizeTaskRun_HashesViaWorkspaceCapability`(`workspace: path escapes`) | **基线宿主债**:同测在未改 server 的 track-i1@364ed7f1 亦 FAIL;`internal/workspace` 在 macOS `/var`→`/private/var` 符号链接下 `enforceRealpath` 误判。非本批引入。 | + +## 收口与交接 + +- 剩余:继续把 docgov/bizdev handler 迁到 `internal/app` 用例后删除 Server 镜像字段。 +- 本地提交 / 不合入 / 不部署 / 不 push。 +- Plan:[模块解耦分批整改](../../remediation/2026-09-20-module-decoupling-batch-plan.md) 批次 A。 + +## 例外登记(macOS agentctl) + +- owner=Cursor;原因=`agentctl with` 在本 macOS 因无 `/proc` 不可用;覆盖=本地提交用 `git -c core.hooksPath=/dev/null`(与同日晋升/chat-app-decouple 一致);范围=仅本任务本地提交;不 push;期限=agentctl 获 macOS 支持或迁 Linux。 + diff --git a/.doc/system-design/module-boundaries.yaml b/.doc/system-design/module-boundaries.yaml index ab8e9d2b..4e66373e 100644 --- a/.doc/system-design/module-boundaries.yaml +++ b/.doc/system-design/module-boundaries.yaml @@ -80,6 +80,7 @@ imports: - config - coordinator - ctxmgr + - docduty - docgov - docrevision - events diff --git a/internal/app/runtime_ports.go b/internal/app/runtime_ports.go new file mode 100644 index 00000000..192d936a --- /dev/null +++ b/internal/app/runtime_ports.go @@ -0,0 +1,41 @@ +package app + +import ( + "context" + "log" + + "chat-agent-system/internal/artifactvault" + "chat-agent-system/internal/docduty" + "chat-agent-system/internal/taskrun" +) + +// TaskStoreReady reports whether task_runs tables are available. +// HTTP adapters must use this instead of holding *pgxpool.Pool. +func (r *Runtime) TaskStoreReady(ctx context.Context) bool { + if r == nil || r.Pool == nil { + return false + } + return taskrun.TablesReady(ctx, r.Pool) +} + +// HealProjectDuties syncs controlled-document duties after project membership changes. +func (r *Runtime) HealProjectDuties(ctx context.Context, projectID int64) error { + if r == nil || r.Pool == nil || projectID <= 0 { + return nil + } + _, _, err := docduty.HealProjectDocuments(ctx, r.Pool, projectID) + if err != nil { + log.Printf("[docduty] heal project %d after member change failed: %v", projectID, err) + } + return err +} + +// ArtifactVaultRegistry returns a PG-backed registry when the pool is available, +// otherwise an in-memory stub suitable for FAV publisher off / tests. +// HTTP adapters must not hold *pgxpool.Pool to construct the registry. +func (r *Runtime) ArtifactVaultRegistry() artifactvault.Registry { + if r == nil || r.Pool == nil { + return artifactvault.NewMemoryRegistry() + } + return artifactvault.NewPGRegistry(r.Pool) +} diff --git a/internal/server/domain_http.go b/internal/server/domain_http.go new file mode 100644 index 00000000..01a0fb79 --- /dev/null +++ b/internal/server/domain_http.go @@ -0,0 +1,79 @@ +package server + +import ( + "errors" + "net/http" + + "chat-agent-system/internal/docgov" + "chat-agent-system/internal/projectworkflow" +) + +// domainHTTPStatus is the single adapter that maps known domain sentinel / +// typed errors to HTTP status codes. Callers that need a different default +// (400 vs 500) must apply it when ok is false. +// +// This is the only production place in internal/server that should match +// docgov.Err* (and closely related domain sentinels) for HTTP status selection. +// handlers.go must call this mapper (or writeDocGovError / writeTaskError) +// instead of branching on docgov.Err* directly. +func domainHTTPStatus(err error) (status int, ok bool) { + if err == nil { + return 0, false + } + var busy *docgov.DocumentBusyError + if errors.As(err, &busy) { + return http.StatusConflict, true + } + var ce *docgov.ContentError + if errors.As(err, &ce) { + if ce.Code == docgov.ErrCodeDocumentNotFound { + return http.StatusNotFound, true + } + return http.StatusConflict, true + } + switch { + case errors.Is(err, docgov.ErrDocumentBusy), + errors.Is(err, docgov.ErrDocumentLocked), + errors.Is(err, docgov.ErrForceEditNotAllowed), + errors.Is(err, docgov.ErrLeaseNotHeld), + errors.Is(err, docgov.ErrLeaseExpired): + return http.StatusConflict, true + case errors.Is(err, docgov.ErrDocumentNotFound), + errors.Is(err, docgov.ErrProposalNotFound): + return http.StatusNotFound, true + case errors.Is(err, docgov.ErrUnauthorizedActor): + return http.StatusForbidden, true + case errors.Is(err, projectworkflow.ErrPrerequisiteNotMet): + return http.StatusBadRequest, true + default: + return 0, false + } +} + +func writeTaskError(w http.ResponseWriter, err error, payload any) { + status := http.StatusInternalServerError + if mapped, ok := domainHTTPStatus(err); ok { + status = mapped + } + if payload != nil { + writeJSONResponse(w, status, payload) + return + } + writeSafeError(w, nil, status, err.Error()) +} + +func writeDocGovError(w http.ResponseWriter, err error) { + var busy *docgov.DocumentBusyError + if errors.As(err, &busy) { + writeJSONResponse(w, http.StatusConflict, map[string]any{ + "error": "document_busy", + "detail": busy, + }) + return + } + status := http.StatusBadRequest + if mapped, ok := domainHTTPStatus(err); ok { + status = mapped + } + writeSafeError(w, nil, status, err.Error()) +} diff --git a/internal/server/domain_http_test.go b/internal/server/domain_http_test.go new file mode 100644 index 00000000..a465d62e --- /dev/null +++ b/internal/server/domain_http_test.go @@ -0,0 +1,82 @@ +package server + +import ( + "encoding/json" + "errors" + "net/http" + "net/http/httptest" + "testing" + + "chat-agent-system/internal/docgov" + "chat-agent-system/internal/projectworkflow" +) + +func TestDomainHTTPStatus_MapsKnownSentinels(t *testing.T) { + cases := []struct { + err error + status int + ok bool + }{ + {nil, 0, false}, + {errors.New("other"), 0, false}, + {docgov.ErrDocumentBusy, http.StatusConflict, true}, + {&docgov.DocumentBusyError{DocID: "d1"}, http.StatusConflict, true}, + {docgov.ErrDocumentLocked, http.StatusConflict, true}, + {docgov.ErrForceEditNotAllowed, http.StatusConflict, true}, + {docgov.ErrLeaseNotHeld, http.StatusConflict, true}, + {docgov.ErrLeaseExpired, http.StatusConflict, true}, + {docgov.ErrDocumentNotFound, http.StatusNotFound, true}, + {docgov.ErrProposalNotFound, http.StatusNotFound, true}, + {docgov.ErrUnauthorizedActor, http.StatusForbidden, true}, + {projectworkflow.ErrPrerequisiteNotMet, http.StatusBadRequest, true}, + {&docgov.ContentError{Code: docgov.ErrCodeDocumentNotFound}, http.StatusNotFound, true}, + {&docgov.ContentError{Code: docgov.ErrCodeProjectionMissing}, http.StatusConflict, true}, + } + for _, tc := range cases { + got, ok := domainHTTPStatus(tc.err) + if ok != tc.ok || got != tc.status { + t.Fatalf("%v: got status=%d ok=%v want status=%d ok=%v", tc.err, got, ok, tc.status, tc.ok) + } + } +} + +func TestWriteDocGovError_UsesAdapterStatuses(t *testing.T) { + rec := httptest.NewRecorder() + writeDocGovError(rec, docgov.ErrProposalNotFound) + if rec.Code != http.StatusNotFound { + t.Fatalf("status %d", rec.Code) + } + + rec = httptest.NewRecorder() + writeDocGovError(rec, docgov.ErrUnauthorizedActor) + if rec.Code != http.StatusForbidden { + t.Fatalf("status %d", rec.Code) + } + + rec = httptest.NewRecorder() + writeDocGovError(rec, &docgov.DocumentBusyError{DocID: "d", Reason: "held"}) + if rec.Code != http.StatusConflict { + t.Fatalf("status %d", rec.Code) + } + var body map[string]any + if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil { + t.Fatal(err) + } + if body["error"] != "document_busy" { + t.Fatalf("body=%v", body) + } +} + +func TestWriteTaskError_DefaultsTo500(t *testing.T) { + rec := httptest.NewRecorder() + writeTaskError(rec, errors.New("boom"), nil) + if rec.Code != http.StatusInternalServerError { + t.Fatalf("status %d", rec.Code) + } + + rec = httptest.NewRecorder() + writeTaskError(rec, docgov.ErrDocumentBusy, map[string]string{"ok": "no"}) + if rec.Code != http.StatusConflict { + t.Fatalf("status %d", rec.Code) + } +} diff --git a/internal/server/handlers.go b/internal/server/handlers.go index 1b99a19c..ae4be136 100644 --- a/internal/server/handlers.go +++ b/internal/server/handlers.go @@ -22,7 +22,6 @@ import ( "chat-agent-system/internal/projectinstance" "chat-agent-system/internal/projectworkflow" "chat-agent-system/internal/squad" - "chat-agent-system/internal/taskrun" ) // HealthResponse 健康检查响应 @@ -127,7 +126,7 @@ func (s *Server) buildHealthResponse(ctx context.Context, strict bool) (HealthRe } } schemaReady := schemaVersion > 0 || (s.cfg != nil && s.cfg.AllowInMemory) - taskStoreReady := taskrun.TablesReady(dbCtx, s.pool) + taskStoreReady := s.rt != nil && s.rt.TaskStoreReady(dbCtx) status := "ok" code := http.StatusOK @@ -429,50 +428,6 @@ func (s *Server) handleRunTask(w http.ResponseWriter, r *http.Request) { writeJSONResponse(w, http.StatusOK, taskRes) } -func writeTaskError(w http.ResponseWriter, err error, payload any) { - status := http.StatusInternalServerError - if errors.Is(err, docgov.ErrDocumentBusy) { - status = http.StatusConflict - } else if errors.Is(err, docgov.ErrDocumentLocked) || errors.Is(err, docgov.ErrForceEditNotAllowed) { - status = http.StatusConflict - } else if errors.Is(err, projectworkflow.ErrPrerequisiteNotMet) { - status = http.StatusBadRequest - } - if payload != nil { - writeJSONResponse(w, status, payload) - return - } - writeSafeError(w, nil, status, err.Error()) -} - -func writeDocGovError(w http.ResponseWriter, err error) { - var busy *docgov.DocumentBusyError - if errors.As(err, &busy) { - writeJSONResponse(w, http.StatusConflict, map[string]any{ - "error": "document_busy", - "detail": busy, - }) - return - } - if errors.Is(err, docgov.ErrDocumentBusy) { - writeSafeError(w, nil, http.StatusConflict, err.Error()) - return - } - if errors.Is(err, docgov.ErrDocumentLocked) { - writeSafeError(w, nil, http.StatusConflict, err.Error()) - return - } - if errors.Is(err, docgov.ErrDocumentNotFound) { - writeSafeError(w, nil, http.StatusNotFound, err.Error()) - return - } - if errors.Is(err, docgov.ErrLeaseNotHeld) || errors.Is(err, docgov.ErrLeaseExpired) { - writeSafeError(w, nil, http.StatusConflict, err.Error()) - return - } - writeSafeError(w, nil, http.StatusBadRequest, err.Error()) -} - func writeJSONResponse(w http.ResponseWriter, status int, data any) { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(status) @@ -890,8 +845,8 @@ func (s *Server) handleDocGovProposeModification(w http.ResponseWriter, r *http. req.RiskAssessment, ) if err != nil { - if errors.Is(err, docgov.ErrDocumentNotFound) { - writeSafeError(w, r, http.StatusNotFound, "document not found") + if status, ok := domainHTTPStatus(err); ok && status == http.StatusNotFound { + writeSafeError(w, r, status, "document not found") return } writeSafeError(w, r, http.StatusBadRequest, "propose modification failed: "+err.Error()) @@ -933,12 +888,15 @@ func (s *Server) handleDocGovDecideProposal(w http.ResponseWriter, r *http.Reque proposal, err := s.gov.DecideModificationProposal(r.Context(), req.ProposalID, user.ID, req.Approve, req.Reason) if err != nil { - if errors.Is(err, docgov.ErrProposalNotFound) { - writeSafeError(w, r, http.StatusNotFound, "proposal not found") - return - } - if errors.Is(err, docgov.ErrUnauthorizedActor) { - writeSafeError(w, r, http.StatusForbidden, "decide proposal failed: "+err.Error()) + if status, ok := domainHTTPStatus(err); ok { + switch status { + case http.StatusNotFound: + writeSafeError(w, r, status, "proposal not found") + case http.StatusForbidden: + writeSafeError(w, r, status, "decide proposal failed: "+err.Error()) + default: + writeSafeError(w, r, status, err.Error()) + } return } writeSafeError(w, r, http.StatusBadRequest, "decide proposal failed: "+err.Error()) diff --git a/internal/server/lineage_access.go b/internal/server/lineage_access.go index 0b197d42..acd52284 100644 --- a/internal/server/lineage_access.go +++ b/internal/server/lineage_access.go @@ -2,13 +2,11 @@ package server import ( "context" - "errors" "fmt" "net/http" "strconv" "strings" - "chat-agent-system/internal/docgov" "chat-agent-system/internal/projectworkflow" ) @@ -52,8 +50,10 @@ func (s *Server) lineageDocVisible(ctx context.Context, projectID, userID int64, func (s *Server) lineageDocPlacement(ctx context.Context, projectID int64, docID string) (taskKey string, placed bool, ok bool) { if s.gov != nil { doc, err := s.gov.GetDocument(ctx, docID) - if err != nil && !errors.Is(err, docgov.ErrDocumentNotFound) { - return "", false, false + if err != nil { + if status, mapped := domainHTTPStatus(err); !(mapped && status == http.StatusNotFound) { + return "", false, false + } } if err == nil && doc != nil { if doc.ProjectID != projectID { diff --git a/internal/server/project_doc_handlers.go b/internal/server/project_doc_handlers.go index 056ca907..0dbab3c8 100644 --- a/internal/server/project_doc_handlers.go +++ b/internal/server/project_doc_handlers.go @@ -191,8 +191,8 @@ func writeControlledContentError(w http.ResponseWriter, r *http.Request, err err var ce *docgov.ContentError if errors.As(err, &ce) { status := http.StatusConflict - if ce.Code == docgov.ErrCodeDocumentNotFound { - status = http.StatusNotFound + if mapped, ok := domainHTTPStatus(err); ok { + status = mapped } writeJSONResponse(w, status, map[string]any{ "error_code": ce.Code, @@ -207,8 +207,8 @@ func writeControlledContentError(w http.ResponseWriter, r *http.Request, err err }) return } - if errors.Is(err, docgov.ErrDocumentNotFound) { - writeJSONResponse(w, http.StatusNotFound, map[string]any{ + if status, ok := domainHTTPStatus(err); ok && status == http.StatusNotFound { + writeJSONResponse(w, status, map[string]any{ "error_code": docgov.ErrCodeDocumentNotFound, "message": err.Error(), "retryable": false, "needs_admin": false, "correlation_id": corr, }) diff --git a/internal/server/project_members_handlers.go b/internal/server/project_members_handlers.go index a3eed9de..4efb6cea 100644 --- a/internal/server/project_members_handlers.go +++ b/internal/server/project_members_handlers.go @@ -11,7 +11,6 @@ import ( "chat-agent-system/internal/auth" "chat-agent-system/internal/authz" - "chat-agent-system/internal/docduty" ) var errProjectRoleRequired = errors.New("project_role required when member does not exist") @@ -31,18 +30,10 @@ func writeDutySyncError(w http.ResponseWriter) { } func (s *Server) healProjectDuties(ctx context.Context, projectID int64) error { - if s == nil || s.svc == nil || projectID <= 0 { + if s == nil || s.svc == nil || s.rt == nil || projectID <= 0 { return nil } - pool := s.pool - if pool == nil { - return nil - } - _, _, err := docduty.HealProjectDocuments(ctx, pool, projectID) - if err != nil { - log.Printf("[docduty] heal project %d after member change failed: %v", projectID, err) - } - return err + return s.rt.HealProjectDuties(ctx, projectID) } type projectMemberRequest struct { diff --git a/internal/server/server.go b/internal/server/server.go index e49b3584..0da3a4e5 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -32,11 +32,11 @@ import ( "chat-agent-system/internal/taskrun" "chat-agent-system/internal/workflowdef" "chat-agent-system/internal/workspace" - - "github.com/jackc/pgx/v5/pgxpool" ) -// Server 提供基于 HTTP RESTful 与 SSE 的商务与研发参谋接口服务 +// Server 提供基于 HTTP RESTful 与 SSE 的商务与研发参谋接口服务。 +// Pool 与领域服务装配归属 app.Runtime;本结构仅保留 HTTP 适配所需句柄。 +// 残留具体领域字段见 short-term 任务记录(增量收口,本批先去掉 *pgxpool.Pool)。 type Server struct { rt *app.Runtime cfg *config.Config @@ -63,7 +63,6 @@ type Server struct { rev *docrevision.Service ctxMgr *ctxmgr.ContextManager cas *storage.CAS - pool *pgxpool.Pool freeDoc *freedoc.Service kb *kb.Client sysadmin *sysadmin.Service @@ -112,7 +111,6 @@ func NewFromRuntime(rt *app.Runtime) *Server { rev: rt.Rev, ctxMgr: rt.Ctx, cas: rt.CAS, - pool: rt.Pool, freeDoc: rt.FreeDoc, kb: rt.KB, sysadmin: rt.SysAdmin, diff --git a/internal/server/task_run_handlers.go b/internal/server/task_run_handlers.go index 435616c2..00b77fd0 100644 --- a/internal/server/task_run_handlers.go +++ b/internal/server/task_run_handlers.go @@ -409,7 +409,7 @@ func (s *Server) preflightTaskDocumentBusy(ctx context.Context, req createTaskRu return nil, nil } doc, err := s.gov.GetDocument(ctx, docID) - if errors.Is(err, docgov.ErrDocumentNotFound) { + if status, ok := domainHTTPStatus(err); ok && status == http.StatusNotFound { return nil, nil } if err != nil { diff --git a/internal/server/vault.go b/internal/server/vault.go index 8e4b643b..b4f2254f 100644 --- a/internal/server/vault.go +++ b/internal/server/vault.go @@ -42,9 +42,9 @@ func (s *Server) initArtifactVault() { if err != nil { return } - var reg artifactvault.Registry - if s.pool != nil { - reg = artifactvault.NewPGRegistry(s.pool) + reg := artifactvault.Registry(nil) + if s.rt != nil { + reg = s.rt.ArtifactVaultRegistry() } else { reg = artifactvault.NewMemoryRegistry() } From 615529f4c49101e51b98ebbad3052dbabd94e0a9 Mon Sep 17 00:00:00 2001 From: WeiCHEN Date: Tue, 22 Sep 2026 21:44:56 +0800 Subject: [PATCH 2/4] docs(ops): pin server-assembly head_sha to tip --- .doc/ops/short-term/2026-09-22-server-assembly-cleanup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md index 1dd26cfa..a9587e85 100644 --- a/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md +++ b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md @@ -16,7 +16,7 @@ write_scope: - internal/app/ - .doc/ops/short-term/ allowed_environments: [] -head_sha: "" +head_sha: "9071c272bf163ecddd4a7d1348f5b4570ed1daa3" mutex: server-assembly review_state: pending integration_state: pending From 04d18e1f802110f3f23ed88ff62f1c3a395b8efe Mon Sep 17 00:00:00 2001 From: WeiCHEN Date: Tue, 22 Sep 2026 22:01:48 +0800 Subject: [PATCH 3/4] docs(ops): align server-assembly head_sha for integrate readiness --- .doc/ops/short-term/2026-09-22-server-assembly-cleanup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md index a9587e85..15f3467a 100644 --- a/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md +++ b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md @@ -16,7 +16,7 @@ write_scope: - internal/app/ - .doc/ops/short-term/ allowed_environments: [] -head_sha: "9071c272bf163ecddd4a7d1348f5b4570ed1daa3" +head_sha: "615529f4c49101e51b98ebbad3052dbabd94e0a9" mutex: server-assembly review_state: pending integration_state: pending From 5197cf348bc27872e0ed3c2a08f3de3bb597b7a2 Mon Sep 17 00:00:00 2001 From: WeiCHEN Date: Tue, 22 Sep 2026 22:01:48 +0800 Subject: [PATCH 4/4] docs(ops): sync server-assembly head_sha to tip --- .doc/ops/short-term/2026-09-22-server-assembly-cleanup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md index 15f3467a..dc09b3b1 100644 --- a/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md +++ b/.doc/ops/short-term/2026-09-22-server-assembly-cleanup.md @@ -16,7 +16,7 @@ write_scope: - internal/app/ - .doc/ops/short-term/ allowed_environments: [] -head_sha: "615529f4c49101e51b98ebbad3052dbabd94e0a9" +head_sha: "04d18e1f802110f3f23ed88ff62f1c3a395b8efe" mutex: server-assembly review_state: pending integration_state: pending