Files
knowledge-governance/cmd/libraryagent/main.go
T
姚章浩 faaf003707
build / build (push) Failing after 17s
fix(libraryagent): 把宿主侧对象存储端点纳入固定命令形态
上一提交只给 libraryctl 加了 -source-s3-endpoint,agent 却不知道这个 flag,
systemd 起不来(exit 2)。端点属于"这台主机怎么访问这个源的存储",必须由 agent
自己钉住并随固定声明传给 libraryctl;请求仍然不能改。没配置时不凭空加 flag。

试过:make verify 15 项全绿;新增 agent 声明用例(有端点必传、无端点不多传)。
2026-10-29 06:11:29 +08:00

81 lines
4.1 KiB
Go

// Command libraryagent is the host-side execution boundary for whole-library
// capture. It runs as the ordinary operator account, owns no network listener
// other than one 0600 unix socket, and executes exactly one fixed command shape.
package main
import (
"context"
"flag"
"log"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"knowledge-governance/internal/libraryagent"
"knowledge-governance/internal/librarymaintenance"
)
func main() {
home, _ := os.UserHomeDir()
var config libraryagent.Config
flag.StringVar(&config.Socket, "socket", filepath.Join(home, ".local/share/knowledge-governance/agent.sock"), "unix socket for capture requests")
flag.StringVar(&config.Binary, "binary", "/home/zheromiku/knowledge-governance/libraryctl", "libraryctl binary this agent executes")
flag.StringVar(&config.ArchiveRoot, "archive", filepath.Join(home, ".local/share/knowledge-governance/library"), "sealed artifact root")
flag.StringVar(&config.JournalRoot, "journal", filepath.Join(home, ".local/share/knowledge-governance/freeze"), "freeze journal root")
flag.StringVar(&config.SourceApp, "source-app", "WKNFull-app", "source container describing the stack")
flag.StringVar(&config.SourcePG, "source-pg", "WKNFull-postgres", "source PostgreSQL container")
flag.StringVar(&config.SourceES, "source-es", "WKNFull-elasticsearch", "source Elasticsearch container")
flag.StringVar(&config.SourceS3Endpoint, "source-s3-endpoint", "", "host-reachable source object-store endpoint (overrides the container-internal one)")
flag.StringVar(&config.GovernancePG, "governance-pg", "knowledge-governance-p1-postgres-1", "governance PostgreSQL container")
flag.StringVar(&config.Project, "project", "weknora071full", "Compose project owning the writers")
flag.StringVar(&config.Writers, "writers", "app", "declared writer services")
nonWriters := flag.String("non-writers", defaultNonWriters, "service=reason for every other project service")
flag.DurationVar(&config.MaxDuration, "max-duration", 10*time.Minute, "upper bound for one operation")
describe := flag.Bool("describe", false, "print the fixed configuration and exit")
flag.Parse()
config.NonWriters = *nonWriters
agent, err := libraryagent.New(config)
if err != nil {
log.Fatal(err)
}
// 实例级维护接线(入口闸门 + 后台队列)不在 agent 的 Config 里:它由同一份
// 环境声明提供给子进程。启动时先说清楚有没有——缺了封存会在开窗口前被拒,
// 不允许"以为接好了"跑到一半才发现没有排空证据。
if target, targetErr := librarymaintenance.TargetFromEnv(os.Getenv); targetErr != nil {
log.Printf("library agent: 封存会拒绝(实例级维护未接线):%v", targetErr)
} else {
log.Printf("library agent: 实例级维护目标 %s 入口 %s 闸门 %s", target.Instance, target.IngressURL, target.IngressService)
}
if *describe {
log.Printf("library agent config: %+v", agent.Describe())
return
}
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
log.Printf("library agent listening on %s (project %s, writers %s)", config.Socket, config.Project, config.Writers)
if err = agent.Serve(ctx); err != nil {
log.Fatal(err)
}
}
// defaultNonWriters mirrors scripts/library-capture.sh: every sibling service of
// the source project is declared, with the reason it cannot write knowledge.
const defaultNonWriters = "frontend=UI only; no knowledge writes" +
",mcp=read-only MCP server" +
",dobotai-target=alpine placeholder; no knowledge writes" +
",docreader=parse RPC service; app persists parse output and settlement requires zero pending ops" +
",elasticsearch=search store; not an initiator" +
",postgres=database store; not an initiator" +
",redis=queue/cache store; not an initiator" +
",neo4j=graph store; not an initiator" +
",langfuse-web=LLM observability UI" +
",langfuse-worker=LLM observability worker; own storage" +
",langfuse-clickhouse=observability store" +
",langfuse-minio=observability object store" +
",langfuse-db-init=one-shot init; exited" +
",searxng=read-only search proxy" +
",searxng-init=one-shot init; exited"