Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f19a4d78d | ||
|
|
be556f4641 | ||
|
|
d1f72aa974 | ||
|
|
2df0d10d96 | ||
|
|
8f113e2376 | ||
|
|
277392acf3 | ||
|
|
e05587f165 | ||
|
|
ad2649b4ab | ||
|
|
f2fb9ffa6d |
@@ -24,7 +24,7 @@ jobs:
|
||||
echo "SUBMODULE_TOKEN is not configured" >&2
|
||||
exit 1
|
||||
fi
|
||||
git config --global url."https://weichen:${SUBMODULE_TOKEN}@git-home.u1680832.nyat.app:30319/".insteadOf "ssh://git@git-ssh.u1680832.nyat.app:31411/"
|
||||
git config --global url."https://weichen:${SUBMODULE_TOKEN}@gitea.naitangbaobao.cn/".insteadOf "ssh://git@gitea.naitangbaobao.cn:52222/"
|
||||
git -c fetch.recurseSubmodules=false submodule update --init --recursive
|
||||
- name: Install Go 1.27.1
|
||||
run: |
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
parsed_server = urlsplit(SERVER)
|
||||
if parsed_server.scheme not in {"http", "https"} or not parsed_server.netloc:
|
||||
sys.exit("Checkout server must be the platform-injected http(s) URL")
|
||||
SSH = "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
|
||||
SSH = "ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
|
||||
# 审查过的白名单,独立于候选 .gitmodules:仅列出两个治理 gitlink。
|
||||
REPOSITORIES = {
|
||||
"deps/development-guidelines": "Development-Guidelines",
|
||||
|
||||
+5
-5
@@ -1,15 +1,15 @@
|
||||
[submodule "deps/development-guidelines"]
|
||||
path = deps/development-guidelines
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Guidelines.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Development-Guidelines.git
|
||||
[submodule "deps/error-code-system"]
|
||||
path = deps/error-code-system
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Error-Code-System.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Error-Code-System.git
|
||||
[submodule "deps/logging-system"]
|
||||
path = deps/logging-system
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Logging-System.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Logging-System.git
|
||||
[submodule "deps/agent-intent"]
|
||||
path = deps/agent-intent
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Intent.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Intent.git
|
||||
[submodule "deps/development-manager"]
|
||||
path = deps/development-manager
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Manager.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Development-Manager.git
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
历史文档与旧链接里的 `git-panel.u1680832.nyat.app:30319` 已失效(TLS 握手失败),
|
||||
见到一律按过期处理,不要再试。当前权威通道:
|
||||
|
||||
- **Web / API(HTTPS)**:`https://git-home.u1680832.nyat.app:30319`(Gitea 1.27.3,
|
||||
- **Web / API(HTTPS)**:`https://gitea.naitangbaobao.cn`(Gitea 1.27.3,
|
||||
API 前缀 `/api/v1`;偶发 broken pipe / 超时,重试即可)。
|
||||
- **Git over SSH**:`ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/<Repo>.git`
|
||||
- **Git over SSH**:`ssh://git@gitea.naitangbaobao.cn:52222/weichen/<Repo>.git`
|
||||
(各仓 origin 与 gitlink 均为此格式)。
|
||||
- **API token**:`~/.secrets/gitea`,两行键值 `URL_PREFIX=…` 与
|
||||
`ACCESS_TOKEN=<40 位 hex>`;取值 `grep ACCESS_TOKEN ~/.secrets/gitea | cut -d= -f2-`,
|
||||
@@ -33,7 +33,7 @@
|
||||
(baseline 硬边界 2:只记录来源、字段与可用状态)。
|
||||
- **SSH key**:`~/.ssh/home_gitea`(ED25519,公钥指纹
|
||||
`SHA256:GYXaOXIMeloQ1fKSfdJ/ndgPQzs/Ix7Hk62ekfkfQ20`,Gitea 侧密钥名 GMKtec);
|
||||
`~/.ssh/config` 已有 `git-ssh.u1680832.nyat.app` 主机条目,克隆/推送直接可用。
|
||||
`~/.ssh/config` 已有 `gitea.naitangbaobao.cn(端口 52222)` 主机条目,克隆/推送直接可用。
|
||||
|
||||
## Agent 执行与新项目准入(强制)
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
|
||||
- 目标/产品边界:独立的 Agent 执行基础库。提供执行契约(contract)、执行端口(exec)、自研运行时(runtime)、外部适配器(adapters)与行为验收(conformance)。不实现小队编排,不依赖 Core 或 Squad。
|
||||
- 源码、资产、文档、机器契约位置:Go 源码在仓库根包目录;模块路径 `agent-native`;人类文档在根 `README.md`、`docs/`、`policy/`;过程记录在 `docs/records/`;机器契约以 `contract` 包类型为准。
|
||||
- 权威远端、集成基线、受保护分支:`ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Native.git`,集成基线 `main`。
|
||||
- 权威远端、集成基线、受保护分支:`ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Native.git`,集成基线 `main`。
|
||||
- 并行共同基线记录位置、合入通知/主动检查方式:任务主记录在 Gitea Issue/PR;合入前在本仓 `main` 上 `git fetch` 并确认 HEAD。
|
||||
- 发布线与批准版本/实际制品查询入口:当前无独立制品仓库。可构建性以本仓 `main` 的 `go test` 为准;依赖子模块版本以 gitlink 为准,不把工作区未提交文件当发布组合。
|
||||
- 提交/审核/合并/发布身份与权限:仓库所有者 weichen。本机提交不代替远端合并。
|
||||
@@ -28,7 +28,7 @@
|
||||
克隆:
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Native.git
|
||||
git clone --recurse-submodules ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Native.git
|
||||
# 已克隆时:git submodule update --init --recursive
|
||||
```
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
版本以本仓 gitlink 为准。`scripts/submodule-consistency.sh` 核对 gitlink 与检出的 HEAD。
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Native.git
|
||||
git clone --recurse-submodules ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Native.git
|
||||
# 已克隆时:git submodule update --init --recursive
|
||||
```
|
||||
|
||||
@@ -83,7 +83,7 @@ replace agent-native => ./deps/agent-native
|
||||
|
||||
本仓自己的 `go.mod` 则把错误码库和日志库替换到 `./deps/`。消费方若同时依赖这三仓,必须在消费方 `go.mod` 里写自己的 `replace`:依赖模块内部的 `replace` 不会在上层构建中生效。
|
||||
|
||||
远程:`ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Native.git`
|
||||
远程:`ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Native.git`
|
||||
|
||||
## CI
|
||||
|
||||
|
||||
@@ -212,8 +212,9 @@ func (b *Backend) Execute(ctx context.Context, req exec.Request) (*exec.Result,
|
||||
}
|
||||
|
||||
writable := writableFrom(ctx)
|
||||
// F02: a non-empty Writable cannot be enforced for exec/MCP/host tools —
|
||||
// reject in preflight rather than pretend the write-set holds.
|
||||
// F02: a non-empty Writable cannot be enforced for exec/MCP/host tools or
|
||||
// subagent delegation — reject in preflight rather than pretend the
|
||||
// write-set holds.
|
||||
if len(writable) > 0 && profile == exec.ToolProfileWorkspace {
|
||||
if b.opts.Exec != nil {
|
||||
return preflightFail("writable write-set cannot be enforced when exec tools are enabled"), nil
|
||||
@@ -224,6 +225,9 @@ func (b *Backend) Execute(ctx context.Context, req exec.Request) (*exec.Result,
|
||||
if len(b.opts.HostTools) > 0 {
|
||||
return preflightFail("writable write-set cannot be enforced when host tools are enabled"), nil
|
||||
}
|
||||
if b.opts.Subagent != nil {
|
||||
return preflightFail("writable write-set cannot be enforced when subagent delegation is enabled"), nil
|
||||
}
|
||||
}
|
||||
var reg *tools.Registry
|
||||
if profile == exec.ToolProfileWorkspace {
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package native
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"agent-native/exec"
|
||||
"agent-native/runtime/llm"
|
||||
"agent-native/runtime/subagent"
|
||||
)
|
||||
|
||||
func TestContractWritableRejectsSubagentInPreflight(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
streamCalls := 0
|
||||
inner := script(llm.Message{Role: llm.RoleAssistant, Content: "x", StopReason: llm.StopEnd})
|
||||
factoryCalls := 0
|
||||
b := New(Options{
|
||||
ModelOptions: ModelOptions{
|
||||
Model: "fake",
|
||||
Stream: func(ctx context.Context, model string, messages []llm.Message, decls []llm.ToolDecl, opts llm.StreamOptions) <-chan llm.Event {
|
||||
streamCalls++
|
||||
return inner(ctx, model, messages, decls, opts)
|
||||
},
|
||||
},
|
||||
ToolOptions: ToolOptions{
|
||||
Subagent: func(ctx context.Context, req subagent.Request) (subagent.Result, error) {
|
||||
factoryCalls++
|
||||
return subagent.Result{Success: true}, nil
|
||||
},
|
||||
},
|
||||
}).Contract()
|
||||
res, err := b.Execute(context.Background(), exec.ContractRequest{
|
||||
ExecutionID: "e-sub",
|
||||
Prompt: "x",
|
||||
Workspace: exec.WorkspaceHandle{
|
||||
Root: dir,
|
||||
Writable: []string{"a.md"},
|
||||
},
|
||||
ToolPolicy: exec.ToolPolicy{Profile: exec.ToolProfileWorkspace},
|
||||
Targets: []string{"a.md"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Outcome == exec.OutcomeSucceeded {
|
||||
t.Fatal("Writable + subagent delegation enabled must be rejected in preflight")
|
||||
}
|
||||
const want = "writable write-set cannot be enforced when subagent delegation is enabled"
|
||||
if res.Err == nil || res.Err.Reason != want {
|
||||
t.Fatalf("want reason %q, got %+v", want, res.Err)
|
||||
}
|
||||
if streamCalls != 0 || factoryCalls != 0 {
|
||||
t.Fatalf("preflight must stop before model/factory: stream=%d factory=%d", streamCalls, factoryCalls)
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, "a.md")); !os.IsNotExist(err) {
|
||||
t.Fatal("deliverable a.md must not be created when preflight rejects")
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, ".agentx")); !os.IsNotExist(err) {
|
||||
t.Fatal("no session state must be written when preflight rejects")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContractSubagentWithoutWritableStillDelegates(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
var delegated *subagent.Request
|
||||
stream, c := captureStream(
|
||||
llm.Message{Role: llm.RoleAssistant, StopReason: llm.StopToolCalls, ToolCalls: []llm.ToolCall{{
|
||||
ID: "c1", Name: "delegate_task",
|
||||
Arguments: `{"goal":"查证数据","write_scope":"research/","done_criteria":"三来源"}`,
|
||||
}}},
|
||||
llm.Message{Role: llm.RoleAssistant, StopReason: llm.StopToolCalls, ToolCalls: []llm.ToolCall{{
|
||||
ID: "c2", Name: "write_file",
|
||||
Arguments: `{"path":"output.md","content":"done"}`,
|
||||
}}},
|
||||
llm.Message{Role: llm.RoleAssistant, Content: "ok", StopReason: llm.StopEnd},
|
||||
)
|
||||
b := New(Options{
|
||||
ModelOptions: ModelOptions{Model: "fake", Stream: stream},
|
||||
ToolOptions: ToolOptions{
|
||||
Subagent: func(ctx context.Context, req subagent.Request) (subagent.Result, error) {
|
||||
delegated = &req
|
||||
return subagent.Result{Success: true, Text: "结论已查明"}, nil
|
||||
},
|
||||
},
|
||||
}).Contract()
|
||||
res, err := b.Execute(context.Background(), exec.ContractRequest{
|
||||
ExecutionID: "e-sub-ok",
|
||||
Prompt: "分工",
|
||||
Workspace: exec.WorkspaceHandle{Root: dir},
|
||||
ToolPolicy: exec.ToolPolicy{Profile: exec.ToolProfileWorkspace},
|
||||
Targets: []string{"output.md"},
|
||||
})
|
||||
if err != nil || res.Outcome != exec.OutcomeSucceeded {
|
||||
t.Fatalf("execute: err=%v res=%+v", err, res)
|
||||
}
|
||||
if delegated == nil || delegated.Goal != "查证数据" {
|
||||
t.Fatalf("factory not invoked with fields: %+v", delegated)
|
||||
}
|
||||
sawDelegate := false
|
||||
for _, names := range c.toolDecls {
|
||||
for _, n := range names {
|
||||
if n == "delegate_task" {
|
||||
sawDelegate = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !sawDelegate {
|
||||
t.Fatal("delegate_task must be declared when Subagent factory is set and Writable is empty")
|
||||
}
|
||||
}
|
||||
Vendored
+1
-1
Submodule deps/agent-intent updated: 765a7e7177...28833bcfca
Vendored
+1
-1
Submodule deps/development-guidelines updated: 2688fd2be6...3ed982138c
Vendored
+1
-1
Submodule deps/development-manager updated: bd3a7de57a...24e8a5c8ba
Vendored
+1
-1
Submodule deps/error-code-system updated: a3ee67bba2...00c03035b5
Vendored
+1
-1
Submodule deps/logging-system updated: 49b5d8be60...7005493077
Reference in New Issue
Block a user