refactor(bizdev): delete eight locator getters

Composition roots already hold Snapshot ports; the interface and archtest now forbid putting Pool/DocGov/DocRevision/ContextManager/CAS/ProjectWorkflow/FreeformDoc/KB back on Service.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
weichen
2026-09-15 13:08:25 +00:00
co-authored by Cursor
parent 3f42149457
commit 2a75abb39e
7 changed files with 62 additions and 62 deletions
+58
View File
@@ -1,7 +1,12 @@
package archtest
import (
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
@@ -48,3 +53,56 @@ func TestArchitectureBoundaries(t *testing.T) {
}
}
}
var forbiddenBizdevLocators = []string{
"Pool", "DocGov", "DocRevision", "ContextManager", "CAS", "ProjectWorkflow", "FreeformDoc", "KB",
}
func TestBizdevNoLocatorGetters(t *testing.T) {
root, err := ModuleRoot()
if err != nil {
t.Fatal(err)
}
dir := filepath.Join(root, "internal", "bizdev")
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, dir, func(info os.FileInfo) bool {
name := info.Name()
return strings.HasSuffix(name, ".go") && !strings.HasSuffix(name, "_test.go")
}, parser.SkipObjectResolution)
if err != nil {
t.Fatal(err)
}
forbidden := make(map[string]struct{}, len(forbiddenBizdevLocators))
for _, name := range forbiddenBizdevLocators {
forbidden[name] = struct{}{}
}
for _, pkg := range pkgs {
for path, file := range pkg.Files {
for _, decl := range file.Decls {
fn, ok := decl.(*ast.FuncDecl)
if !ok || fn.Recv == nil || fn.Name == nil {
continue
}
if _, hit := forbidden[fn.Name.Name]; !hit {
continue
}
if !recvIsBizdevService(fn.Recv) {
continue
}
t.Errorf("locator getter %s must not exist on *bizdev.Service (%s)", fn.Name.Name, relFile(root, path))
}
}
}
}
func recvIsBizdevService(recv *ast.FieldList) bool {
if recv == nil || len(recv.List) == 0 {
return false
}
expr := recv.List[0].Type
if star, ok := expr.(*ast.StarExpr); ok {
expr = star.X
}
ident, ok := expr.(*ast.Ident)
return ok && ident.Name == "Service"
}
-35
View File
@@ -238,25 +238,6 @@ func (s *Service) DatabaseReady() bool {
return s != nil && s.pool != nil
}
func (s *Service) ContextManager() *ctxmgr.ContextManager {
return s.ctxMgr
}
func (s *Service) CAS() *storage.CAS {
return s.cas
}
func (s *Service) DocGov() *docgov.GovernanceEngine {
return s.docGov
}
func (s *Service) DocRevision() *docrevision.Service {
if s == nil {
return nil
}
return s.docRev
}
// AgentOutputMaterializer is the production materialize path. Runtime injects
// *docflow.Commands so candidate-ready/commit envelopes share the unique UoW.
type AgentOutputMaterializer interface {
@@ -279,22 +260,6 @@ func (s *Service) materializeAgentOutput(ctx context.Context, req docrevision.Ag
return s.docRev.MaterializeAgentOutput(ctx, req)
}
func (s *Service) ProjectWorkflow() *projectworkflow.Service {
return s.projectWorkflow
}
func (s *Service) Pool() *pgxpool.Pool {
return s.pool
}
func (s *Service) FreeformDoc() *freedoc.Service {
return s.freeDoc
}
func (s *Service) KB() *kb.Client {
return s.kb
}
var SupportedTasks = squad.SupportedTasks
var SupportedStages = []StageMeta{
-6
View File
@@ -6,10 +6,8 @@ import (
"chat-agent-system/internal/ctxmgr"
"chat-agent-system/internal/docgov"
"chat-agent-system/internal/kb"
"chat-agent-system/internal/maturity"
"chat-agent-system/internal/squad"
"chat-agent-system/internal/storage"
)
type TaskMeta = squad.TaskMeta
@@ -157,8 +155,4 @@ type BizdevService interface {
ExecuteStage(ctx context.Context, req StageRunRequest) (*StageRunResult, error)
InspectWorkspace(ctx context.Context, workDir string) (*squad.WorkspaceState, error)
ResumeOrModifyWorkspace(ctx context.Context, req squad.ModifyWorkflowRequest) (*squad.SquadRunResult, error)
ContextManager() *ctxmgr.ContextManager
CAS() *storage.CAS
DocGov() *docgov.GovernanceEngine
KB() *kb.Client
}
@@ -5,14 +5,10 @@ import (
"testing"
"chat-agent-system/internal/app/stageflow"
"chat-agent-system/internal/ctxmgr"
"chat-agent-system/internal/docgov"
"chat-agent-system/internal/intent"
"chat-agent-system/internal/kb"
"chat-agent-system/internal/maturity"
"chat-agent-system/internal/projectinstance"
"chat-agent-system/internal/squad"
"chat-agent-system/internal/storage"
)
type countingBizdev struct {
@@ -34,10 +30,6 @@ func (c *countingBizdev) InspectWorkspace(_ context.Context, _ string) (*squad.W
func (c *countingBizdev) ResumeOrModifyWorkspace(_ context.Context, _ squad.ModifyWorkflowRequest) (*squad.SquadRunResult, error) {
return nil, nil
}
func (c *countingBizdev) ContextManager() *ctxmgr.ContextManager { return nil }
func (c *countingBizdev) CAS() *storage.CAS { return nil }
func (c *countingBizdev) DocGov() *docgov.GovernanceEngine { return nil }
func (c *countingBizdev) KB() *kb.Client { return nil }
func TestDialogueAdvanceStage_LiveInstanceDoesNotUseBizdev(t *testing.T) {
store := projectinstance.NewMemoryStore()
@@ -7,13 +7,10 @@ import (
"time"
"chat-agent-system/internal/app/stageflow"
"chat-agent-system/internal/ctxmgr"
"chat-agent-system/internal/docgov"
"chat-agent-system/internal/intent"
"chat-agent-system/internal/kb"
"chat-agent-system/internal/maturity"
"chat-agent-system/internal/squad"
"chat-agent-system/internal/storage"
)
type pendingReplyBizdev struct {
@@ -34,10 +31,6 @@ func (p *pendingReplyBizdev) InspectWorkspace(_ context.Context, _ string) (*squ
func (p *pendingReplyBizdev) ResumeOrModifyWorkspace(_ context.Context, _ squad.ModifyWorkflowRequest) (*squad.SquadRunResult, error) {
return nil, nil
}
func (p *pendingReplyBizdev) ContextManager() *ctxmgr.ContextManager { return nil }
func (p *pendingReplyBizdev) CAS() *storage.CAS { return nil }
func (p *pendingReplyBizdev) DocGov() *docgov.GovernanceEngine { return nil }
func (p *pendingReplyBizdev) KB() *kb.Client { return nil }
func TestSyncTriggerTask_PendingConfirmation_NotSavedCompleted(t *testing.T) {
pending := &stageflow.TaskRunResult{
+2 -4
View File
@@ -30,9 +30,7 @@ func (s *Server) finalizeTaskRun(ctx context.Context, record *taskrun.RunRecord,
cmds := s.taskCommands()
if s != nil {
cmds.PW = s.pwSvc
if s.svc != nil {
cmds.Ctx = s.ctxMgr
}
cmds.Ctx = s.ctxMgr
}
return cmds.Finalize(ctx, record, result)
}
@@ -49,7 +47,7 @@ func (s *Server) taskCommands() *taskrun.Commands {
cmds.Env = s.cfg.Env
cmds.StorageIdentity = "env:" + s.cfg.Env
}
if s != nil && s.svc != nil {
if s != nil {
cmds.Ctx = s.ctxMgr
}
return cmds
+2 -2
View File
@@ -185,7 +185,7 @@ func TestAsyncTaskRun_FinalizesAfterWorkerCompletes(t *testing.T) {
workDir := t.TempDir()
_ = os.WriteFile(filepath.Join(workDir, "output.md"), []byte("# async finalize\n"), 0o644)
srv := &Server{cfg: cfg, svc: svc, pwSvc: pwSvc, taskRuns: taskrun.NewManager(pwSvc, ctxMgr)}
srv := &Server{cfg: cfg, svc: svc, pwSvc: pwSvc, ctxMgr: ctxMgr, taskRuns: taskrun.NewManager(pwSvc, ctxMgr)}
srv.taskRuns.SetExecutor(
func(_ context.Context, _ string, _ bizdev.TaskRunRequest, _ *stream.Streamer) (*bizdev.TaskRunResult, error) {
return &bizdev.TaskRunResult{
@@ -242,7 +242,7 @@ func TestAsyncTaskRun_PendingConfirmation_FinalizesAsPending(t *testing.T) {
workDir := t.TempDir()
_ = os.WriteFile(filepath.Join(workDir, "output.md"), []byte("# head\n"), 0o644)
srv := &Server{cfg: cfg, svc: svc, pwSvc: pwSvc, taskRuns: taskrun.NewManager(pwSvc, ctxMgr)}
srv := &Server{cfg: cfg, svc: svc, pwSvc: pwSvc, ctxMgr: ctxMgr, taskRuns: taskrun.NewManager(pwSvc, ctxMgr)}
srv.taskRuns.SetExecutor(
func(_ context.Context, _ string, _ bizdev.TaskRunRequest, _ *stream.Streamer) (*bizdev.TaskRunResult, error) {
return &bizdev.TaskRunResult{